So, here's the problem I have.
void * something = ???;
void (*fun)(void*) = ???;
try
{
fun(something);
}
catch (...)
{
assert(false);
}
I've been tasked with establishing why the assert is getting fired. Unfortunately I don't get to change the above code. Furthermore this is in a multi-threaded environment and it's during shutdown of the program. The part that does the try/catch is unlocked quite purposefully in the real world code. When I try to step through the program it suddenly just disappears on me...I can't even step TO the right fun() call, let alone into it.
My only recourse seems to be to put a breakpoint in the catch(...) and examine whatever is there. Unfortunately this tells me nothing as I don't know what fun really is nor what something is.
My only hope at this point is that I can somehow talk the Visual Studio debugger into telling me what ... is and I'd be overjoyed if I could find out where it was thrown. It's not in the auto list at least...might it be elsewhere? Is there any way for me to make progress here or am I screwed? I feel screwed...
====
Update: There was an external program killing mine when it didn't shut down in time. That's why stepping made it disappear. Had nothing to do with threads.
Once I realized that I was able to turn on exceptions as suggested. Unfortunately there was no place that throws one...it was an access violation. The function being stored gets pounded somehow.
Try to use Visual Studio functionality that breaks execution when an exception is thrown. Go to Visual Studio main menu Debug -> Exceptions and tick all exceptions.
This way visual studio will stop when your exception is thrown and you will know what it was.
Can you just go to menu: Debug|Exceptions and mark the exceptions that you suspect is thrown ?
If you can step/attach to a running program that should be possible. This will cause the debugger to break when a specific exception(s) are thrown.
I usually mark the whole subtree 'Win32 Exceptions' in the Debug|Exceptions dialog box. I assume the your program does not throw and silently ignore other (Win32) exceptions (in this case you would have a lot of 'false' alarms).
I hope that helps.
Related
A variety of other questions hint that it is possible to continue debugging past an "Exception Unhandled" popup like this:
This is the popup from Visual Studio 2019, but VS 2015 gives similar behaviour. In both cases, for all combos of Win32/x64 and Debug/Release I have tried, the debugger refuses to go past the point that throws the unhandled exception - the same popup pops up again on each attempt to continue. I would like to push past this point and continue into the code I have set up via SetUnhandledExceptionFilter(). Is that possible?
This strongly upvoted answer suggests that it might be, via an option under Tools -> Options then Debugging -> General regarding unwinding the stack... but a comment on the answer suggests the option may have disappeared from VS2017. I found the option in VS 2015, but it does not have the desired effect. Is the accepted answer to that question therefore correct despite fewer votes - that continuing to debug past an unhandled exception is not possible by design?
Yes - it's possible. If you get to that pop up repeatedly, and the exception settings are such that the exception is NOT intercepted by the debugger (and therefore passed to the application's own exception handling), then it could be that your "unhandled" exception handling has already run, or does not exist in the form you think it does. Double-check where you have set breakpoints and make sure they are ones that stand to be hit.
Note also that if you have something like this to catch SEH exceptions (such as integer divide by zero):
__try
{
// set up and run the application
}
__except( RecordUnhandledException( GetExceptionInfo() ) )
{
}
... then the debugger can hide RecordUnhandledException() from you. That is, if you set a breakpoint on the line where the exception is (deliberately) thrown, and try to step into it, the debugger may step straight back to that point by executing the handling code in a single step that makes it invisible to you. However, if it produces other output, you should be able to see that output. If not, it may take an explicit breakpoint within RecordUnhandledException() to reveal that it exists and step through its logic.
In good old time, invalid memory access or unhandled exception in application resulted in some form messagebox displayed.
It seems to me that recently this stopped to be true. I can create a small application that does nothing else than write to NULL pointer, run it from the windows shell and it just dies silently.
I have Visual C++ commandline tools installed and using to compile that small app (plain C++ and win32 SDK). App is compiled in 64bit mode.
Any clue what is going on? I am really missing those crash messageboxes...
It's true by default this message boxes are disabled. You can do a few things about it:
1. (Re)Enable the messagebox (most probably what you are looking for)
Press Start and type gpedit.msc. Than navigate to Computer Configuration -> Administrative Templates -> Windows Components -> Windows Error Reporting -> Prevent display of the user interface for critical errors and select Disabled.
This will bring back at least some error messages if your application crashes.
2. Setup an Unhandled Exception Filter (probably dangerous)
Install an exception handler filter and filter for your desired exceptions. The drawback here is, the filter is called on every thrown exception.
3. Setup a signalhandler (also dangerous)
Basically like this.
void SignalHandler(int signal)
{
printf("Signal %d",signal);
throw "!Access Violation!";
}
int main()
{
typedef void (*SignalHandlerPointer)(int);
SignalHandlerPointer previousHandler;
previousHandler = signal(SIGSEGV , SignalHandler);
}
4. Use Windows Error Reporting
As mentioned by IInspectable and described in his answer.
Option 2 and 3 can become quite tricky and dangerous. You need some basic understanding in SEH exceptions, since different options can lead to different behavior. Also, not everything is allowed in the exception handlers, e.g: writing into files is cosidered extremly dangerous, or even printing to the terminal. Plus, since you are handling this exceptions, your program won't be terminated, means after the handler, it will jump right back to the erroneous code.
If you want your process to always show the error UI, you can call WerSetFlags with a value of WER_FAULT_REPORTING_ALWAYS_SHOW_UI. Or use any other applicable option offered by Windows Error Reporting, that suits your needs (like automatically creating a crash dump on unhandled exceptions).
I'm a beginner with the windows api so there must be something i don't understand here. In my main function i'm using a try-catch to catch all uncaught exceptions, but for some reason, exceptions i throw from somewhere else in the code are never caught. My application uses a single (main) thread.
I'm throwing like this :
throw "ClassName::methodName() - Error message";
And catching the exceptions outside of the message loop :
try {
while(GetMessage(args...)) {
TranslateMessage(args...);
DispatchMessage(args...);
}
}
catch( const char * sExc ) {
::MessageBox(args...);
}
I first thought it was a problem of types mismatching, but then i added a catch(...) with ellipsis and i still caught nothing. If you ask, yes, i'm sure the exception is thrown. Isn't it a problem related to some kind of asynchronousness or something like that ?
Thanks for your help !
It depends on the specific message that's getting dispatched. But no, not all of them allow the stack to be unwound through Windows internal code. Particularly the messages that involve the window manager, WM_CREATE for example. There's a backstop inside Windows that prevents the stack from being unwound past that critical code. There's also an issue with exceptions in 32-bit code that run on the 64-bit version of Windows 7, they can get swallowed when the message needs to traverse the Wow64 boundary several times. Fixed in Windows 8.
On later Windows versions this can also activate "self-healing" code, automatically activating an appcompat shim that swallows the exception. You'll get a notification for that, easy to dismiss. You'll then see the first-chance exception notification in the VS Output window but your program keeps running. Okayish for the user perhaps but not great while you are debugging of course. Run Regedit.exe and navigate to HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Persisted and check if your program is listed there. Just delete the entry.
Long story short, it is not safe to catch exceptions outside of the message loop. You have to do it inside the window procedure.
You are talking about "Windows Structured Exception Handling" (http://msdn.microsoft.com/en-us/library/windows/desktop/ms680657%28v=vs.85%29.aspx). C++ exceptions are not thrown.
If you want to go the troublesome route: _set_se_translator
See also: Can a C program handle C++ exceptions? (The windows API is not C++)
We have an unmanaged C++ application that utilizes 3rd party APIs to read CAD files. On certain corrupted CAD files, the 3rd party library crashes and brings our EXE down with it. Because of this our main application is a separate EXE and in this way it does not get affected by the crash. Howevever, we end up with annoying Microsoft Error Reporting dialogs.
I do not want to disable Microsoft Error Reporting system wide. Is there a way to turn off error reporting for a single application, so that if it crashes, it crashes silently without error popup dialogs?
On Vista and above, the WerAddExcludedApplication API function can be used to exclude a specified application executable from error reporting. As far as I'm aware, there's no similar option on XP and other legacy OS versions.
However, since WER will only kick in on unhandled application exceptions, you should be able to suppress it by adding a "catch-all" exception handler to your EXE. See vectored exception handling for some ideas on how to achieve that.
Note that suppressing all unhandled exceptions is generally a bad idea (and will, for example, cause your app to fail Windows Logo certification), so you should not use this technique indiscriminately...
Yeah, there's something you can do. Call SetUnhandledExceptionFilter() in your main() method to register a callback. It will be called when nobody volunteers to handle the exception, just before the Microsoft WER dialog shows up.
Actually doing something in that callback is fraught with trouble. The program has died with, invariably, something nasty like an AccessViolation exception. Which often is tripped by heap corruption. Trying to do something like displaying a message box to let the user know is troublesome when the heap is toast. Deadlock is always lurking around the corner too, ready to just lock up the program without any diagnostic at all.
The only safe thing to do is to have a helper process that guards your main process. Wake it up by signaling a named event in your callback. Give it the exception info it needs with a memory-mapped file. The helper can do pretty much anything it wants when it sees the event signaled. Including showing a message, taking a minidump. And terminating the main process.
Which is exactly how the Microsoft WerFault helper works.
Hans Passant's answer about SetUnhandledExceptionFilter is on the right track. He also makes some good points about not being able to do too much within the callback because various parts of the process could be in an unstable state.
However, from the way the issue is described, it doesn't sound like you want to do anything except tell the system not to put up the normal crash dialog. In that case, it's easy and should be safe regardless of what parts of the process the crash may have affected.
Make a function something like this:
LONG WINAPI UnhandledExceptionCallback(PEXCEPTION_POINTERS pExceptPtrs)
{
if (IsDebuggerPresent())
// Allow normal crash handling, which means the debugger will take over.
return EXCEPTION_CONTINUE_SEARCH;
else
// Say we've handled it, so that the standard crash dialog is inhibited.
return EXCEPTION_EXECUTE_HANDLER;
}
And somewhere in your program (probably as early as possible) set the callback:
SetUnhandledExceptionFilter(UnhandledExceptionCallback);
That should do what you want - allow any crashes of that particular program to die silently.
However, there's something else to note about this: Any time you bring in 3rd-party components (DLLs, OCXs, etc) there is a risk that one of them may also call SetUnhandledExceptionFilter and thus replace your callback with their own. I once encountered an ActiveX control that would set its own callback when instantiated. And even worse, it failed to restore the original callback when it was destroyed. That seemed to be a bug in their code, but regardless I had to take extra steps to ensure that my desired callback was at least restored when it was supposed to be after their control was shutdown. So if you find this doesn't appear to work for you sometimes, even when you know you've set the callback correctly, then you may be encountering something similar.
I found myself in exactly this situation while developing a Delphi application. I found that I needed two things to reliably suppress the "app has stopped working" dialog box.
Calling SetErrorMode(SEM_NOGPFAULTERRORBOX); suppresses the "app has stopped working" dialog box. But then Delphi's exception handler shows a message box with a runtime error message instead.
To suppress Delphi's exception handler I call SetUnhandledExceptionFilter with a custom handler that terminates the process by calling Halt.
So the skeleton for a Delphi client app that runs code prone to crashes becomes:
function HaltOnException(const ExceptionInfo: TExceptionPointers): Longint; stdcall;
begin
Halt;
Result := 1; // Suppress compiler warning
end;
begin
SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetUnhandledExceptionFilter(#HaltOnException);
try
DoSomethingThatMightCrash;
except
on E: Exception do
TellServerWeFailed(E.Message);
end;
end.
I'm not at all sure, but perhaps SetErrorMode or SetThreadErrorMode will work for you?
I have a Windows application written in C++ that occasionally evaporates. I use the word evaporate because there is nothing left behind: no "we're sorry" message from Windows, no crash dump from the Dr. Watson facility...
On the one occasion the crash occurred under the debugger, the debugger did not break---it showed the application still running. When I manually paused execution, I found that my process no longer had any threads.
How can I capture the reason this process is terminating?
You could try using the adplus utility in the windows debugging tool package.
adplus -crash -p yourprocessid
The auto dump tool provides mini dumps for exceptions and a full dump if the application crashes.
If you are using Visual Studio 2003 or later, you should enable the debuggers "First Chance Exception" handler feature by turning on ALL the Debug Exception Break options found under the Debug Menu | Exceptions Dialog. Turn on EVERY option before starting the debug build of the process within the debugger.
By default most of these First Chance Exception handlers in the debugger are turned off, so if Windows or your code throws an exception, the debugger expects your application to handle it.
The First Chance Exception system allows debuggers to intercept EVERY possible exception thrown by the Process and/or System.
http://support.microsoft.com/kb/105675
All the other ideas posted are good.
But it also sounds like the application is calling abort() or terminate().
If you run it in the debugger set a breakpoint on both these methods and exit() just for good measure.
Here is a list of situations that will cause terminate to be called because of exceptions going wrong.
See also:
Why destructor is not called on exception?
This shows that an application will terminate() if an exceptions is not caught. So stick a catch block in main() that reports the error (to a log file) then re-throw.
int main()
{
try
{
// Do your code here.
}
catch(...)
{
// Log Error;
throw; // re-throw the error for the de-bugger.
}
}
Well, the problem is you are getting an access violation. You may want to attach with WinDBG and turn on all of the exception filters. It may still not help - my guess is you are getting memory corruption that isn't throwing an exception.
You may want to look at enabling full pageheap checking
You might also want to check out this older question about heap corruption for some ideas on tools.
The most common cause for this kind of sudden disappearance is a stack overflow, usually caused by some kind of infinite recursion (which may, of course, involve a chain of several functions calling each other).
Is that a possibility in your app?
You could check the Windows Logs in Event Viewer on Windows.
First of all I want to say that I've only a moderate experience on windows development.
After that I think this is a typical case where a log may help.
Normally debugging and logging supply orthogonal info. If your debugger is useless probably the log will help you.
This could be a call to _exit() or some Windows equivalent. Try setting a breakpoint on _exit...
Have you tried PC Lint etc and run it over your code?
Try compiling with maximum warnings
If this is a .NET app - use FX Cop.
Possible causes come to mind.
TerminateProcess()
Stack overflow exception
Exception while handling an exception
The last one in particular results in immediate failure of the application.
The stack overflow - you may get a notification of this, but unlikely.
Drop into the debugger, change all exception notifications to "stop always" rather than "stop if not handled" then do what you do to cause the program failure. The debugger will stop if you get an exception and you can decide if this is the exception you are looking for.
I spent a couple hours trying to dig into this on Visual Studio 2017 running a 64-bit application on Windows 7. I ended up having to set a breakpoint on the RtlReportSilentProcessExit function, which lives in the ntdll.dll file. Just the base function name was enough for Visual Studio to find it.
That said, after I let Visual Studio automatically download symbols for the C standard library, it also automatically stopped on the runtime exception that caused the problem.