A few days ago I was testing the latest version of C++ Memory Validator x64.
The testing was going fine until I tried testing a particular test tool of ours. C++ Memory Validator x64 would inject into the test tool, start injecting then just die at some point.
No problem, just set the injection flags to inject a breakpoint and that’ll trigger the debugger as soon as we inject. This works with most software and with all our test tools. No joy. Hmmm, puzzling.
OK, try again, but when we get to CreateProcess() I’ll attach the debugger to the paused process myself. That’ll work. Right? Wrong. The debugger does attach and thats great. I resume the process and the the debugger spits out a really impenetrable error message.
“Debugger:: An unhandled non-continuable exception was thrown during process load”.
That is a really useful and useless message all in one.
|Useful||Unhandled. No one handled it, so in that case it will be a problem.|
|Useful||Non-continuable. Even if someone could handle it, you can’t recover from it. Major problem.|
|Useless||No description of what the exception was, no exception code, nothing. Why?|
One possible next step would be to repeat this sequence but before resuming the application, go to the debugger and open the Exceptions dialog from the Debug menu.
When the Exceptions dialog is displayed go to the Win32 exceptions part of the settings and expand it so that you can see the various exceptions that will be reacted to. We need to tell the debugger to react to some of these exceptions. I’ve included screenshots with the exceptions highlighted. Feel free to enable other exceptions that you think may be troublesome.
Having enabled the appropriate exceptions you can resume the process and see if the debugger reacts to any of these more obscure exceptions.
It turned out the problem was a DLL dependency was failing and thus resulting in a module not found exception.
In my case what had tripped me up was that we’ve been doing static analysis of our software recently using PC-Lint from Gimpel Software combined with Visual Lint from Riverblade. PC-Lint does the hard word of analysing your source code and Visual Lint organises the mountain of results into useful and usable information. If you’ve ever seen the log file from PC-Lint you’ll understand the benefits of a tool like PC-Lint to organise the results.
The result of the static analysis is that we’ve changed many APIs. Many objects that were passed in as objects (and implicitly incurred object copying penalties) are now passed as const references. Many char * strings and wchar_t * strings are now passed as const and so on. We’ve done this all over – changing our DLL APIs, everything.
It’s great, we’ve found bugs because of this. Really useful. But I digress. One side effect of this is that the anything dynamically or statically linked against our libraries now fails to work. We had rebuilt all the dynamically linked tests but forgotten the statically linked one. The test I was performing was statically linked.
Rebuilding and relinking the statically linked test meant that the DLL imports/exports now resolved and the DLL would load. Problem solved.
The change to our APIs is a one time change and will be painful for the folks that use our linkable APIs, but the benefits are increased software robustness for everyone, ourselves and customers alike.