Greetings.
C++ Windows application / release build with all optimizations disabled
/ Visual Studio 2005 / Windows XP sp2
I am facing the problem that our application terminates unexpectedly
without any debug/reporting mechanism being invoked, i.e. it terminates
*as if* I would issue the call ::TerminateProcess(hCurrent, 0xC0000005)
manually. However, we are sure that no user code in our application
calls TerminateProcess (let alone with the code for access violation).
This happens *only* if the release build (no optimization) of this app
is *not* run under the debugger, i.e. started normally via explorer or
command line.
The application has set an unexpected filter via
SetUnhandledExceptionFilter(..) but this handler is not invoked. (It
*is* correctly invoked if I cause an acc.viol. anywhere in user code,
e.g. by dereferencing a NULL pointer)
The application does not terminate through abort() as that would display
a dialog.
The app does not terminate through ExitProcess()/exit() as that would
run global destructors and these are not run.
The process exits shortly (< 1sec) after a call to FreeLibrary(..) in
one thread, but as determined through tracing, not during this
FreeLibrary call and probably not during this thread.
If the FreeLibrary call is not issued the error does not happen.
I'm strongly suspecting the cleanup code of this 3rd party DLL to break
something but I'm really lost how to narrow it down as I have no
starting point whatsoever where the access violation happens.
Any ideas welcome!
cheers,
Martin
This is where C++ programmers earn their keep.
Brian
"Martin T." <0xCDC...@gmx.at> wrote in message
news:gkigtt$sl6$1...@news.motzarella.org...
What you see is typical to the foloowng scenario:
1. A thread exhausts its stack space; EXCEPTION_STACK_OVERFLOW
exception (0xC00000FD) is risen.
2. A thread swallows EXCEPTION_STACK_OVERFLOW and continue
execution.
3. At the next attempt to grow stack, the system takes control,
issues EXCEPTION_ACCESS_VIOLATION (0xC0000005) exception and
terminates the process immediately - without any GUI message!
Now, this scenario is true to all WinNT line from 4.0 up to XP.
However, I read it somewhere that now Vista and higher shows some
error message to the user. The process is terminated on the spot,
anyway.
HTH
Alex
"Martin T." <0xCDC...@gmx.at> wrote in message
news:gkigtt$sl6$1...@news.motzarella.org...
I rather think that this behavior is *not* typical for memory
corruption. At least not the type of corruption I usually see.
A "normal" access violation (accessing an invalid pointer after some
bogus values where introduced by corruption) usually results in a
program termination *with* an error message.
I know of 2 examples where the process terminates in this way, without
message:
1.) EXCEPTION_STACK_OVERFLOW (or the EXCEPTION_ACCESS_VIOLATION
following a stack overflow)
2.) When a exception is raised in a filter function installed by
SetUnhandledExceptionFilter - but I have ruled out that case here.
If anyone knows other *specific* cases where the process terminates
silently that would be great!
> code, ensuring there are no buffer overruns, and that each heap
> allocation is matched by exactly one deallocation. Also, where DLL's are
> concerned, check to see whether there are any C++ classes or STL
> containers being passed. If so, the DLL most likely needs to be rebuilt
> using matching compiler/link options.
>
Just to make sure: Do you have a concrete example where a buffer
overrun, a double-delete or a mismatched class can be used to make the
VC8 compiler create an executable that *silently* terminates?
> This is where C++ programmers earn their keep.
>
> Brian
>
cheers,
Martin
Thanks for pointing this out explicitly.
However, this scenario requires that either a) we have two subsequent
stack overflows or b) the EXCEPTION_STACK_OVERFLOW is "handled" by
EXCEPTION_CONTINUE_EXECUTION, which we do not do (at least not explicitly.
Di you know of any "system" mechanism that would do that, as we do not
explicitly catch these exceptions ... ?
cheers,
Martin
I am not aware of any system mechanism that would do such things.
However, it may be third party code that inadvertently catches too
much (including EXCEPTION_STACK_OVERFLOW).
Alex
"Martin T." <0xCDC...@gmx.at> wrote in message
news:gkk9om$saj$1...@news.motzarella.org...
Well. There is the fact that any exception during DLL cleanup is
silently skipped (via EXCEPTION_EXECUTE_HANDLER) by the MS crt code.
Other than that, I guess there are quite a few instances of catch(...)
so I guess I'm out of luck there.
One other thing I would emphasize: This happens only if the application
is *not* run under the debugger. If it were a "normal" stack overflow
caused by faulty program logic it should also happen when run under the
debugger.
Well I'll keep searching ...
cheers,
Martin
Yes, I realize now I missed the boat with my post. Very interesting
thread, by the way. I'll be very interested in learning what you find
once you resolve this issue.
Brian
Well, since VC++7.1,if I am not mistaken, catch(...) with default
compiler settings won't catch SEH exceptions. So, it must be
explicit __except.
> Well I'll keep searching ...
Good luck!
Alex
After approx two working days of playing around, recompiling various
stuff, etc. I have finally managed to get a few crashes during debugging
and got on the right track ... (or so I hope):
1.) DLL is loaded
2.) foo() = causes code in DLL to create a thread
...
3.) DLL terminates through call to FreeLibrary()
4.) D'tors of static objects run (correctly) and implicitly signal the
created thread to terminate and then go clean up other stuff.
5.) DLL is unloaded
6.) (!) Scheduler switches back to the thread created in step 2, thread
tries to access some DLL specific data -- boom.
Synchronizing the thread termination resolved the problem.
(As an aside, I learned that you cannot WaitForSingleObject during DLL
detach:
http://groups.google.com/group/microsoft.public.win32.programmer.kernel/msg/d70002d5b32f4876
)
Lesson learned: if your static destructors are cleaning up, make really
sure they a) wait for all threaded cleanup to finish (and b) don't wait
by waiting for the thread handle).
thanks all who gave input!
cheers,
Martin