bombela / backward-cpp

A beautiful stack trace pretty printer for C++
MIT License
3.66k stars 466 forks source link

Pass MSVC exception through SetUnhandledExceptionFilter #336

Open nanoant opened 2 months ago

nanoant commented 2 months ago

This restores ability to chain std::set_terminate handlers on Windows by passing MSVC C++ runtime exceptions using their 0xE06D7363 system code back to original handler that will later call backward-cpp's terminator.

Without this other std::set_terminate handlers were blocked when using backward-cpp.

Accompanying example below. Running test.exe ex shows that custom termination handler is now effective and rethrowing prints proper stack trace.

#include <cstring>
#include <stdexcept>
#include "backward.hpp"

backward::SignalHandling sh;

void crash(const char* mode) {
  if (!std::strcmp(mode, "ex")) {
    throw std::runtime_error("std exception test");
  }
  if (!std::strcmp(mode, "strex")) {
    throw "string exception test";
  }
  int* n = nullptr;
  *n = 1;
}

void pass2(const char* mode) { crash(mode); }

void pass1(const char* mode) { pass2(mode); }

int main(int argc, char const *argv[]) {
  std::set_terminate([]() {
    const std::exception_ptr ex = std::current_exception();
    try {
        std::rethrow_exception(ex);
    } catch (std::exception ex) {
        std::cerr << "Uncaught exception: " << ex.what() << std::endl;
    }
  });
  const char* mode = argc == 2 ? argv[1] : "crash";
  std::cerr << "mode: " << mode << std::endl;
  pass1(mode);
}