7

Is there a way to cause a throw in C++ to dump core at the throw site if the thrown exception would be handled by a certain catch block? I would like something similar to what happens with g++ when an exception reaches the top level.

For example, I would like something like this:

try {
  bar();
  try {
    foo();
  } catch(...) {
#  pragma dump_at_throw_site
  }
} catch(...) {
  std::cerr << "There was a problem" << std::endl;
}

This way, if any exception thrown from foo() or its callee's that reaches the call-site of foo() would cause a core dump at the throw site so one can see who threw the exception that made it to the to this level.

On the other hand, exceptions thrown by bar() would be handled normally.

Manish
  • 173
  • 2
  • 4
  • 1
    I think the usual method is to simply not catch it, and hope the compiler/environment does a dump for you. The info about the throw site is lost the _instant_ after the `throw` expression. – Mooing Duck Sep 05 '12 at 23:05
  • Right, that is why I want to tell the compiler to generate logic for a core dump so that the stack isn't unwound. This is possible because this is exactly what happens when there is *no* catch block all the way to the root of the call chain. However, there are outer catch blocks that will catch the exception in my case. I very specifically want to dump core at the throw site for foo() as in the example, and ignore exceptions from bar. I can live with a clang++ or g++ specific answer. – Manish Sep 05 '12 at 23:07
  • 1
    In that case, the _throw site_ has to generate the core dump, not the catchee. However, one option is to generate a core dump into some internal structure, save that information in an exception, and _then_ throw the exception. _Then_ the catchee can do something with that dump info. – Mooing Duck Sep 05 '12 at 23:10
  • possible duplicate of [How to programatically cause a core dump in C/C++](http://stackoverflow.com/questions/979141/how-to-programatically-cause-a-core-dump-in-c-c) – Matt K Sep 05 '12 at 23:12
  • It's not a duplicate, but one of the answers, the one about http://code.google.com/p/google-coredumper/ plus what Mooing Duck suggested, looks like an answer... – piokuc Sep 05 '12 at 23:16
  • Not a dup, I could just do assert(false) if I wanted a dump at the catch site. I want a dump at the throw site. – Manish Sep 05 '12 at 23:16
  • When executing a throw, there must be some logic to traverse the call stack and find the innermost catch block. This could involve some trickery on call, be left to throw alone, etc. There are many implementations (I think g++ uses the latter approach to make calls fast). In this case, there could be some kind of marker on the stack frame that says if you are going to unwind to here, dump core instead. The problem is I have no interest in hacking g++, clang++, or anything else to make this happen. So, is there already a mechanism in place to make the compiler generate this code? – Manish Sep 05 '12 at 23:20
  • Mooing Duck, if there weren't a possible 100k+ lines of code potentially reachable from foo() I'd be glad to use BOOST_THROW_EXCEPTION which does stuff the throw site into the exception. Alas, it isn't practical to find all potential throw sites in all the code and all the libraries. – Manish Sep 05 '12 at 23:24

1 Answers1

2

Yes,it can in Windows. I don't know Linux, suppose it can also.

We can register a Exception Handler function to response the throw before the catch Here is the code example:

#include <iostream>
#include "windows.h"
#define CALL_FIRST 1
LONG WINAPI
VectoredHandler(
    struct _EXCEPTION_POINTERS *ExceptionInfo
    )
{
    UNREFERENCED_PARAMETER(ExceptionInfo);
    std::cout <<"VectoredHandler"<<std::endl;
    return EXCEPTION_CONTINUE_SEARCH;
}
int main()
{
    PVOID handler;
    handler = AddVectoredExceptionHandler(CALL_FIRST,VectoredHandler);

    try {
        throw 1;
    }catch(...)
    {
        std::cout <<"catch (...)"<< std::endl;
    }

    RemoveVectoredExceptionHandler(handler);
    std::cout << "end of main"<<std::endl;
    return 0;
}

The outputs of code are:

VectoredHandler
catch (...)
end of main

So,you can dump core int the function VectoredHandler. The VectoredHandler is called after the debugger gets a first chance notification, but before the system begins unwinding the stack. And if your purpose is just to debug the problem issue, then you can rely on the debugger feature to handle the first chance exception, don't need dump the application.

For your information, you may need know What is a First Chance Exception? in windows to understand how windows dispatch the exception.

RolandXu
  • 3,566
  • 2
  • 17
  • 23