Link to home
Start Free TrialLog in
Avatar of NakedTimeMan
NakedTimeMan

asked on

Handling (or not)Unhandled Exception C0000005

Hi everyone,

Here is my situation:  I wrote this program that runs simultaneously 192 threads all the time (doing all kinds of stuff).

Here us the problem:  About once a day I get a dialog box that says: "the instruction at 0x00408b59 referenced memory at 0x0045a514 . The memory could not be read.  Click OK to terminate the application or click CANCEL to debug. (by the way the addresses usually change...)

Of course the first thing that I did was to go into the debugger and see if I could see anything in there...  But it was just a bunch of assembler...  And of course that didnt even begin telling me what to look for on my source code.... (ie. possible errors, missuses, etc) (If at least I knew what part of the program was generating the exception I could fix IT!!)

My question is this:  what would happen if I dissable the Exception handler on the project settings?  (under [project], settings, C/C++, C++ Language)

Would the program crash?

(I would like the program to terminate cleanly WITHOUT message boxes or things like that) so I can have another program just re-start it.

Any and all help will be appreciated.



Avatar of Answers2000
Answers2000

This means your program has a bug, a pointer is pointing somewhere it shouldn't hence crashing it.

The way to fix it is to find the bug - changing exception handling settings won't help

Try building with debug info and running under the debugger.  You may be able to see back up the stack to see where the crash occured.

Otherwise I recomend spending a few $ on Bounds Checker from Numega.  This will help you find these kinds of bugs more easily.

See
http://www.numega.com/products/vc.shtml
Avatar of NakedTimeMan

ASKER

Hi Answer2000,

Sorry, but I can not grant you the 200 points,  you pretty much tell me what I already said on my original question.  I know I have a bug, but I cant find it (yet), and I mentioned on my question that I have already gone through the debug thing during execution... and it didnt help me at all.

What I was also asking is "will the program exit "clean" if I disable the exception handling"?  Right now the program doesnt actually exit, it sits there waiting for me to click OK or CANCEL.  If this is the case and disabling it will make the program abort completely that would be great, since I have a program that checks if this one is running and if its not it starts another instance of it.  The way things are now, the program hasnt technically exited, so the 2nd program thinks that the first on is still running and it doesnt do anything about it.

I am increasing the points to 400, to see if I can generate more responses, so far yours is the only one (thanks!) and it hasnt solved my problem...

Thanks again.
NakedTimeMan


The error message you get is not caused by C++ exceptions, but by using a dangling pointer, as Answers2000 said.

Since you can't find the bug using the debugger, I suspect the bug is caused by the *interaction* between several threads. Since the debugger changes the timing behavior of your program, this may cause the bug to disappear (a heisenbug). Using BoundsChecker is a good advice, but it may also cause the bug to disappear. Still, I recommend using it anyway.

I would advice to do a code review with someone experienced with multi-threading. There are many things to be aware of when writing multi-threaded programs, and the best way to check them all is still to have someone experienced look at the code.

If this is not an option at your company, try to "take the program apart" while keeping the bug. You should try to end up with a small program that still has the bug. Then, when the code is short enough, just post it here and let some experts review it for you :-)

Good luck!
The reason why you only see assembler is probably because you have not recompiled your code with the appropriate debugging option.  Even so, it should still be possible to get the call stack to find out where it went wrong.

If you have, then you are probably using some 3rd party software which you can't recompile in debug mode, so the problem is probably the way you are using the 3rd party code.  Which operating system are you using?  Are you using any libraries from other suppliers?

If this is not help, then a useful tool for tracking memory leaks, array bounds errors and other dangling pointer type errors on UNIX and NT is Purify from http://www.pureatria.com/ (I think).

Hi Braveheart,

I compiled both a debug and a release version.  The debug version contains all the debug info that VC will put out.  But still there is nothing there that clues me into what might be causing this.  I have done this before in other projects and usually the debugger shows the  assembler code mixed with my original code, therefore I would always know what to check for.  This time this is not the case,  the debugger seems to be showing me some part of the memory that does not belong to my program.  ( I assume, since there is none of my code in sight)

