tags:

views:

629

answers:

10

Is there a way catch an exception like access violation and get information about on which line an exception occurred? This would be very good for debugging purposes, especially for testers..

My environment is Windows with VC++ on VS2008

+1  A: 

I'm not sure why testers would need to know which line an exception occurred.

The developers might want to know, though. But a better approach is the following:

  1. Include the information about class and method with each PROGRAM exception. These are exceptions that should NOT have happened.

  2. This should be output by whatever logs your exceptions. Your program does catch and log every exception, doesn't it? If not, it should.

  3. Make sure your methods are small enough that the above is enough information to easy track down a bug. If you need line information as well, then your methods are too large and your exceptions are not specific enough.

Larry Watanabe
A: 

That's really a compiler question.

If you want to know if it is possible for a compiler to provide, the answer is yes. I know multiple Ada compilers that provide tracebacks for unhandled exceptions, so it is clearly possible. This includes the gcc-based Gnat, so if the C++ compiler uses any of the same facilities for its exceptions, the support for doing that should already be there.

T.E.D.
+3  A: 

An access violation is not an exception in C++ terms, so the answer is in general "no". Concieveably, your specific implementation might have a feature that turns access violations into C++ exceptions - you need to specify what compiler & platform you are using.

anon
In Windows this would be a call to SetUnhandledExceptionFilter.
George Edison
@George Edison - Can you give some detailed info?
whoi
A: 

On unix type systems a Access violation generates a SEGV or BUS signal. This normally causes the application to core dump. You could always write your own signal handler. From there you could probably generate a stack-dump using the glibc before core dumping.

A core dump generally give you all this for wasy analysis in gdb.

doron
+1  A: 

In MSVC you can set the debugger to break when any exception or things like an access violation happen buy going to debug->Exceptions and checking the appropriate box.

Note that access violations are not C++ exceptions and will be handled differently on different systems. In Windows you can trap them with a structured exception handler. In unixy systems it will usually core dump. You can usually get a stacktrace from that.

Matt Price
+1  A: 

My answer refers to Windows only. You have quite a few options:

Without changing your code -

  • Avoid catching exceptions (at least ones you do not expect), and let your app just crash. Configure good ol' dr. watson (drwtsn32.exe) to create a crash dump, and open that dump in your debugger. You'll get the exact line of code there.
  • Use adPlus (from the windbg installation) to monitor your app's run, and create a dump when an exception is thrown.

From within your code, you can -

Finally, quite a lot of questions have been asked here on this issue. Look around, and you'll get additional answers.

eran
+1  A: 

In case you really want to log info about C++ exceptions (AV is not one) thrown from your code, you can use macros __FILE__ and __LINE__ within constructors of your exception types.

Nemanja Trifunovic
Just make sure you use those macros in the call to the constructor, rather than in the constructor body itself--otherwise you'll always get the same location--right there in the constructor body! :)
Drew Hall
LOL - a good point. I used to work with some THROW macros that would do that automatically for me.
Nemanja Trifunovic
@Nemanja Trifunovic - can you give min sample of __FILE__ __LINE__?
whoi
@whoi: untested. class my_exception : public std::exception { public: my_exception(const char* file, const char* line) { log(file, line); } }; ... throw my_exception(`__FILE__`, `__LINE__`);
Nemanja Trifunovic
A: 

For msdev / Windows, during development, always have your linker generate a MAP file. When Windows throws up an access violation, and it's your code (not library), you can use the address to match up function / data in the MAP file and get within a few lines of the offender. At a minimum, you'll know the function/method.

A: 

On one project I worked on, the root class of the exception hierarchy used captured a callstack in the constructor in case that information was needed later for debugging after the exception was caught. It was a decent idea, although if you're catching and 'handling' the exception, exactly when it was thrown shouldn't really matter all that much.

To put it another way, if you care about this info (context of "who" threw it), you probably shouldn't be using an exception to report this condition, or potentially you shouldn't be catching the exception in the first place. Uncaught exceptions cause crashes, giving you a crash dump at the point the exception was thrown.

Terry Mahaffey
A: 

If you catch the SEH exception using a __catch handler you can then access the thread context at the time of the exception and then use StackWalk64 to dump the call stack at the point where the exception was generated. Note that as I mentioned here: http://stackoverflow.com/questions/301892/printing-the-stack-trace-in-c-msvc/301984#301984 StackWalker by Jochen Kalmbach [MVP VC++] and available on codeproject is probably the easiest way to do this. It wraps up all of the details of dealing with the underlying StackWalk64 API.

Alternatively you could the same solution that I proposed here: http://stackoverflow.com/questions/1832809/how-to-catch-divide-by-zero-error-in-visual-studio-2008-c/1833378#1833378 to convert the Windows Structured Exceptions into C++ exceptions and capture the stack trace as shown above at the point where you translate the exception. This would give you a C++ exception with a stack trace like you get in C# or Java.

Len Holgate