Can I view an unhandled exception in the Visual Studio 2017 Debugger? - c++

A library I am using (zmq) throws an exception. The debugger breaks and informs me.
How, if possible, can I see this exception. Specifically the what() message?
Without having to place try/catch around it and printing to the output stream.
It does not appear in the Autos or Locals watch lists. I have searched the stack frames around the point at which it occured.
Adding $exception to a manual watch list simply returns a value of "identifier $exception is undefined"
Using memory explorer to interrogate the exception's location does not show anything useful.
I have read this can be done when using the CLR - can I do it in regular C++?

Referencing this answer:
You'll get a window when the exception is thrown with the option to break/continue/ignore. Copy and paste the hex address this dialog reports, then click the break button. Now in a watch window, enter something like:
(std::exception*)0xXXXXXXXX

(1) Please check that whether the Exception messages was enabled in the output window under Tools->Options->Debugging->Output window.
(2)If it still no exception messages, one possible reason is that zmq really doesn't support the Exception throw feature of VS. Of course, you could write a general app like C# or VC++ which can prove it. If other apps have no this issue, we would think about the specific zmq.

Step 1. Identify the exception (it would be logged in the output window in VS)
Step 2. Put an exception breakpoint with the exception you saw from the output.
If this is ZeroMQ, I'd wager you're Sending 2 requests on a REQ socket without waiting for a reply.

your output window
(View/Output or click CTRL + ALT + O)
is where you should see the message, but you may need to check the exceptions option:
Look here for more detail

As far as I'm aware, this isn't currently possible. I've added a User Voice suggestion here but I'm not sure when, if ever, Microsoft will implement this feature.
For now, what you can do is take the Type and Location of the exception (from the message 'Exception thrown at Address in Module: Microsoft C++ exception: Type at memory location Location.', and then add to the Watch window the expression '(Type*)Location'. If Type is some internal exception type that you don't have access to, then you can hope it derives from std::exception and cast to that instead.

Related

Is it possible to continue debugging past an unhandled exception in Visual Studio?

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.

If application crashes (eg. segfault or unhandled exception), since some Win10 update it now seems to die silently

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).

C++ / WIndows - Can't catch 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++)

First-chance exception with Pantheios

