C++ Win32 Unhandled Exception Handler - c++

currently I used SetUnhandledExceptionFilter() to provide callback to get information when an unhandled exception was occurred, that callback will provides me with EXCEPTION_RECORD which provides ExceptionAddress.
[1]what is actually ExceptionAddress is? does it the address of function / code that gives exception, or the memory address that some function tried to access?
[2]is there any better mechanism that could give me better information when unhandled exception occured? (I can't use debug mode or add any code that affect runtime performance, since crash is rare and only on release build when code run as fast as possible)
[3]is there any way for me to get several callstack address when unhandled exception occured.
[4]suppose ExceptionAddress has address A, and I have DLL X loaded and executed at base address A-x, and some other DLL Y at A+y, is it good to assume that crash was PROBABLY caused by code on DLL X?

(1) The ExceptionAddress is the address of the code that caused the exception. In case of an access violation error (0xC0000005) one of the additional arguments of the exception record holds the address from which a read or a write was attempted and another argument tells if it was a read or a write. This is documented in the link you provide in the question.
(2) no. additionally, adding debug information to a release build doesn't affect performance. You can verify this and see for yourself.
(3) dbghelp.dll provides a complete library to investigate crashes. among athers there is StackWalk64 which allows you to get the complete stack of the crash.
(4) calling GetModuleHandleEx with the ExceptionAddress as an argument will get you the handle of the dll where the offending code resides. As to the question of which DLL CAUSED the crash, this depends on your definition of "CAUSED". A crash which occur in one dll can be the result of a bug in a completely different and unrelated dll.

Not direct answer to your question, but possibly this is what you need:
http://www.codeproject.com/KB/debug/postmortemdebug_standalone1.aspx
Post-mortem debugging is the way to find exception place when the program runs in Release build on a client computer.

Also, not a direct answer to your question, but I think it could help you:
http://www.codeproject.com/KB/applications/blackbox.aspx
It will produce a readable output to screen or file, which will give you a stack output to find the place where the exception occured along with other useful information.
It worked good for me.
There is also an improved version named "Blackbox revised". Can't find the website right now, though.

Related

Unhandled Win32 exception

At runtime, when myApp.exe crashes i receive "Unhandled Win32 exception" but how would i know which exception was occurred? where did something went wrong?
For a Native C++ app see my earlier answer here: Detect/Redirect core dumps (when a software crashes) on Windows for catching the unhandled exception (that also gives code for creating a crash dump that you can use to analyse the crash later. If the crash is happening on a development system then in Visual Studio (I'm assuming you're using that, if not other IDEs will have something similar), in Debug/Exceptions tick the 'Thrown' box for 'Win32 Exceptions'.
Typically, Windows will give you several hexadecimal numbers as well. Chances are that the exception code will be 0xC0000005. This is the code of an Access Violation. When that happens, you also will have three additional bits of information: the violating address, the violated address, and the type of violation (read, write or execute).
Windows won't narrow it down any further than that, and often it couldn't anyway. For instance, if you walk past the end of an array in your program, Windows likely won't realize that you were even iterating over an array. It just sees "read:OK, read:OK, read:out of bounds => page fault => ACCESS VIOLATION". You will have to figure that out from the violating address (your array iteration code) and the violated address (the out-of-bounds address behind your array).
If it's a .Net app you could try to put in a handledr for the UnhandledException event. You can find more information about it and some sample code here.
In general it's a good sign that your exception handling is broken though, so might be worth going through your code and finding places that could throw but where you don't handle exceptions.
Use the debugger. You can run the program and see what exception is been thrown that kills your application. It might be able to pinpoint the location of the throw. I have not used the VS debugger for this, but in gdb you can use catch throw to force a breakpoint when an exception is thrown, there should be something similar.

run-time error and program crash

How can I specify a separate function which will be called automatically at Run-Time error to prevent program crash?
Best thing as mentioned already is to identify the area where the crash ic occuring and then fix the piece of code. This is the idealistic approach.
In case you are unable to find that out another alternative is to do structured exception handling in the areas where you suspect crashes to occur. Once the crash occurs you capture what ever data you want and process it. Meanwhile you can change the settings in windows service manager to restart your application whenever it crashes. Hope this answers your question.
Also in case you are looking for methods to capture the crash and analyse debugdiag and windbg are some of the standard tools that people use to take the crash dumps.
If your in Windows you need to write your own custom runtime check handler. Use:
_RTC_SetErrorFunc
to install your custom function in place of
_CrtDbgReport.
Here is a good article on how to do it:
http://msdn.microsoft.com/en-us/library/40ky6s47(VS.71).aspx
If by run-time error you mean an unhandled exception, don't do it. If an unhanded exception propagates through your code, you want your app to crash. Maybe create a dumpfile on the way down, sure. But the last thing you want to do is catch the exception, do nothing, and continue running as if nothing had happened in the first place.
When an exception is generated, whatever caused the problem could have had other effects. Like blowing the stack or corrupting the heap. If you were to silently ignore these exceptions and continue running anyway, your app might run for a while and seem OK, but something underneath is unstable. Memory could be corrupt, resources might not be available, who knows. You will eventually crash. Bu ignoring unhandled exceptions and running anyway, all you do is delay the inevitable, and make it that much more difficult to diagnose the real problem, because when you do crash, the stack will be in a totally different and probably unrelated place from what caused the initial problem.

Visual Studio 2008 Team: No call stack when I throw an exception

I am building the debug version of my app, with full symbols. I set a breakpoint on the following line:
throw std::range_error( "invalid utf32" );
When the breakpoint hits, my stack looks normal. I can see all my routines. But if I run, and let the exception get thrown, I see a worthless stack. it has MyApp.exe!_threadstartex() towards the bottom, a few disabled entries labeled kernel32.dll, and the line "Frames below may be incorrect and/or missing" etc.
This really sucks! Because very often I will get an exception in my debug build, and this $5000 development environment is not even showing me my own stack! I am statically linking with everything so its not a DLL problem.
Help!
The problem is that you don't have any debug symbols loaded for the location the debugger stopped at. This means the rest of the call stack is nonsense.
Fortunately the solution is easy: Starting at the top of the call stack window, right-click on each greyed-out entry (e.g. KernelBase.dll!...) and select Load Symbols From / Microsoft Symbol Servers. After doing this for one or two entries your true call stack will be revealed.
I bet the problem is that you don't have "break on exception" enabled. I had this same problem, and couldn't believe I couldn't find useful answers to this...how did my vs2008 get configured differently? I don't know. But one day my call stacks just became useless when a debugged program crashed. Finally I went and checked all those classes of exceptions to get the program to "break on exception", and now it breaks right when the exception is thrown (e.g. bad access) and I have a useful call stack to debug with. Yay!
I think you mix up smth. here.
If you catch the exception in some catch statement or it is propagated until main your stack was unwound and you can not expect VC++ to remember the entire stack.
For example in Java stack trace is part of the exception itself. Dependent on you compiler you can write an exception class which records the stack trace if it is constructed (but not copy constructed) and carries the information. When the class is caught you can evaluate the info. If you program using MFC take a look at AfxDumpStack.
Hope that helps,
Ovanes
P.S: This DDJ article might be helpful to you: C++ Stack Traces
Probably you are watching the callstack of the wrong thread.
Go to the Tread Panel, in Debug->Windows->Threads, and then select the correct thread.

Application crashes says : Access violation reading location

My application crashes after running for around 18 hours. I am not able to debug the point in the code where it actually crashes. I checked the call stack- it does not provide any information as such. The last few calls in the call stack are greyed out-meaning I cannot see the code of that part-they all belong to MFC libraries.
However, I get this 'MicroSoft Visual Studio' pop-up when it crashes which says :
Unhandled exception at 0x7c809e8a in NIMCAsst.exe: 0xC0000005:
Access violation reading location 0x154c6000.
Could the above information be useful to understand where it is crashing.Is there any software that could tell me a particular memory address is held by which variable in the code.
If you can't catch the exception sometimes you just have to go through your code line by line, very unpleasant but I'd put money on it being your code not in MFC (always is with my bugs). Check how you're using memory and what you're passing into the MFC functions extra carefully.
Probably the crash is caused by a buffer overflow or other type of memory corruption. This has overwritten some part of the stack holding the return address which has made the debugger unable to reconstruct the stack trace correctly. Or, that the code that caused the crash, you do not have correct sybols for (if the stack trace shows a module name, this would be the case).
My first guess would be to examine the code calling the code that crashed for possible issues that might have caused it. Do you get any other exceptions or error conditions before the crash? Maybe you are ignoring an error return? Did you try using the Debug Heap? What about adplus? Application verifier to turn on heap checks?
Other possibilities include to run a tool like pclint over the code to check for obvious issues of memory use. Are you using threads? Maybe there is a race condition. The list could go on forever really.
The above information only tells you which memory was accessed illegally.
You can use exception handling to narrow down the place where the problem occurs, but then you need at least an idea in which corner to seek.
You say that you're seeing the call stack, that suggests you're using a debugger. The source code of MFC is available (but perhaps not with all vc++ editions), so in principle one can trace through it. Which VC++ version are you using?
The fact that the bug takes so long to occur suggests that it is memory corruption. Some other function writes to a location that it doesn't own. This works a long time, but finally the function alters a pointer that MCF needs, and after a while MFC accesses the pointer and you are notified.
Sometimes, the 'location' can be recognized as data, in which case you have a hint. F.e. if the error said:
Access violation reading location 0x31323334
you'd recognize this as a part of an ASCII string "1234", and this might lead you to the culprit.
As Patrick says, it's almost definitely your code giving MFC invalid values. One guess would be you're passing in an incorrect length so the library is reading too far. But there are really a multitude of possible causes.
Is the crash clearly reproducible?
If yes, Use Logfiles! You should use a logfile and add a number statements that just log the source file/line number passed. Start with a few statements at the entrypoint (main event handler) and the most common execution paths. After the crash inspect the last entry in the logfile. Then add new entries down the path/paths that must have been passed etc. Usually after a few iterations of this work you will find the point of failure. In case of your long wait time the log file might become huge and each iteration will take another 18 hours. You may need to add some technique of rotating log files etc. But with this technique i was able to find some comparable bugs.
Some more questions:
Is your app multithreaded?
Does it use any arrays not managed by stl or comparable containers (does it use C-Strings, C/C++-Arrays etc)?
Try attaching a debugger to the process and have the debugger break on access violations.
If this isnt possible then we use a tool called "User mode process dumper" to create a memory dump of the process at the point where the access violation happened. You can find this for download here:
http://www.microsoft.com/downloads/details.aspx?FamilyID=E089CA41-6A87-40C8-BF69-28AC08570B7E&displaylang=en
How it works: You configure rules on a per-process (or optionally system-wide) basis, and have the tool create either a minidump or a full dump at the point where it detects any one of a list of exceptions - one of them being an access violation. After the dump has been made the application continues as normal (and so if the access violation is unhandled, you will then see this dialog).
Note that ALL access violations in your process are captured - even those that are then later handled, also a full dump can create a while to create depending on the amount of memory the application is using (10-20 seconds for a process consuming 100-200 MB of private memory). For this reason it's probably not a good idea to enable it system-wide.
You should then be able to analyse the dump using tools like WinDbg (http://www.microsoft.com/whdc/devtools/debugging/default.mspx) to figure out what happened - in most cases you will find that you only need a minidump, not a full dump (however if your application doesnt use much memory then there arent really many drawbacks of having a full dump other than the size of the dump and the time it takes to create the dump).
Finally, be warned that debugging access violations using WinDbg can be a fairly involed and complex process - if you can get a stack trace another way then you might want to try that first.
This is the cause of possible memory leak, there are various blogs could teach on checking for memory leaks in application, you simply make observations on Physical Memory of the process from Windows Task Manager, you could find at some stage where memory keep increasing & run out of memory. You can also try running with windbg tool to identify memory leaks in your code. I havent used this tool just giving some heads up on this.
This question is pretty old, and I've had the same problem,
but I've quickly solved it - it's all about threads:
First, note that updating GUI can only be done at the Main Thread.
My problem was that I've tried to handle GUI from a Worker Thread (and not a Main Thread) and i've got the same error: 0xC0000005.
I've solved it by posting a message (which is executed at the Main Thread) - and the problem was solved:
typedef enum {
WM_UPDATE_GUI
}WM_MY_MSG
// register function callback to a message
BEGIN_MESSAGE_MAP(CMyDlg, CDlgBase)
ON_MESSAGE(WM_UPDATE_GUI, OnUpdateGui)
END_MESSAGE_MAP()
// For this example - function that is not invoked in the Main Thread:
void CMyDlg::OnTimer()
{
CString str_to_GUI("send me to gui"); // send string to gui
// Update_GUI(str_to_GUI); // crashed
::PostMessage(hWnd, MyMsg::WM_UPDATE_GUI, (WPARAM)&str_to_GUI, 0);
}
HRESULT CMyDlg::OnUpdateGui(WPARAM wParam, LPARAM lParam)
{
CString str = *(CString*)wParam; // get the string from the posted message
Update_GUI(str);
return S_OK;
}

Heisenbug: WinApi program crashes on some computers

Please help! I'm really at my wits' end.
My program is a little personal notes manager (google for "cintanotes").
On some computers (and of course I own none of them) it crashes with an unhandled exception just after start.
Nothing special about these computers could be said, except that they tend to have AMD CPUs.
Environment: Windows XP, Visual C++ 2005/2008, raw WinApi.
Here is what is certain about this "Heisenbug":
1) The crash happens only in the Release version.
2) The crash goes away as soon as I remove all GDI-related stuff.
3) BoundChecker has no complains.
4) Writing a log shows that the crash happens on a declaration of a local int variable! How could that be? Memory corruption?
Any ideas would be greatly appreciated!
UPDATE: I've managed to get the app debugged on a "faulty" PC. The results:
"Unhandled exception at 0x0044a26a in CintaNotes.exe: 0xC000001D: Illegal Instruction."
and code breaks on
0044A26A cvtsi2sd xmm1,dword ptr [esp+14h]
So it seems that the problem was in the "Code Generation/Enable Enhanced Instruction Set" compiler option. It was set to "/arch:SSE2" and was crashing on the machines that didn't support SSE2. I've set this option to "Not Set" and the bug is gone. Phew!
Thank you all very much for help!!
4) Writig a log shows that the crash happen on a declaration of a local int variable! how could that be? Memory corruption?
What is the underlying code in the executable / assembly? Declaration of int is no code at all, and as such cannot crash. Do you initialize the int somehow?
To see the code where the crash happened you should perform what is called a postmortem analysis.
Windows Error Reporting
If you want to analyse the crash, you should get a crash dump. One option for this is to register for Windows Error Reporting - requires some money (you need a digital code signing ID) and some form filling. For more visit https://winqual.microsoft.com/ .
Get the crash dump intended for WER directly from the customer
Another option is to get in touch witch some user who is experiencing the crash and get a crash dump intended for WER from him directly. The user can do this when he clicks on the Technical details before sending the crash to Microsoft - the crash dump file location can be checked there.
Your own minidump
Another option is to register your own exception handler, handle the exception and write a minidump anywhere you wish. Detailed description can be found at Code Project Post-Mortem Debugging Your Application with Minidumps and Visual Studio .NET article.
So it doesnnt crash when configuration is DEBUG Configuration? There are many things different than a RELEASE configruation:
1.) Initialization of globals
2.) Actual machine Code generated etc..
So first step is find out what are exact settings for each parameter in the RELEASE mode as compared to the DEBUG mode.
-AD
1) The crash happens only in the Release version.
That's usually a sign that you're relying on some behaviour that's not guaranteed, but happens to be true in the debug build. For example, if you forget to initialize your variables, or access an array out of bounds. Make sure you've turned on all the compiler checks (/RTCsuc). Also check things like relying on the order of evaluation of function parameters (which isn't guaranteed).
2) The crash goes away as soon as I remove all GDI-related stuff.
Maybe that's a hint that you're doing something wrong with the GDI related stuff? Are you using HANDLEs after they've been freed, for example?
Download the Debugging tools for Windows package. Set the symbol paths correctly, then run your application under WinDbg. At some point, it will break with an Access Violation. Then you should run the command "!analyze -v", which is quite smart and should give you a hint on whats going wrong.
Most heisenbugs / release-only bugs are due to either flow of control that depends on reads from uninitialised memory / stale pointers / past end of buffers, or race conditions, or both.
Try overriding your allocators so they zero out memory when allocating. Does the problem go away (or become more reproducible?)
Writig a log shows that the crash happens on a declaration of a local int variable! How could that be? Memory corruption?
Stack overflow! ;)
4) Writig a log shows that the crash happen on a declaration of a local int variable!how could that be? Memory corruption
I've found the cause to numerous "strange crashes" to be dereferencing of a broken this inside a member function of said object.
What does the crash say ? Access violation ? Exception ? That would be the further clue to solve this with
Ensure you have no preceeding memory corruptions using PageHeap.exe
Ensure you have no stack overflow (CBig array[1000000])
Ensure that you have no un-initialized memory.
Further you can run the release version also inside the debugger, once you generate debug symbols (not the same as creating debug version) for the process. Step through and see if you are getting any warnings in the debugger trace window.
"4) Writing a log shows that the crash happens on a declaration of a local int variable! How could that be? Memory corruption?"
This could be a sign that the hardware is in fact faulty or being pushed too hard. Find out if they've overclocked their computer.
When I get this type of thing, i try running the code through gimpels PC-Lint (static code analysis) as it checks different classes of errors to BoundsChecker. If you are using Boundschecker, turn on the memory poisoning options.
You mention AMD CPUs. Have you investigated whether there is a similar graphics card / driver version and / or configuration in place on the machines that crash? Does it always crash on these machines or just occasionally? Maybe run the System Information tool on these machines and see what they have in common,
Sounds like stack corruption to me. My favorite tool to track those down is IDA Pro. Of course you don't have that access to the user's machine.
Some memory checkers have a hard time catching stack corruption ( if it indeed that ). The surest way to get those I think is runtime analysis.
This can also be due to corruption in an exception path, even if the exception was handled. Do you debug with 'catch first-chance exceptions' turned on? You should as long as you can. It does get annoying after a while in many cases.
Can you send those users a checked version of your application? Check out Minidump Handle that exception and write out a dump. Then use WinDbg to debug on your end.
Another method is writing very detailed logs. Create a "Log every single action" option, and ask the user to turn that on and send it too you. Dump out memory to the logs. Check out '_CrtDbgReport()' on MSDN.
Good Luck!
EDIT:
Responding to your comment: An error on a local variable declaration is not surprising to me. I've seen this a lot. It's usually due to a corrupted stack.
Some variable on the stack may be running over it's boundaries for example. All hell breaks loose after that. Then stack variable declarations throw random memory errors, virtual tables get corrupted, etc.
Anytime I've seen those for a prolong period of time, I've had to go to IDA Pro. Detailed runtime disassembly debugging is the only thing I know that really gets those reliably.
Many developers use WinDbg for this kind of analysis. That's why I also suggested Minidump.
Try Rational (IBM) PurifyPlus. It catches a lot of errors that BoundsChecker doesn't.