I have a call stack like below from my dump file.
I want to find my code in the call stack, but I can't.
What is start point to analyze my dump?
Link option of my program is release/Od.
msvcr120.dll!abort()
msvcr120.dll!terminate()
msvcp120.dll!_Call_func$catch()
msvcr120.dll!_CallSettingFrame()
msvcr120.dll!__CxxCallCatchBlock(_EXCEPTION_RECORD * pExcept=0x0000002885f9b010)
ntdll.dll!RcConsolidateFrames()
msvcp120.dll!_Call_func(void * _Data=0x00000028835d5ce0)
msvcr120.dll!_callthreadstartex()
msvcr120.dll!_threadstartex(void * ptd=0x000000288366e410)
kernel32.dll!BaseThreadInitThunk()
ntdll.dll!RtlUserThreadStart()
TL;DR: If you re-throw; the call stack will not show the original location, but something further up the stack and ntdll.dll!RcConsolidateFrames().
You will find ntdll.dll!RcConsolidateFrames() in your call stack for an unhandled exception instead of the actual location when the code uses catch(ANYTHING) + throw; in an x64 binary.
You see, if you catch and re-throw, the original call stack has been already unwound, and when you then throw; it will re-throw the original exception, but the call stack information is now messed up.
My observations for MSVC is that this will always happen with any throw; that is then unhandled and leads to a dump file. Specifically:
It does not matter whether you use catch(...) or catch(cppTypeEx&)
It does not matter whether it is a C++ exception (with /EHsc or /EHa) or a SEH exception (with /EHa).
It will look like this in the debugger as well as in a dump file.
Bottom line: throw;will mess up your call stack
Related
I have a weird situation. My game is definitely being built with debugging information, and I can merrily hit breakpoints and step through code, and look at data. No settings are unusual. I have ruled out multithreading as a problem.
When I have an actual bug, and a legitimate crash, i get no call stack. A typical crash bug will be
First-chance exception at 0x004678da in Democracy3Debug.exe: 0xC0000005: Access violation reading location 0x0000004c.
Unhandled exception at 0x774015de in Democracy3Debug.exe: 0xC0000005: Access violation reading location 0x0000004c.
And the callstack is just ntdll and some disassembly. I must have changed some option somewhere, but cannot imagine what. Any ideas?
Those errors are indicative of hardware exceptions due to an attempt on your part to access memory that your process cannot read or write. In particular, it looks like you are directly or indirectly attempting to access some element 76 bytes from the address referred to by some pointer, but that pointer is in fact null (thus the access violation reading location 0x0000004c).
Your debug information may not be invalid in any way, you simply may legitimately be in some code inside nt.dll -- for example, if you passed a null pointer to a Windows API function that does not permit them. If you don't have symbols loaded for nt.dll, you won't get a useful call stack.
It's also possible the access violation's coming from a bad pointer you passed that wasn't used until some callback was invoked by the Windows API, which might explain why you don't see your code anywhere in the stack frame.
Enabling break-on-throw in the VS IDE (Debug -> Exceptions, check the boxes for relevant exception types) can help you break earlier when this occurs, but may not help diagnosing the problem if it's legitimately not directly from your code.
You can also use structured exception handling to integrate these exceptions and C++'s exceptions for catching purposes. You may also want to look in to using a symbol server to get the symbols for the Windows DLLs.
Your exception isn't being caught, so it's moving up the call stack all the way to main and terminating your app.
MSDN:
If a matching handler (or ellipsis catch handler) cannot be found for
the current exception, the predefined terminate run-time function is
called.
There's usually an option to allow you to pause debugging when an exception is thrown.
How to: Break When an Exception is Thrown (Visual Studio 2012)
You could also have a catch statement at top level and examine the exception (.what() often gives an description) when you catch it.
Update: You most likely can't catch this exception because it's an Access violation (not a C++ exception, but the pause should still work afaik). If you're on Windows you could use SEH to catch it.
I have GDB attached to a process that is currently inside a catch(...) block.
Is there a known technique to access that thrown exception?
The program in question is a gcc/x86-64 binary, but I'm also curious about other builds.
As you say, you can re-throw it, so you can re-throw it inside another try/catch block with more specific clauses to extract the exception (and another ... if you want as well). You can even do this inside another function so you can centralize your exception handling.
Edit: I misunderstood the importance of gdb in your question, but you can apply the idea I described. Make a function that re-throws the exception you can set a breakpoint in:
void
helper()
{
try {
throw;
} catch (int i) {
// anything that won't get optimized away
volatile int j = i; // breakpoint here
}
}
Then in gdb just do call helper(). I just tested this to be sure it worked.
Further edit: If you literally mean I'm running a program under gdb right now and you are not exiting gdb until you are sure you can't get the exception, then it's time to look at eh_throw.cc and friends in the gcc source. __cxa_rethrow starts with:
__cxa_eh_globals *globals = __cxa_get_globals ();
__cxa_exception *header = globals->caughtExceptions;
You will have to examine all of those structures to figure out what's buried inside.
I have not tested this - but the exception (or at least a pointer to it) should probably be on the stack somewhere close to the head. I guess the exact position and format is implementation dependent, but you should be able casting different addresses in this area of the stack to your exception type (or at least to std::exception) and see if you get meaningful results.
If I'm catching a C++ exception of some kind, and in the catch statement throws a new break exception, will I ever be able to retain the original exception if post mortem debugging a crash dump in WinDbg? If so, how?
I've seen the usage of searching for CONTEXT (0001003f) on x86, but it's not valid on x64.
It is possible. You will need to know how to read x64 assembly and find exception record pointer. From there see http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx
This will allow you to see the exception object, but at the time the catch statement is executed, stack unwinding has already happened so you will not have the original stack.
I have a program failing with:
terminate called after throwing an instance of 'std::bad_alloc'
what(): St9bad_alloc
I imagine it's something to do with malloc/free, but I don't know which one.
What breakpoint can I in gdb set that will break on the error so that I can view a stack trace?
The program is a combination of C and C++, compiled with gcc 3.4.2.
It is not really malloc/free which causes the exception, it is "new" which is definitely in C++ part of your application. It looks like you are providing a parameter which is too big for "new" to allocate.
'std::bad_alloc' is caused by the following code for example:
int * p = new int[50000000];
What does backtrace says when you load crash dump into gdb?
If you cannot generate dump, you can ask GDB to stop when exception is thrown or caught.
Unfortunately, some versions of GDB support only the following syntax:
catch throw
which allows you to break application when any exception is thrown.
However, in help you see that it should be possible to run
catch throw std::bad_alloc
in newer versions.
And don't forget that:
(gdb) help catch
is a good source for other useful information.
It's quite possible that this happens due to some memory being overwritten, thus corrupting the memory allocation system's state (which is generally kept either before or after the memory blocks returned to the application).
If you have the possibility (i.e., you're on x86 Linux), run your program in Valgrind, it can often show you exactly where the corruption happens.
I have had this when trying to read in a file that doesn't exist... I'd try to create an internal buffer for the file contents, but because the file didn't exist, my creation of the buffer screwed up.
int lenth_bytes;
length_bytes = in_file.tellg();
new char [length_bytes]; // length_bytes hadn't been initialised!!!!
Remember kids, always initialise your variables :D and check for zero cases.
We're attempting to update our application in order to submit it for Vista certification. Part of the requirements are to handle only known exceptions and have Windows Error Reporting deal with all unhandled exceptions.
We have a global exception handler in our application (subscribed to the Application.ThreadException event) and in there, we perform certain processing for known exceptions, but if an exception is unknown we wish to throw it out for the app to terminate and WER to handle.
We cannot see a way of doing this and maintaining the call stack if we re-throw then the call stack is recreated.
We've looked at terminating via Environment.FailFast() but we don't believe that that gives the exception information we'd require.
Are we missing something obvious?
Why not just throw a new exception and set the InnerException property to be the unhandled one? The default StackTrace property will concatenate both traces together.
Bear in mind that if you're debugging from a memory dump that you've retrieved from WinQual then it'll be a native exception that's trapped anyway. It's almost always possible to walk back up the native stack and retrieve the managed exception and if you have symbols available it's usually easy to find out what went wrong. The stack trace of the managed exception will be redundant in this situation anyway.
Yes but we're within the Application.ThreadException global handler, not a catch block so we can't just call throw, we'd have to throw e.Exception.
Yea, as Marc states, just use THROW and the original exception will be re-thrown with the stack trace information preserved.
A THROW E will start the whole exception stack over again with the original stack information lost. Typically this is not what you want.
Alternative you can throw a new exception and add the original exception as an inner exception. Then your new exception could add additional bits of information.