Ticket #1820 (new bug)

Opened 6 years ago

Last modified 8 months ago

Windows segfault-catching only works for the main thread

Reported by: simonmar Owned by:
Priority: lowest Milestone: 7.6.2
Component: Runtime System Version: 6.8.1
Keywords: Cc:
Operating System: Windows Architecture: Unknown/Multiple
Type of failure: None/Unknown Difficulty: Unknown
Test Case: derefnull(ghci), divbyzero(ghci) Blocked By:
Blocking: Related Tickets:

Description

On Windows, the RTS tries to catch segmentation faults and divide-by-zero exceptions using structured exception handling in rts/Main.c. Unfortunately this only works for the main thread, so if the exception occurs in another thread it won't be caught. GHCi runs all its computations in a separate thread, hence derefnull(ghci) and divbyzero(ghci) are failing.

Change History

Changed 6 years ago by igloo

  • owner set to igloo
  • milestone changed from 6.8 branch to 6.8.3

Changed 5 years ago by igloo

  • milestone changed from 6.8.3 to 6.10.1

Changed 5 years ago by simonmar

  • architecture changed from Unknown to Unknown/Multiple

Changed 5 years ago by igloo

  • milestone changed from 6.10.1 to 6.10.2

Changed 4 years ago by igloo

  • milestone changed from 6.10.2 to 6.12.1

Changed 4 years ago by igloo

See also the mingw GCC 4.4.0 announcement info on exceptions:  http://sourceforge.net/project/shownotes.php?release_id=691876

Changed 4 years ago by igloo

  • failure set to None/Unknown
  • milestone changed from 6.12.1 to 6.12 branch

Changed 3 years ago by igloo

  • milestone changed from 6.12 branch to 6.12.3

Changed 3 years ago by igloo

  • owner igloo deleted

This program, with the seh_excn.* files in the GHC tree:

#include "seh_excn.h"

void g(int *p) {
    printf("1 Points to %d\n", *p);
    printf("2 Not %d\n", 5 / 0);
    printf("3 Points to %d\n", *p);
}

void h() {
    printf("1 Points to %d\n", 6);
    printf("2 Not %d\n", 5 / 0);
    printf("3 Points to %d\n", 7);
}

void f(int *p) {
    BEGIN_CATCH
    g(p);
    // h();
    END_CATCH
}

int main(void) {
    int p;
    p = 28;
    printf("Start\n");
    f(&p);
    printf("End\n");
}

doesn't work properly:

$ ./seh
Start
1 Points to 28

(note that we don't get a "divide by zero" message) whereas if you change it to call h rather than g then it does:

$ ./seh
Start
1 Points to 6
divide by zero

This is a problem because I think we want to do the exception handling in workerStart, where we need to pass the task argument on.

I've looked at using the simpler-looking AddVectoredExceptionHandler instead (which would mean we have to drop Win 2k support, I think), but I'm getting

C:\cygwin\tmp/ccYnOVfO.o:seh2.c:(.text+0xe3): undefined reference to `AddVectoredExceptionHandler'
C:\cygwin\tmp/ccYnOVfO.o:seh2.c:(.text+0xf6): undefined reference to `RemoveVectoredExceptionHandler'
collect2: ld returned 1 exit status

Changed 3 years ago by igloo

  • priority changed from normal to low
  • milestone changed from 6.12.3 to 6.14.1

Changed 2 years ago by igloo

  • milestone changed from 7.0.1 to 7.0.2

Changed 2 years ago by igloo

  • milestone changed from 7.0.2 to 7.2.1

Changed 20 months ago by igloo

  • milestone changed from 7.2.1 to 7.4.1

Changed 16 months ago by igloo

  • priority changed from low to lowest
  • milestone changed from 7.4.1 to 7.6.1

Changed 8 months ago by igloo

  • milestone changed from 7.6.1 to 7.6.2
Note: See TracTickets for help on using tickets.