My Visual C++ application is compiled with /EHA option, letting me catch structured exceptions (division by zero, access violation, etc). I then translate those exceptions to my own exception class using _set_se_translator(). My goal is to improve our logging of those types of exceptions.
I can get the type of exception from the EXCEPTION_RECORD structure, and the exception address. I would like to be able to gather more information, like the source file/location where the exception is thrown, the call stack, etc. Is that possible?
I do create an exception minidump on structured exceptions - is there a tool to automatically get the call stack from that?
Call stack and all other exception information is available using minidump post-mortem debugging:
http://www.codeproject.com/KB/debug/postmortemdebug_standalone1.aspx
AFAIK, generating stack information in the place for logging is impossible without .pdb files. Usually .pdb files are not installed on a client computer.
One idea I had is to use different translator functions in some of the different threads (there is one translator function per thread) so I can know from which thread the structured exception was thrown.
It's not so practical because you can't pass any argument to the translator function, so you need a bunch of different translator functions.
Related
My program calls into a library for which I don't have source code (Direct2D ID2D1DCRenderTarget::BeginDraw). Visual Studio debugger gives me a "first-chance" when that library code throws an exception. I have the definition of the thrown object (it's a _com_error). How can I inspect that object in the debugger at that point?
I tried modifying my code to catch the exception, but the library is catching (and handling?) the exception before it propagates back to the call site. I tried poking around at the registers and memory in the debugger at the point of the first-chance exception, but I don't know enough about how VS maps exceptions into the ABI to really know where to look. Is there a particular register that points to the exception object?
Why I'm asking: I'm trying to figure out if this exception is part of the normal operation of the library or if it's indicative of a bug in how I'm using the library. The library appears to be handling whatever exceptional condition arises, but I'm not sure if it's just covering up a mistake on my part. In certain circumstances[*], it happens in every iteration of a hot loop[**], so I'm concerned about the performance impact of the exception propagation. I'm hoping the details in the _com_error exception object will give me a clue as to what's going on under the covers.
[*] The certain circumstances are that a high-contrast theme is selected. When a "standard" theme is selected, no exception is thrown.
[**] It's a hot loop because it's every frame of an animation. And, actually, it's a few times per frame because I'm animating on a few render targets simultaneously and the exception happens on the BeginDraw call for every target.
The address listed in the throw should be the address of a _com_error object. If he turns on the Microsoft Symbol Server, you should be able to inspect the properties of the _com_error and the IErrorInfo it’s holding internally.
Example:
Exception thrown at 0x757708F2 in ConsoleApplication1.exe: Microsoft C++ exception: _com_error at memory location 0x00BAFA70.
Watch window:
However, I would suggest you turn on the sdk layers instead:
https://msdn.microsoft.com/en-us/library/windows/desktop/ee794277(v=vs.85).aspx
That should tell you if anything is going wrong with his D2D calls better than inspecting an error that may be intentional.
I have a Windows service written in (Visual) C++ with a very detail logging functionality that has often helped me find the cause of errors customers are sometimes experiencing. Basically I check every return value and log what is going on and where errors are coming from.
Ideally, I would like to have the same level of detailed visibility into exceptions (like array out of range, division by zero, and so on). In other words: I want to know exactly where an exception is coming from. For reasons of readability and practicality I do not want to wrap every few lines of code into separate try/catch blocks.
What I have today is one general catch-all that catches everything and logs an error before shutting down the program. This is good from the user's point of view - clean shutdown instead of app crash - but bad for me because I only get a generic message from the exception (e.g. "array out of range") but have no idea where that is coming from.
Wouldn't it be better to remove the catch-all and let the program crash instead? I could direct the customer to have Windows create an application crash dump (as described here). With the dump file WinDbg would point me exactly to the position in the code where the exception was thrown.
You can register a custom, vectored exception handler by calling AddVectoredExceptionHandler .
This will get called whenever an exception gets thrown, and in it you can generate a stack trace that you can then save off for logging purposes.
Writing the code to do this is not completely trivial but not rocket surgery either.
I've never personally done it in C++, but I would be surprised if there weren't ready-built libraries that do this available somewhere, if you don't have the time or inclination to do it on your own.
You can throw exceptions with description where the error occurred and why:
throw std::string("could not open this file");
If you do not want to write different descriptions for every possible error you can use standard macros __FILE__ and __LINE__:
#define _MyError std::string("error in " __FILE__ + std::to_string(__LINE__))
// ...
throw _MyError;
If source file name and line of the error is not enough and you need more information, for example stack trace or memory values, your program can generate a debug report. Google Breakpad is a C++ library that allows you to do that in a portable way. Class wxDebugReport from wxWidgets library is an alternative. On Windows the debug reports may include a minidump file that can be loaded in Visual Studio and allows you to analyse the error in a way similar to debugging.
Wouldn't it be better to remove the catch-all and let the program
crash instead?
You can catch-all and
Write a (more personal) message about the fatal error that occurred, forcing the application to be closed. Do not let the program continue: you don't know what happened, where. Continuing might cause damage to the user's data, follow up errors, etc.
Tell the user to contact you with specifics as to what they did and what happened.
Tell the user to include the log file your application has generated.
If you don't do something like this, then you might just as well remove the catch-all.
For reasons of readability and practicality I do not want to wrap
every few lines of code into separate try/catch blocks.
And yet if you want your program to be able to recover, this is exactly what you have to do. What you could do is
Tell the user what happened, perhaps what was wrong with the input that may have caused it. Don't make it sound technical.
Save any data the user has entered so their work is not completely lost
You know at which step the failure happened. Undo that step, i.e. throw away objects / data, and go back to the point before the exception.
Restore data the user had entered from the second point so they don't need to repeat actions all over again.
The point being that your program can return to a valid state.
As per the title, I can't locate any dump files when this program I support is crashing.
The application's logs clearly mention its a SIGSEGV exception, but I have searched my entire hard drive, and there are no .dmp files anywhere to be found.
The developers of the program have seen similar issues elsewhere but have so far been unable to explain why this is happening - and we're kind of a bit stuck at the moment.
The last section in the application logs reads as :
Received signal SIGSEGV, segmentation violation.
OurApplication::sigHandler 11.
Removing signal handlers.
OurApplication::signalCatched.
OurApplication::sigHandler: exiting application.
Removing signal handlers.
My limited understanding of this is that our application's signal handler might be 'neutralising' the SIGSEGV exception that got thrown. And therefore no core dump is getting generated... I did raise this idea with the developers but they never really seemed have investigated if this might be the reason. The theory they raised in counter was that they think the reason the dmp isn't getting generated is because the program may be crashing twice very close together.
So the questions I have at this point are:
Are there any Windows7 parameters that control the creation of a .dmp file?
Are there any requirements/flags that need to be compiled into a program in order for it (or windows) to create a core dump file if it crashes?
I'm 99% sure it must be windows that is responsible for creating the core file, since the program itself would be dead/terminated when it crashed, correct?
Are there any other things I should be aware of, or check for, or 'evidence' I can collect and then show our developers?
Many thanks in advance
Are there any Windows7 parameters that control the creation of a .dmp file?
There are parameters which control the creation of a crash dump: see MSDN on Collecting user-mode dumps.
Are there any requirements/flags that need to be compiled into a program in order for it (or windows) to create a core dump file if it crashes?
You don't need to compile anything in for the previous answer to work. However, the program needs to terminate due to an unhandled exception, which means you need to let the exception bubble up and not being handled by the unhandled exception handler.
I'm 99% sure it must be Windows that is responsible for creating the core file, since the program itself would be dead/terminated when it crashed, correct?
As stated above, Windows can handle that and it's a good idea to have Windows handle the crash. Imagine that your program is broken due to a memory leak. Some memory has been overwritten. In that case, your unhandled exception handler can be destroyed. Windows, however, still has full control over the process, can suspend it and create a dump from outside (rather from inside).
Are there any other things I should be aware of, or check for, or 'evidence' I can collect and then show our developers?
Well, suggest letting the dump be created by Windows due to above reasons. Then they also don't need to implement a configuration setting (you don't want the crash dump file to be always created, do you?). You don't need to implement a limiting number for the files. You don't need to implement a check for disk space, etc.
And you can suggest to read the Windows Internals 6 books.
Consider creating your own minidump file programatically. Should be plenty of code around showing how to do it. You can try here:
https://stackoverflow.com/search?q=minidump
This way, you're not relying on Dr. Watson or any other settings to create a dump file. Instead you will be calling the functions in DBGHELP.DLL to create the dump file.
I know that there has to be quite a lot of documentation about this topic on the internet.
But doing research for hours without a proper answer is quite frustrating. So I assume I can't put my question in a good phrase. So here the full version:
I'm doing a presentation about try-catch, but it's rather boring to do the basic things. I know what try catch is and I know how it works.
But here comes the magic: Let's assume I use C++.
The compiler will create a read only list on the heap with structures that give information about the functions in the try-block. That includes pointers for start and end of the routine, information about about the object type of the exception and so on. (Please correct me if I'm wrong)
Okay. Now an exception occurs. The so called error handler (here we go, who is the error handler?) will look up all the data about the failing routine and get the appropriate catch routine. The correct catch is found by comparing the exception object that is generated through the error with the exception objects in the catch.
For example: InvalidCastException (or something like that) is created. There is a catch for that, the error is handled and all objects that are created in the try block are destroyed.
But: How can the program notice that there is an exception? Is this handled by the program, by the runtime or maybe even by the processor (I read something about Ring0 and Ring1, different levels in the CPU oO).
There are two ways of implementing exception handling in C++. First is to use Itanium ABI Zero-Cost exception handling. The second one is to use a pair of setjmp/longjmp to handle control flow for exceptions. The first is a preferred implementation for every modern compiler.
The program does not "listen" for exceptions, so it doesn't notice exceptions. Instead, it raises and processes them as part of the control flow. For example, "throw" is always raising an exception which triggers transfers the execution to exception handling code.
Even though these exceptions are heavily used in C++ which provides a nice interface to "throw" and "catch" them, they are also used in C, and even in the Linux kernel.
You can read more here:
http://sourcery.mentor.com/public/cxx-abi/abi-eh.html
http://llvm.org/docs/ExceptionHandling.html
Zero cost exception handling vs setjmp/longjmp
The fact a stack/function trace is supplied in Java/C# exceptions is really useful. Is there a handy way to do this in C++ or would I have to bake extra data into every method/function?
Most debuggers can be set up to pause your program each time an exception is thrown (either any exception or an exception for which there's no handler) so that you can obserevr a call stack.
Also if your code only throws exceptions of classes you control you can put code for dumping the call stack in those classes constructors.
If you are considering adding metdata to your exceptions, You may consider using boost exception handling . boost::exception allows adding information to an exception after it has been thrown.
Some OS APIs provide for stack traces, I know that the Windows API has StackWalk64 or something like that that can do stack tracing.
However, if you can't depend on such a thing, then pretty much all you can do is either ship a debug build, or do it manually.