Failure to get call stack in a debug build C++ - c++

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.

Related

How to find the location where exception occurred in VS C++

I am getting this exception:
Microsoft C++ exception: std:out_of_range at memory location 0xBlahBlahBlah
How can I find this location in my code?
One way is to enable the "Break When Thrown" for everything in the Exception Settings. It will have a list of exception types that can be turned on via checkboxes. I usually will turn them all on and go. You may get a few handled exceptions along the way but you shouldn't miss the problem one.
You can find it under: Debug->Windows->Exception Settings
Once you're done, I recommend returning it to its default settings (there's a graphical button for it) so you don't keep breaking every time a handled exception is thrown.
Here are problem resolution steps:
Find memory location displayed in "exception: EEEE at memory location 0xXXXXX" location In disassembly window.
Set breakpoint at that location and run program until it breaks.
Check call stack to find the function that actually threw the exception.
For some reason debugger did not break when std::out_of_range exception was thrown even though debugger exception settings were set to break when std::exception was thrown.
My approach is setting up a break point somewhere, and then press keep pressing F10 until it throw the exception. Now you know where the bug is.
This error is a run time logical error which can happen in many cases and to find it you should trace your code and look for some logical errors. e.g.
int x[4];
x[5] = 1;
int this case you are using a memory unit which is not allowed.

MS Visual Studio 2005 C++ exception handling

I have a C++ application built in MS Visual Studio 2005 that links to a 3rd party library. For a certain input, the application crashes in the 3rd party library (apparently somewhere in realloc.c; so has to be a memory issue of some kind). I ran in release because the input is huge. So I ran until it crashes and then choose to debug. While I separately debug the guilty function, I was hoping to use some exception handling to prevent the application from crashing and instead exit cleanly. So I used something like:
try {
//- call 3rd party application function that fails
}
catch(...) {
//- handle exception or whatever
Logger::Fatal("Fatal error: Exiting...");
return false;
}
But to my surprise the application still crashes! I was expecting to see it display the error message since I've presumably caught all exceptions with the ellipsis (...); what am I missing here? I even tried setting /EHca (was /EHsc) in Project Properties -> C/C++ -> Code Configuration -> Enable Exception Handling. On a related note about what might be causing the problem, is the following usage correct?
my_class* mc[] = {nil, nil, nil};
for (int i = 0; i < 3; ++i) {
mc[i] = new my_class();
//-Do stuff with mc[i]
if (mc[i] != nil) {
delete mc[i];
mc[i] = nil;
}
}
The failure to get the exception handling working is rather puzzling. I would certainly appreciate ideas/insights from the C++ gurus out there. BTW, the same problem also occurs on Linux (RHEL5) but I am currently trying to get the exception handling to work on Windows.
NOTE: When I let it debug after the crash. I do get an "Access violation..unable to read location" message. With this updated info, I was hoping something in C++ would still work on both Windows & Linux for such crashes.
Have you tried catching the crash by calling SetUnhandledExceptionFilter?
As Miguel suggested, a correct way to solve your problem is probably to use SetUnhandledExceptionFilter. But I'd like to explain your phenomena in details nevertheless.
First of all, not all the program "crashes" are related to exceptions. For instance, CRT may trigger program termination upon errors, such as invalid element access in a vector, or a pure virtual destructor call. If you want to cover those cases as well - see set_unexpected, set_terminate and etc.
Besides of this, catch block may only catch exceptions thrown from the appropriate code block. OTOH there may be functions that are called elsewhere, such as window procedures (if applicable), other threads and etc.
Now, regarding your problem. Let's first realize why things like catch(...) may catch things like access violation, and etc, and why this does not always happen (like in your case).
Windows provides its own exception handling mechanism - SEH, structured exception handling. It's far superior to C++ exception handling. In addition hardware interrupts (caused by CPU) are automatically "converted" into SEH exceptions, so that the code that uses SEH handles both software exceptions and hardware failures.
Microsoft C++ compilers actually implement C++ exceptions via SEH. That is throw is implemented via RaiseException with specifying C++ - specific exception code and parameters, catch is a C++ - specific wrapper for __except, and for every object with destructor the compiler generates something similar to __finally block. And this also works vice-versa. When a non-C++ exception is raised - the same code generated for C++ exceptions is executed.
In addition there are so-called compiler exception handling options that affect both the compiler exception handling code generation, and its behavior in runtime. They are called exception handling models:
synchronous. The compiler generates a code that is guaranteed to work correctly only if exceptions are raised explicitly. This includes throw statments, and all the "foreign" functions whose code is not visible to the compiler (in some variations - only C++ foreign functions). In particular reading from memory is considered "safe".
asynchronous. The compiler is not allowed to assume anything about where exceptions may arise. Hence it generates the code that should work correctly even if exception is arises from accessing a memory address.
In addition, CRT code that's invoked in catch (...) deliberately ignores non-C++ exceptions, unless asynchronous EH model is choosen.
So that if you want catch (...) to catch non-C++ exceptions - you must choose the asynchronous EH model.
Once I've written an article on the codeproject, after I had a related problem in driver development. It explains all this in details.

