相关文章推荐
耍酷的跑步鞋  ·  自由球_百度百科·  1 月前    · 
ibaobao  ·  歌海情天_百度百科·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm looking for a way to catch segfaults and other errors anywhere in a program (which uses multiple threads, some of which are created by external libraries). I'm using Visual Studio 2013 with the Intel C++ Compiler 2015.

Some external DLL's - in some cases I've even seen this with Windows drivers - can contain bugs that are out of my control, and my software runs 24/7 - I need to be able to log a crash somewhere and restart my software.

So far, I found that you can set a signal handler which handles SIGSEGV and other signals. Based on what I read, under Linux this would do exactly what I need (handle this signal for all threads), but under Windows you need to set the signal handler for each thread separately. Since I'm not the one who creates all the threads (if I was, I could just use __try/__catch), this isn't really an option. On top of that, I'm seeing that when I set a signal handler in a thread and then cause a SIGSEGV it doesn't get handled by the handler, while the exact same code works fine in the main thread - not sure what's going on there (but even a fix for that wouldn't help, since I don't create all the threads, and looping through all existing threads in my process to set handlers sounds like a very bad idea).

So, is there a way to do this? Googling and searching here did not help - I found several people with similar questions but no answers that are usable in my situation.

Note: What I have now, which works perfectly in the main thread but not at all if I copy this same block of code to any thread:

SignalHandlerPointer previousHandlerSEGV = signal(SIGSEGV, SignalHandler);
int *a;
a = NULL;
*a = 0;

To get notified about all unhandled exceptions in a process you can call SetUnhandledExceptionFilter. The functionality is documented as:

Issuing SetUnhandledExceptionFilter replaces the existing top-level exception filter for all existing and all future threads in the calling process.

Inside the exception filter it is recommended to trigger a call to MiniDumpWriteDump (in an external process), to produce a mini dump for off-line analysis. You get to control the amount of information that is written into the mini dump (e.g. threads, modules, call stacks, memory). Most importantly, you can dump the call stack of the thread that raised the uncaught exception, at the time the exception is raised.

As an alternative, I believe some/most/all of this can be done automatically by registering for application recovery and restart.

SetUnhandledExceptionFilter doens't work because this isn't an exception. But, it looks like your link about registering for application recovery and restart works fine! I did have to tweak it a bit to keep it compatible with Windows XP (I still have many people using my software on XP... It's a 24/7 thing that doesn't require internet access). Anyway, with LoadLibrary inside an if I managed to get it to work! – Hans van Zutphen Dec 20, 2016 at 17:31 @HansvanZutphen: What you consider to be a "seg fault" is in fact implemented as an SEH exception in Windows. Setting the unhandled exception filter does exactly what you had in mind. – IInspectable Dec 20, 2016 at 17:33 Hm... it didn't work when I tried it. Also try/catch doesn't catch it, you need to use __try and __catch. But I guess it would if I would choose the (non-standard) compiler flag "/EHa (Yes with SEH exceptions)". – Hans van Zutphen Dec 20, 2016 at 17:44 @HansvanZutphen: SEH is a system service, that's unrelated to any compiler settings. int* a = nullptr; *a = 42; will always trigger an access violation SEH exception (error code 0xC0000005), that can be filtered using the __except keyword, or in an unhandled exception filter (as set up using SetUnhandledExceptionFilter). – IInspectable Dec 20, 2016 at 17:50 That said, you should always compile your C++ code using the /EHs or /EHsc compiler switches for portability. Using /EHa would cause a C++ catch(...) clause to intercept SEH exceptions (like access violations), which should pass through to the unhandled exception filter. – IInspectable Dec 20, 2016 at 17:55

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.