Skip to content
This repository was archived by the owner on Jul 20, 2026. It is now read-only.
Omega493Public archive

Latest commit

 

History

4 Commits

Folders and files

Repository files navigation

Panic Handler

Caution

Repository has been permanently moved to its Codeberg alternative. This one here is for archive purposes. Please visit the given link instead.

Two small helper functions (wrapper around the write function) and a panic handler for both Linux and Windows. What the panic handler does is to print out the values in the 16 GPRs + the RIP register whenever a crash occurs. The print occurs to stderr, while an equivalent stdout function is present as well.

How to Use

Just drag and drop the include/panic_handler directory in your project, include include/panic_handler/panic_handler.hpp in your source file (ideally, the same file where your main() is located), add "include/panic_handler/panic_handler.cpp" in your CMakeLists.txt file and call it a day!

Your main() must be of the following way to reasonably use the provided functions:

// Other includes...

#include "include/panic_handler/panic_handler.hpp"

// ...

int main(int argc, char* argv[]) { // or int main()
  std::signal(SIGINT, [](const int signum_) {
    stderr_write("SIGINT (external interrupt) sent to program.");
    std::_Exit(signum_);
  });

  std::signal(SIGTERM, [](const int signum_) {
    stderr_write("SIGTERM (termination request) sent to program.");
    std::_Exit(signum_);
  });

#ifdef _WIN32
  LPTOP_LEVEL_EXCEPTION_FILTER prev_handler_{ SetUnhandledExceptionFilter(panic_handler) };
#elifdef __linux__ // ^^^ _WIN32 / __linux__ vvv
  struct sigaction signal_action_{};
  signal_action_.sa_sigaction = panic_handler;
  signal_action_.sa_flags = SA_SIGINFO;
  sigemptyset(&signal_action_.sa_mask);
  sigaction(SIGABRT, &signal_action_, nullptr);
  sigaction(SIGFPE, &signal_action_, nullptr);
  sigaction(SIGILL, &signal_action_, nullptr);
  sigaction(SIGSEGV, &signal_action_, nullptr);
#endif // ^^^ _WIN32 ^^^

  // ... Your own logic
}

As is evident, the panic handlers must be the first thing to be setup in main. You could also follow the main.cpp provided in this repo to know more.

Example - 1

An example is provided in the repo itself, via the src/main.cpp:

// ... in main()...
int* ptr{ nullptr };
*ptr = 2;

I deliberately dereference the null pointer for this example.

1. Windows

On Windows, the example will write to stderr something similar to:

Process ID: 26408
Exception at address 0x00007FF7E6E11037: EXCEPTION_ACCESS_VIOLATION - a thread attempted to read from an address it doesn't have access to.

Registers:
RAX: 0x0000000000000000  RCX: 0xFFFFFFFFFFFFFFFF
RDX: 0x0000000000000000  RBX: 0x000001E1E09AF2B0
RSP: 0x00000030412FFA70  RBP: 0x0000000000000000
RSI: 0x0000000000000000  RDI: 0x000001E1E09B6510
RIP: 0x00007FF7E6E11037
R8:  0x00000030412FF748  R9:  0x0000000000000000
R10: 0x0000000000000000  R11: 0x00000030412FFA60
R12: 0x0000000000000000  R13: 0x0000000000000000
R14: 0x0000000000000000  R15: 0x0000000000000000

2. Linux

On a Linux system, the example will write to stderr something similar to:

Process ID: 444
Exception at address 0x0000000000000000: SIGSEGV - segment violation.

Registers:
RAX: 0x0000000000000000  RCX: 0x0000779148C3E3B6
RDX: 0x0000000000000000  RBX: 0x0000000000000000
RSP: 0x00007FFF8839A640  RBP: 0x00007FFF8839A6F0
RSI: 0x00007FFF8839A4F0  RDI: 0x0000000000000008
RIP: 0x0000625730CEA178
R8:  0x0000000000000000  R9:  0x0000000000000000
R10: 0x0000000000000008  R11: 0x0000000000000246
R12: 0x0000000000000000  R13: 0x0000000000000001
R14: 0x000077914935E000  R15: 0x0000625730CECDA8

Example - 2

Now, let us do...

std::cout << 10 / 0;

1. Windows

On Windows, this writes something similar to stderr:

Process ID: 2728
Exception at address 0x00007FF62A451509: EXCEPTION_INT_DIVIDE_BY_ZERO - a thread attempted division by zero.

Registers:
RAX: 0x000000000000000A  RCX: 0x0000000000000000
RDX: 0x0000000000000000  RBX: 0x0000025F9222DB10
RSP: 0x00000074B6BCF990  RBP: 0x0000000000000000
RSI: 0x0000000000000000  RDI: 0x0000025F9222CDD0
RIP: 0x00007FF62A451509
R8:  0x7FFFFFFFFFFFFFFC  R9:  0x00000074B6BCF814
R10: 0x00000FFF3B0FCD80  R11: 0x00000074B6BCF950
R12: 0x0000000000000000  R13: 0x0000000000000000
R14: 0x0000000000000000  R15: 0x0000000000000000

2. Linux

On Linux, it writes the following to stderr:

Process ID: 526
Exception at address 0x000056C5D1CF628C: SIGFPE - floating point exception (erroneous arithmatic operation, maybe division by zero).

Registers:
RAX: 0x000000000000000A  RCX: 0x0000000000000000
RDX: 0x0000000000000000  RBX: 0x0000000000000000
RSP: 0x00007FFFD7FECEF0  RBP: 0x00007FFFD7FECFA0
RSI: 0x00007FFFD7FECDA0  RDI: 0x0000000000000008
RIP: 0x000056C5D1CF628C
R8:  0x0000000000000000  R9:  0x0000000000000000
R10: 0x0000000000000008  R11: 0x0000000000000246
R12: 0x00007FFFD7FED0D8  R13: 0x0000000000000001
R14: 0x00007946C68D4000  R15: 0x000056C5D1CF8DA8

Contributors

Languages