Getting the real C++ exception on x64

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.

CoGetClassObject gives many First-chance exceptions in ATL project. Should I worry?

I have written a COM object that in turn uses a thrid party ActiveX control. In my FinalConstruct() for my COM object, I instantiate the ActiveX control with the follow code:
HRESULT hRes;
LPCLASSFACTORY2 pClassFactory;
hRes = CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
bool bTest = SUCCEEDED(hRes);
if (!bTest)
return E_FAIL;
if (SUCCEEDED(CoGetClassObject(__uuidof(SerialPortSniffer), CLSCTX_INPROC_SERVER, NULL,
IID_IClassFactory2, (LPVOID *)(&pClassFactory))))
{ ... more set up code
When I step over the line if (SUCCEEDED(CoGetClassObject(__uuidof(SerialPortSniffer), ...,
I get 20+ lines in the Output window stating:
First-chance exception at 0x0523f82e
in SillyComDriver.exe: 0xC0000005:
Access violation writing location
0x00000000.
I also get the lines:
First-chance exception at 0x051e3f3d
in SillyComDriver.exe: 0xC0000096:
Privileged instruction. First-chance
exception at 0x100ab9e6 in
SillyComDriver.exe: 0xC000001D:
Illegal Instruction.
Notice these are first-chance exceptions. The program runs as expected I can access the third party methods/properties. Still, I'm left wondering why they are occurring. Perhaps my way of instantiating the ActiveX control (for which I want use of it's methods/properties and not it's GUI stuff) is incorrect? Besides the code I'm showing, I also put the line
#import "spsax.dll" no_namespace
in the stdafx.h
That's all the code necessary for my simple demo project. I noticed this problem because I had (inadvertently) set the "break on exceptions" options in my "real" project and it was breaking on this line. Once I removed it, it also works.
If you're read this far thank you, and perhaps I can ask one other minor question. In my demo project, if I right click on SerialPortSniffer and "go to definition", it takes me to the file C:....\AppData\Local\Temp\spsax.tlh. Can someone explain that? Finally, in my "real" project, right clicking on SerialPortSniffer and going to difinition leads to "The symbol 'SerialPortSniffer' is not defined". It doesn't seem to affect the program though. Is there some setting I've messed up?
By the way, all my code is written w/ VS2008.
Thanks,
Dave
These are definitely the worst kind of hardware exceptions that you'd ever could encounter in a Windows program. There is absolutely no reason that something as simple as a serial port sniffer should ever throw exceptions like that, let alone catch them and handle them.
Still, it does and there's nothing you can do about it. You can only hope and pray that this doesn't byte you in the ass some day. Personally, that component would quickly end up on my thrash heap.
The #import statement auto-generates code from the COM type library. It generates a .tlh file with declarations and a .tli file with COM method wrappers. The .tlh file contains smart pointers (xxxxPtr) to make instantiating the COM object and calling its methods easy. That's why "Goto Definition" takes you to that file.
It's usually nothing to worry about.
When an exception is thrown, the debugger is notified and depending on the debugger configuration, it may stop the application or let the application resume normally. This is a "first-chance" exception. If the application resumes, then it may catch the exception, and do whatever is necessary in the exceptional case.
If the application does not handle the exception, it becomes a "second-chance" exception and the debugger is notified again. The debugger is usually configured to stop the application at this point to let you see what went wrong.
So if you get a first-chance exception and not receive a second-chance exception later, it's usually means that nothing is wrong, and the application is handling exceptions in a "graceful" matter.
(Also see Link)

Application Shutdown and Windows Error Reporting

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.