How to handle seg faults under Windows?
Asked Answered
L

6

7

How can a Windows application handle segmentation faults? By 'handle' I mean intercept them and perhaps output a descriptive message. Also, the ability to recover from them would be nice too, but I assume that is too complicated.

Lunisolar answered 2/1, 2010 at 20:56 Comment(0)
B
3

Use SEH for early exception handling, and use SetUnhandledExceptionFilter to show a descriptive message.

Bloodstock answered 2/1, 2010 at 21:4 Comment(5)
Do the __try and __except blocks work with other Windows compilers like mingw32? (Not just vc++)Lunisolar
You can go down this route (though I'd encourage you to check out what WER can do for you, you can register to get the reports / provide problem links!) - remember that your app will be in a very hosed state in the filter, you will be pretty limited as to what you can safely do ; anything involving new/delete is out for example.Spitzer
I guess I'll stick with VC++ then.Lunisolar
After learned what WER is, it's really convenient to handle application crash. I also recommend WER now. But when tried the sample of WER is not support Windows XP.Bloodstock
Check out libSEH for (MINGW32, CYGWIN) programmingunlimited.net/siteexec/content.cgi?page=libseh and programmingunlimited.net/siteexec/content.cgi?page=mingw-sehBloodstock
S
5

Let them crash and let the Windows Error Reporting handle it - under Vista+, you should also consider registering with Restart Manager (http://msdn.microsoft.com/en-us/library/aa373347(VS.85).aspx), so that you have a chance to save out the user's work and restart the application (like what Word/Excel/etc.. does)

Spitzer answered 2/1, 2010 at 20:59 Comment(0)
B
3

Use SEH for early exception handling, and use SetUnhandledExceptionFilter to show a descriptive message.

Bloodstock answered 2/1, 2010 at 21:4 Comment(5)
Do the __try and __except blocks work with other Windows compilers like mingw32? (Not just vc++)Lunisolar
You can go down this route (though I'd encourage you to check out what WER can do for you, you can register to get the reports / provide problem links!) - remember that your app will be in a very hosed state in the filter, you will be pretty limited as to what you can safely do ; anything involving new/delete is out for example.Spitzer
I guess I'll stick with VC++ then.Lunisolar
After learned what WER is, it's really convenient to handle application crash. I also recommend WER now. But when tried the sample of WER is not support Windows XP.Bloodstock
Check out libSEH for (MINGW32, CYGWIN) programmingunlimited.net/siteexec/content.cgi?page=libseh and programmingunlimited.net/siteexec/content.cgi?page=mingw-sehBloodstock
S
3

If you add the /EHa compiler argument then try {} catch(...) will catch all exceptions for you, including SEH exceptions.
You can also use __try {} __except {} which gives you more flexibility on what to do when an exception is caught. putting an __try {} __except {} on your entire main() function is somewhat equivalent to using SetUnhandeledExceptionFilter().

That being said, you should also use the proper terminology: "seg-fault" is a UNIX term. There are no segmentation faults on Windows. On Windows they are called "Access Violation Exceptions"

Symbiosis answered 2/1, 2010 at 22:13 Comment(4)
One warning: enabling /EHa is a recipe for introducing security vulnerabililities in your application. The problem is that there are exceptions that are thrown by the operating system (like guard page exceptions) which can correctly be filtered if you use the __except filter but if you use /EHa and try {} catch() you won't be able to determine if it's appropriate to let the OS handle the exception. Structured exceptions are extremely difficult to get right without introducing security defects, IMHO Paul Betts answer is right - let the OS handle the error.Piloting
I thought I had explained the issue above. Masking exceptions like guard page exceptions or random memory access errors can introduce security holes (for instance if you catch memory access errors, an attacker can use this to defeat platform protections like ASLR - there was at least one recent MSFT security bulletin that was caused by this issue).Piloting
Apologies for the drive-by down vote. Accidental mis-click and then didn't discover my vote before it was locked.Mallarme
SEH exception handling is not a black box. If the error code is well known... and is something you can ignore... you can handle them. __try, __except is the correct way to do this.Belligerence
G
1

C++ self-contained example on how to use SetUnhandledExceptionFilter, triggering a write fault and displaying a nice error message:

#include <windows.h>
#include <sstream>

LONG WINAPI TopLevelExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
{
  std::stringstream s;
  s << "Fatal: Unhandled exception 0x" << std::hex << pExceptionInfo->ExceptionRecord->ExceptionCode 
  << std::endl;

  MessageBoxA(NULL, s.str().c_str(), "my application", MB_OK | MB_ICONSTOP);
  exit(1);

  return EXCEPTION_CONTINUE_SEARCH;
}

int main()
{
   SetUnhandledExceptionFilter(TopLevelExceptionHandler);
   int *v=0;
   v[12] = 0;   // should trigger the fault
   return 0;
}

Tested successfully with g++ (and should work OK with MSVC++ as well)

Gimel answered 27/6, 2017 at 14:37 Comment(0)
E
0

What you want to do here depends on what sort of faults you are concerned with. If you have sloppy code that is prone to more or less random General Protection Violations, then @Paul Betts answer is what you need.

If you have code that has a good reason to deference bad pointers, and you want to recover, start from @whunmr's suggestion about SEH. You can handle and indeed recover, if you have clear enough control of your code to know exactly what state it is in at the point of the fault and how to go about recovering.

Evidence answered 2/1, 2010 at 21:19 Comment(4)
I hope my code isn't sloppy :) Most of the faults in my app come from the embeded python interpreter. Certain scripts seem to cause problems.Lunisolar
If you throw away and recreate the interpreter, and if that process does not leak, then you're good to go.Evidence
Too bad that isn't an option.Lunisolar
Put python in its own process and communicate via pipes or files?Evidence
C
0

Similar to Jean-François Fabre solution, but with Posix code in MinGW-w64. But note that the program must exit - it can't recover from the SIGSEGV and continue.

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>

void sigHandler(int s)
{
    printf("signal %d\n", s);
    exit(1);
}

int main()
{
    signal(SIGSEGV, sigHandler);
    int *v=0;
    *v = 0;   // trigger the fault

    return 0; 
}
Cleancut answered 30/5, 2019 at 16:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.