#include <vector>
#include <string>
struct stack_tracer {
stack_tracer(const char* f) {stacktrace().push_back(f);}
~stack_tracer() {stacktrace().pop_back();}
static const std::vector<const char*>& get_stack() {return stacktrace();}
protected:
stack_tracer(const stack_tracer& NOCOPY);
stack_tracer&operator=(const stack_tracer& NOCOPY);
static std::vector<const char*>& stacktrace() {
static std::vector<const char*> stack;
return stack;
}
};
#include <iostream>
#include <exception>
#include <stdexcept>
class stack_aware_exception : public std::runtime_error {
std::vector<const char*> stack;
public:
stack_aware_exception(const char* msg)
:std::runtime_error(msg),
stack(stack_tracer::get_stack())
{}
virtual ~stack_aware_exception() throw() {}
const std::vector<const char*>& get_stack() const {return stack;}
};
unsigned thing(unsigned i) {
stack_tracer trace(__PRETTY_FUNCTION__);
if (i==10)
throw stack_aware_exception("message!");
else if (i==0)
return i;
return thing(i-1);
}
int Foo() {
stack_tracer trace(__PRETTY_FUNCTION__);
return thing(7) + thing(0) + thing(17);
}
int main(int argc, char** argv) {
stack_tracer trace(__PRETTY_FUNCTION__);
try {
Foo();
} catch(const stack_aware_exception& exc) {
std::cout << exc.what() << '\n';
for(unsigned i=0; i<exc.get_stack().size(); ++i)
std::cout << exc.get_stack()[i] << '\n';
}
return 0;
}