06-18-2008 09:08 AM
So this is a tricky one...
To make the story as short as possible, I've "inherited" a test executive that interfaces with TestStand to run CVI based test code.
After running a test (dll) and closing the testexec (exe), I get a windows protection error. As stated:
The instruction at "0x63489bc3" referenced memory at "0x00000000", The memory could not be "read". Click on OK to terminate the program.
I've generated a map file for the application in an attempt to determine the location of this error. However the valid range of address in the map file runs from 00400000 to 006F1D90. Where you can see that the address specified is a full 2 significant places in difference.
In running the testexec under the compiler I get:
FATAL RUN-TIME ERROR
Unknown source position, thread id 0x00000FF4
The program has caused a 'General protection' fault at 001B:63489BC3
I can Break at this point but, like it says, it doesn't know where it is.
I've downloaded windows ProcessExplorer and ProcessMonitor in an attempt to find the associated thread ID. However, when run under CVI the testexec is considers it a child of CVI and doesn't show thread IDs any deeper than that. At least I've not figured out how.
The body of code for this testexec is very large and it's functions are mostly driven as callbacks from UI elements, thus obfuscating everything that much more.
What I'm looking for is a some place to start. I need a tool or method that will let me see what's going on at this address and maybe some how attach it to a symbol that I can then follow to a fix.
I'm running Windows XP Pro SP2, CVI 8.0.1, TestStand 3.5.0.725
06-18-2008 09:49 AM
06-18-2008 09:59 AM
This kind of error (on program termination) is commonly caused by failing to terminate threads/handles/timers, before unloading a dll that uses such a resource (which of course happens during a process shutdown). Is the error caused by just one particular test? Or one particular dll? It might be worth trying to use the debugger to break into the program before you get an error, in an attempt to identify the region of code before it gets unloaded.
JR
06-18-2008 10:16 AM - edited 06-18-2008 10:17 AM
Yeah, I've had this happen before with a handle used to communicate with a CompactFieldPoint device, but the code was infinitely less complex and I was able just to "hunt" it down without any "fanciness". But, I'd like a more consistent way of discovery. Oddly enough it was only in migrating platforms from 2000 to XP that this flaw became visible.
I have broken the code prior to it's termination, and looked over sections where the "cleanup" is supposed to happen. Though given the non-sequential nature (lots of event driven stuff ) of the testexec I've not a whole lot of idea about what has and hasn't been used at that point. The debugger will show me a little in terms of what's "visible" to that section of code in terms of "Global" and "Local"; But, in terms of what others threads/timers/whatever were made elsewhere I'm still in the dark.
I've more testing to do in terms of limiting it down to one particular set of UUT test.
If only the compiler had dynamic a way to associate allocators and deallocators...
I've also tried calling the CVIDynamicMemoryAllocation (I think that's right) function. It does not seem to think that I've allocated any memory, but did take issue with some other structures. My problem with it was that it gave me the names, but not the location of instantiation. Leaving me do keyword searches against all the code. Say in my "main" function I call the CVIDynamic... will it notice allocations happening done via UI callbacks from a call to RunUserInterface? I assumed I should just put it at the beginning of the application, perhaps I should move it to the end?
Thanks for the help!06-18-2008 02:56 PM
I hoped to use Dr. Watson, but to no avail. For some reason it would not capture the application crash. I ensured it was setup at the default debugger in the registry. By instructions I found I called drwtsn32 -i to set it up. But for whatever reason the application will crash and it will not update the log file. I can call it with the processor id, but this will terminate the application, not at the point of failure.
I waited until the application errored out, and before acknowledging the "ok" button I called drwtsn32 with the processor id. It killed the application but then nothing was put into the log!