Question

I recently started working on an existing project written in C++ Builder. The application consists of a MainModule that loads lots of modules (DLLs). The MainModule itself is a DLL (there is a small loader (.exe) that starts the MainModule).

The MainModule should not crash if a problem appears in any of the loaded modules (DLLs). So, it is imperative that the exceptions will not leave the module(s). Therefore, in each DLL there is a global try/catch that traps all exceptions inside.

To make the code more compact, exceptions are used everywhere for

  • flow control
  • signaling things
  • error logging (when something wrong happens, the exception handler will output a message to the console)

The debugging is done based on the messages shown in the console and also printf lines are inserted in code to see if the program reaches a certain point in a function or not.

I wonder, how could I debug those DLLs?
The problem is that when an access violation happens in one of those plugins/DLLs, the global try/catch will catch the exception. It will never reach the main application/debugger.

Note: The code is reviewed. Therefore, it is also imperative to do as little changes as possible to the existing code!

Was it helpful?

Solution

I see two approaches to your issue:

  • Configure your debugger to break when an exception is thrown and not just on unhandled exceptions. This is the approach I usually choose, but it only works if exceptions are only used for exceptional events and not all the time. So it doesn't appear to fit your application very well.

    Some debuggers allow configuring this settings based on the exception type. So you can use this approach for exceptions that should never happen (e.g. access violations) while resorting to the second approach for exceptions that happen frequently in your code-base.

  • You could put a break-point into the global exception handler in the dll.

    Something along the lines of: if(IsDebuggerPresent())__debugbreak();

    Unfortunately part of the stack will already be unrolled by that point, removing a lot of information that'd be useful for debugging.

Though it's unlikely that you can do anything about that, an access violation is generally considered an unrecoverable exception (because it might result from/in memory corruption) and you should use a separate process that gets terminated to contain the fallout instead of letting a process continue in which such an error happened.

OTHER TIPS

'swallowing' a structured exception in general, is very dangerous. Are you only doing so with exceptions you have triggered yourself intentionally? I. E. If you swallow a segfault, that may subtly corrupt your process and make the problem nigh impossible to debug when it REALLY messes up later.

I would suggest isolating your sub modules in separate processes if possible

Licensed under: CC-BY-SA with attribution
scroll top