I am as you say using third party libraries, but I dont think the problem is there. (for unrelated reasons I changed libraries from one vendor to another and the problem persists)

BTW I am running VC 5 developer studio under windows nt4.  

Sorry, but these are 400 points we are talking about, and I would like an answer, and I havent gotten one yet to my original question.  Will the program exit cleanly (and not create any additional problems,) without any dialog boxes etc if I disable the exception handling option on the compiler.

You would think that i could try it out, but I can NOT risk that, this is a realtime program that interacts with 100's of users/hour and I cannot play rusian roulette with this.  (my boss would choke me, *lol*)

So what is the 3rd party product?

Some libraries insist on an incremental link, because they do non-kosher things such as writing after the allocated object code in what would otherwise be unallocated memory. After several incremental links the spare memory between the blocks of object code in the link can get eaten up, causing an access violation.
If the executable is now deleted (including all .ilk and .exp files, etc.) the problem goes away for a while until successive incremental links cause it to return.

Of course, this really causes a problem when the application is so large that the linker refuses to perform an incremental link and switches to a non-incremental link by itself - at least it tells you when it does this.

Another problem we have come across was using VC5 Developer Studio with the Microsoft Fortran Compiler (Powerstation?), version 4. We discovered thattThis combination is not supported and causes all sorts of problems in non-debug mode.  The workaround is to use Digital Visual FORTRAN, which works even on Intel.

So another problem could be using a mix of languages in the same executable, forming an unsupported combination.  So, how about some more information.

Another approach is write to a log file at strategic points throughout the code so that you get some idea of what is generating the dialog. Yeah, that's what we did on the IBM/360 some 20 years ago - the old techniques still work, even in this day and age.
Hey Braveheart,

Thanks for all the tips,

The 3rd party product I use is some external libraries for some hardware that this program uses. Its not your common program.... anyway, I can not get into specifics.

I use a printdebug function (I also like the good old tricks!!!, been programming for 11 years...)  But the problem is that I dont know exactly where OR what is causing the problem.  Therefore I dont know if what I'm printing is relevant or not... all the log files come out clean....

Thanks for your time
NakedTimeMan



Avatar of jkr
If you want to terminate you application upon an error, you'll have to supply your own exception filter by calling 'SetUnhandledExceptionFilter()'. This replaces the top-level SEH frame handler (typically 'UnhandledExceptionFilter()', the creator of those infamous dialog boxes) with your own one, in which you can decide whether you could successfully handle the exception ( return ( EXCEPTION_CONTINUE_EXECUTION);) or terminate the application ungracefully ( return ( EXCEPTION_EXECUTE_HANDLER);)
Since you are using 3rd party software, and you use a lot of threads, is that software thread-safe? This might be a silly question, but get's overlooked sometimes.

FlorizzzZzZz
First, let me state this clearly: The error message you are getting will NOT go away if you turn off exceptions. It is caused by using a dangling pointer, and not because of C++ exceptions.

Second, the fact that the bug is not deterministic (different addresses each time) and that it disappers when you use a debugger, suggests that it is caused by the INTERACTION between threads. This interaction is very sensitive to timing issues, which is why these kinds of bugs are hard to track.

The solution is, therefore, to ensure every part of your program is thread-safe. This includes 3rd party libraries, as TheMadManiac suggested, and every line of your code. This is not an easy task, but it is necessary. Sorry.
Thanks Yonat,

Thats what I was affraid off.   There is only one place on the program where there is interacion between threads, so if thats what causing the problem, I guess I can take (yet) another look at the code...


Consider "stripping off" the rest of the program. If you have a program with only this part and the bug still exists, you'll know it has to be there somewhere.
A very intresting tool to find such bugs could be BugTrapper from Mutek
Have a look to
http://www.mutek.com

Try this article
http://support.microsoft.com/support/kb/articles/q133/1/74.asp

It points out ways to use map files and stack tracing to find what causes such bugs.  Includes discussion of reading Dr Watson Logs, etc
'\0'
Sorry \0,