My app was running fine until I tried to debug it with the Application Verifier. After that I started getting "First-chance exception... : An invalid handle was specified" and the issue seems to be in the "bailout.c" file in Pantheios:
hFile = CreateFileA("logging-bailout.txt"
, GENERIC_WRITE
, 0
, NULL
, OPEN_ALWAYS
, 0
, NULL); <--- this is where it crashes, line 442
And message:
First-chance exception at 0x7769f8cd in myapp.exe: 0xC0000008: An invalid handle was specified.
=======================================
VERIFIER STOP 0000000000000300: pid 0x3814: Invalid handle exception for current stack trace.
00000000C0000008 : Exception code.
00000000111DE950 : Exception record. Use .exr to display it.
00000000111DE460 : Context record. Use .cxr to display it.
0000000000000000 : Not used.
=======================================
This verifier stop is continuable.
After debugging it use `go' to continue.
=======================================
Before the console just logged the exceptions that I got with Pantheios and I didnt really care too much about. However, now when the app crashes on the first occurrence of logging using Pantheios it's time for me to deal with this, but I'm not too sure sure how to.
I was following this guide when setting up my Pantheios: http://www.codeproject.com/Articles/27119/Using-Callback-Back-ends-with-the-Pantheios-Loggin
In every file I have logging I have the following lines in the source file:
#include <pantheios/pantheios.hpp>
#include <pantheios/inserters/boolean.hpp>
#include <pantheios/inserters/integer.hpp>
#include <Shared/logs.h>
logs.h contains:
#include <pantheios/implicit_link/core.h>
#include <pantheios/implicit_link/fe.simple.h>
#include <pantheios/implicit_link/be.WindowsConsole.h>
I also call pantheios::init(); before doing any logging.
I'm using Visual studio 2010 and are including the following lib-files under "Additional Dependencies":
$(PANTHEIOS_ROOT)\lib\pantheios.1.core.vc10.mt.debug.lib
$(PANTHEIOS_ROOT)\lib\pantheios.1.be.WindowsConsole.vc10.mt.debug.lib
$(PANTHEIOS_ROOT)\lib\pantheios.1.fe.simple.vc10.mt.debug.lib
$(PANTHEIOS_ROOT)\lib\pantheios.1.util.vc10.mt.debug.lib
However, all my logging looks like this:
First-chance exception at 0x750bb9bc in myapp.exe: Microsoft C++ exception: stlsoft::winstl_project::windows_exception at memory location 0x1822bda0..
20120423-104817.497: failed to write message to log file; given message follows: [myapp.Qt.Framework.13424, 23/04/2012 10:48:17.496 a.m.; Debug]: "some logging"
when calling pantheios::log(pantheios::debug, "some logging");
Then, all my logging is written to a "bailout"file in the same folder as the project. This worked before but it was a big bullet on my "To-do-list" (but a bit further down than other things).
So now my question is, how do I fix this? Followed every tutorial I can find but with no success. And why did my app decide to not accept this anymore after running the Ms Application Verifier? Makes no sense.
First chance exceptions mean only that an exception was thrown. It does not mean you have a bug in your program, just that the debugger is showing you that an exception is being thrown, so you have a chance to examine it before it is propagated up the call chain. If the exception is caught by an exception handler (e.g. for logging), your application continues, otherwise the debugger gives you a second-chance exception notification to inform you that the application will exit due to an unhandled exception.
If you do not want to receive the first-chance exception notifications, you can turn it off in your debugger. This link may help on how to turn off exception handling in Application Verifier.
To work around this problem, turn off exceptions testing in Application Verifier. To do this, follow these steps:
1.Start Application Verifier.
2.Under Applications, click the GDI+ program that you want to test.
3.Under Tests, expand Basics.
4.Click to clear the Exceptions check box.
5.Run the GDI+ program that you want to test.
You can also configure the debugging tool to make sure that you do not experience a breakpoint in the debugging tool when an access violation occurs.
The alternative (turning off exception notification in MSVS) is via "Debug->Exceptions..."
Alternatively, if it is possible, make sure the exception does not get thrown in the first place. You will need to examine the nature of the exception (e.g. file not found) and fix the condition that is preventing the intended operation.
Given the nature/purpose of Application Verifier, I would suggest the latter approach: AV is telling you that something incorrect is going on that might have been ok previously, but can cause problems later on (depending on enviornment, circumstances, etc.)

Displaying exception debug information to users

I'm currently working on adding exceptions and exception handling to my OSS application. Exceptions have been the general idea from the start, but I wanted to find a good exception framework and in all honesty, understand C++ exception handling conventions and idioms a bit better before starting to use them. I have a lot of experience with C#/.Net, Python and other languages that use exceptions. I'm no stranger to the idea (but far from a master).
In C# and Python, when an unhandled exception occurs, the user gets a nice stack trace and in general a lot of very useful priceless debugging information. If you're working on an OSS application, having users paste that info into issue reports is... well let's just say I'm finding it difficult to live without that. For this C++ project, I get "The application crashed", or from more informed users, "I did X, Y and Z, and then it crashed". But I want that debugging information too!
I've already (and with great difficulty) made my peace with the fact that I'll never see a cross-platform and cross-compiler way of getting a C++ exception stack trace, but I know I can get the function name and other relevant information.
And now I want that for my unhandled exceptions. I'm using boost::exception, and they have this very nice diagnostic_information thingamajig that can print out the (unmangled) function name, file, line and most importantly, other exception specific information the programmer added to that exception.
Naturally, I'll be handling exceptions inside the code whenever I can, but I'm not that naive to think I won't let a couple slip through (unintentionally, of course).
So what I want to do is wrap my main entry point inside a try block with a catch that creates a special dialog that informs the user that an error has occurred in the application, with more detailed information presented when the user clicks "More" or "Debug info" or whatever. This would contain the string from diagnostic_information. I could then instruct the users to paste this information into issue reports.
But a nagging gut feeling is telling me that wrapping everything in a try block is a really bad idea. Is what I'm about to do stupid? If it is (and even if it's not), what's a better way to achieve what I want?
Putting a try/catch block in main() is okay, it doesn't cause any problems. The program is dead on an unhandled exception anyway. It isn't going to be helpful at all in your quest to get the all-important stack trace though. That info is gonzo when the catch block traps the exception.
Catching a C++ exception won't be very helpful either. The odds that the program dies on a an exception derived from std::exception are pretty slim. Although it could happen. Much more likely in a C/C++ app is death due to hardware exceptions, AccessViolation being numero uno. Trapping those requires the __try and __except keywords in your main() method. Again, very little context is available, you've basically only got an exception code. An AV also tells you which exact memory location caused the exception.
This is not just a cross-platform issue btw, you can't get a good stack trace on any platform. There is no reliable way to walk the stack, there are too many optimizations (like framepointer omission) that make this a perilous journey. It is the C/C++ way: make it as fast as possible, leave no clue what happened when it blows up.
What you need to do is debug these kind of problems the C/C++ way. You need to create a minidump. It is roughly analogous to the "core dump" of old, a snapshot of the process image at the time the exception happens. Back then, you actually got a complete dump of the core. There's been progress, nowadays it is "mini", somewhat necessary because a complete core dump would take close to 2 gigabytes. It actually works pretty well to diagnose the program state.
On Windows, that starts by calling SetUnhandledExceptionFilter(), you provide a callback function pointer to a function that will run when your program dies on an unhandled exception. Any exception, C++ as well as SEH. Your next resource is dbghelp.dll, available in the Debugging Tools for Windows download. It has an entrypoint called MiniDumpWriteDump(), it creates a minidump.
Once you get the file created by MiniDumpWriteDump(), you're pretty golden. You can load the .dmp file in Visual Studio, almost like it's a project. Press F5 and VS grinds away for a while trying to load .pdb files for the DLLs loaded in the process. You'll want to setup the symbol server, that's very important to get good stack traces. If everything works, you'll get a "debug break" at the exact location where the exception was thrown". With a stack trace.
Things you need to do to make this work smoothly:
Use a build server to create the binaries. It needs to push the debugging symbols (.pdb files) to a symbol server so they are readily available when you debug the minidump.
Configure the debugger so it can find the debugging symbols for all modules. You can get the debugging symbols for Windows from Microsoft, the symbols for your code needs to come from the symbol server mentioned above.
Write the code to trap the unhandled exception and create the minidump. I mentioned SetUnhandledExceptionFilter() but the code that creates the minidump should not be in the program that crashed. The odds that it can write the minidump successfully are fairly slim, the state of the program is undetermined. Best thing to do is to run a "guard" process that keeps an eye on a named Mutex. Your exception filter can set the mutex, the guard can create the minidump.
Create a way for the minidump to get transferred from the client's machine to yours. We use Amazon's S3 service for that, terabytes at a reasonable rate.
Wire the minidump handler into your debug database. We use Jira, it has a web-service that allows us to verify the crash bucket against a database of earlier crashes with the same "signature". When it is unique, or doesn't have enough hits, we ask the crash manager code to upload the minidump to Amazon and create the bug database entry.
Well, that's what I did for the company I work for. Worked out very well, it reduced crash bucket frequency from thousands to dozens. Personal message to the creators of the open source ffdshow component: I hate you with a passion. But you're no longer crashing our app anymore! Buggers.
Wrapping all your code in one try/catch block is a-ok. It won't slow down the execution of anything inside it, for example. In fact, all my programs have (code similar to) this framework:
int execute(int pArgc, char *pArgv[])
{
// do stuff
}
int main(int pArgc, char *pArgv[])
{
// maybe setup some debug stuff,
// like splitting cerr to log.txt
try
{
return execute(pArgc, pArgv);
}
catch (const std::exception& e)
{
std::cerr << "Unhandled exception:\n" << e.what() << std::endl;
// or other methods of displaying an error
return EXIT_FAILURE;
}
catch (...)
{
std::cerr << "Unknown exception!" << std::endl;
return EXIT_FAILURE;
}
}
No it's not stupid. It's a very good idea, and it costs virtually nothing at runtime until you hit an unhandled exception, of course.
Be aware that there is already an exception handler wrapping your thread, provided by the OS (and another one by the C-runtime I think). You may need to pass certain exceptions on to these handlers to get correct behavior. In some architectures, accessing mis-aligned data is handled by an exception handler. so you may want to special case EXCEPTION_DATATYPE_MISALIGNMENT and let it pass on to the higher level exception handler.
I include the registers, the app version and build number, the exception type and a stack dump in hex annotated with module names and offsets for hex values that could be addresses to code. Be sure to include the version number and build number/date of your exe.
You can also use VirtualQuery to turn stack values into "ModuleName+Offset" pretty easily. And that, combined with a .MAP file will often tell you exactly where you crashed.
I found that I could train beta testers to send my the text pretty easily, but in the early days what I got was a picture of the error dialog rather than the text. I think that's because a lot of users don't know you can right click on any Edit control to get a menu with "Select All" and "Copy". If I was going to do it again, I would add a button
that copied that text to the clipboard so that it can easily be pasted into an email.
Even better if you want to go to the trouble of haveing a 'send error report' button, but just giving users a way to get the text into their own emails gets you most of the way there, and doesn't raise any red flags about "what information am I sharing with them?"
In fact, boost::diagnostic_information has been designed specifically to be used in a "global" catch(...) block, to display information about exceptions which should not have reached it. However, note that the string returned by boost::diagnostic_information is NOT user-friendly.