How can I guarantee to catch structured exception EXCEPTION_STACK_OVERFLOW in C ++ in Visual Studio 2005?

Background

  • I have an application with Poof-Crash [1]. I am pretty sure that this is due to a hollow stack.
  • The application is multithreaded.
  • I am compiling with " Enable C++ Exceptions: Yes With SEH Exceptions (/EHa) ".
  • I wrote the SE Translator function and called it _set_se_translator() .
  • I wrote the functions and settings of set_terminate() and set_unexpected() .
  • In order to get stack overflow, I have to work in release mode under heavy load for several days. Running under the debugger is not an option, as the application cannot run fast enough to reach the runtime required to view the problem.
  • I can simulate a problem by adding infinite recursion when executing one of the functions, and thus test the EXCEPTION_STACK_OVERFLOW exception catch.
  • I have set up WinDBG as a crash dump program and get good information about all the other problems with emergency situations, but not this one . The crash dump will contain only one thread, which is "Sleep ()". All other threads are out.

Question

None of the things I tried led to the EXCEPTION_STACK_OVERFLOW exception EXCEPTION_STACK_OVERFLOW .

Does anyone know how to guarantee getting a chance for this exception at run time in release mode?

Definitions

  • Poof-Crash: The application crashes, crossing the puff and disappearing without a trace.

(Given the name of this site, I am surprised that this question is no longer here!)

Notes

  • In response, a short question was raised about setting the size of the stack in order to quickly cause a problem and resolve it to the debugger. This is a clever idea, but, unfortunately, I do not believe that this will help. The problem is most likely caused by the edge case leading to infinite recursion. Shortening the stack will not cause a problem earlier and will probably cause an unrelated crash in really deep code. Nice idea, and thanks for posting, even if you deleted it.
+6
c ++ debugging exception-handling stack-overflow
source share
5 answers

Everything that was before Windows XP could not (or would be more difficult) to catch stack overflows at all. With the advent of xp, you can install a vector exception handler that gets a chance before any stack-based handlers (structured exceptions) this is the very reason - structured exception handlers are stack-based).

But in reality you cannot do much, even if you can catch such an exception.

On his blog , cbrumme (sorry, he does not have his / her real name) discusses the stack page adjacent to the protective page (the one that generates the stack overflow), which could potentially be used for backup. If you can compress your return code to use only one page of the stack, you can free as much as your logic allows. Otherwise, the application is pretty much dead in a collision with a stack overflow. The only reasonable thing to do with this is to write a dump file for later debugging.

Hope this helps.

+5
source share

I'm not sure if you are on the right track, diagnosing this as a stack overflow.

But in any case, the fact that you get poof !, plus what you see in WinDbg

The crash dump will contain only one thread, which is "Sleep ()". All other threads are out.

suggests me that someone called the C function of RTL exit () or perhaps directly called the Windows API TerminateProcess (). This may have something to do with your interrupt handlers or not. Perhaps something in the exception handling logic has a re-entry check and arbitrarily decides to exit () if it reappears.

My suggestion is to fix your executables so that you can possibly debug INT 3 at the exit entry point (), if it is statically linked or dynamically linked, fixes the import, and also fixes any import files kernel32 :: TerminateProcess instead throws DebugBreak () .

Of course, exit () and / or TerminateProcess () can also be called during a normal shutdown, so you have to filter out false alarms, but if you can get a call stack for the case when it is just about to go for proof, you should have that you need.

EDIT ADD: just writing your own version of exit () and linking it instead of the CRTL version can do the trick.

+4
source share

I remember the code from the previous workstation, which sounded the same way, having explicit checks on the boundaries of the stack pointer and manually throwing an exception.

Some time has passed since I touched C ++, although even when I touched it, I did not know what I was doing, therefore, I caution about the possibility of portability / reliability of the mentioned advice.

+1
source share

Have you considered ADPlus from the debugging tools for Windows?

ADPlus attaches the CDB debugger to the process in crash mode and generates crash dumps for most of the exceptions that the process throws. Basically, you run "ADPlus-crash -p yourPIDhere", it performs an invasive connection and starts the registration.

Given your comment above about running under a debugger, I just wanted to add that CDB adds almost zero overhead in off-mode on a decent (dual-core, 2 GB RAM) machine, so don't let this delay you from trying it.

+1
source share

You can create debugging symbols without disabling optimization. In fact, you should do it anyway. It just makes debugging easier.

And the documentation for _set_se_translator says that each thread has its own SE translator. Do you set one for each thread?

set_unexpected probably doesn't work, at least according to the VS 2005 documentation. And each thread also has its own terminate handler, so you must set it for the thread as well.

I also highly recommend NOT using SE translation. It takes hardware exceptions that you should not ignore (i.e. you should really log the error and complete) and turns them into something that you can ignore (C ++ exceptions). If you want to catch such an error, use the __try/__except handler.

0
source share

All Articles