But I am asking about access violation exceptions, NOT about general protection faults.

Very interesting article, but not relevant to my situation,

Thanks

ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks JKR,

So the program WILL crash and EXIT without the dialog box, eh?

Anyway, I didnt want to have to write an exception handler, but that seems to be what I'm going to have to do...

Thanks for the info, and thanks for your time.

No, the dialog box will still remain with exception handling turned off, since there'll _ONLY_ be the top frame handler and no SEH frames (can be detected, when a fct. starts with 'MOV EAX,FS:[00000000]' it sets up a SEH frame, the C/C++ equivalent is '__try {}')
BTW: writing an exception handler is not too hard - feel free to add followup questions as comments.
Hey Jkr,

well, I hope (like you say) that writing one is not too hard (or time consuming) I need this thing fixed ASAP....

I've never writeen one... (never had to...) But I dont even know where to start.  If you have any suggested reading, or maybe even sample code, or anything like that, that would be greatly appreciated.

NakedTimeMan
OK - a quick example (for the beginning ;-):

/*
 *
 * Function:     LONG WINAPI    __XceptFilter    (   EXCEPTION_POINTERS* pExp)
 *
 * Description:
 *
 *  filter function for structured exception handling. This function is
 *  necessary due to a bug in ODBCJT32.DLL (Microsoft ODBC Desktop Driver
 *  Pack 3.0, Vers. ID 3.40.2829) which causes an access violation exception
 *  in 'RtlpWaitForCriticalSection()' (mem 0x77f6cb4e, call sequence
 *  BaseThreadStart()->MSJT3032@0x0401ffb2()->RtlEnterCriticalSection()->
 *  RtlpWaitForCriticalSection()) and/or at MSJT3032@0x040200a5 when
 *  'CDatabase::Close()' is called more than once within an application.
 *  This exception filter detects these two particular cases and suppresses
 *  the exceptions by signalling 'EXCEPTION_CONTINUE_EXECUTION' to the top-level
 *  exception handler of WIN32 (typically 'UnhandledExceptionFilter()'.
 *  In all other cases, this filter will return 'EXCEPTION_EXECUTE_HANDLER',
 *  so the exceptions will be processed as usual.
 *
 * Parameters:
 *
 *  pExp                pointer to structure describing the exception
 *
 * Return value:
 *
 *  EXCEPTION_CONTINUE_EXECUTION when one of the cases descibed above is
 *  detected, EXCEPTION_EXECUTE_HANDLER otherwise
 *
 */
LONG WINAPI __XceptFilter    (   EXCEPTION_POINTERS* pExp)
{
    LONG    lnRC    =   EXCEPTION_EXECUTE_HANDLER;
#ifdef _DEBUG
    char    acXcept[ 1024];

    sprintf (   acXcept,
                "__pxmXceptFilter(): got exception, code == 0x%x @ 0x%x, flags == 0x%x",    
                            pExp->ExceptionRecord->ExceptionCode,
                ( DWORD)    pExp->ExceptionRecord->ExceptionAddress,
                            pExp->ExceptionRecord->ExceptionFlags
            );
#endif

    if  (   EXCEPTION_ACCESS_VIOLATION  ==  pExp->ExceptionRecord->ExceptionCode)
        {
            if  (       0x77f6cb4e  ==  ( DWORD) pExp->ExceptionRecord->ExceptionAddress
                    ||  0x040200a5  ==  ( DWORD) pExp->ExceptionRecord->ExceptionAddress
                )
                {
#ifdef _DEBUG
                    strcat( acXcept, " => EXCEPTION_CONTINUE_EXECUTION");
                    TRACE1  (   "%s\n", acXcept);
                    AfxMessageBox( acXcept);
#endif
                    return( EXCEPTION_CONTINUE_EXECUTION);
                }

        }

#ifdef _DEBUG
    strcat( acXcept, " => EXCEPTION_EXECUTE_HANDLER");
    TRACE1  (   "%s\n", acXcept);
    AfxMessageBox( acXcept);
#endif

    return( lnRC);
}