How to Automatically Generate a Stacktrace When My Program Crashes

How to automatically generate a stacktrace when my program crashes

For Linux and I believe Mac OS X, if you're using gcc, or any compiler that uses glibc, you can use the backtrace() functions in execinfo.h to print a stacktrace and exit gracefully when you get a segmentation fault. Documentation can be found in the libc manual.

Here's an example program that installs a SIGSEGV handler and prints a stacktrace to stderr when it segfaults. The baz() function here causes the segfault that triggers the handler:

#include <stdio.h>
#include <execinfo.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>


void handler(int sig) {
void *array[10];
size_t size;

// get void*'s for all entries on the stack
size = backtrace(array, 10);

// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, STDERR_FILENO);
exit(1);
}

void baz() {
int *foo = (int*)-1; // make a bad pointer
printf("%d\n", *foo); // causes segfault
}

void bar() { baz(); }
void foo() { bar(); }


int main(int argc, char **argv) {
signal(SIGSEGV, handler); // install our handler
foo(); // this will call foo, bar, and baz. baz segfaults.
}

Compiling with -g -rdynamic gets you symbol info in your output, which glibc can use to make a nice stacktrace:

$ gcc -g -rdynamic ./test.c -o test

Executing this gets you this output:

$ ./test
Error: signal 11:
./test(handler+0x19)[0x400911]
/lib64/tls/libc.so.6[0x3a9b92e380]
./test(baz+0x14)[0x400962]
./test(bar+0xe)[0x400983]
./test(foo+0xe)[0x400993]
./test(main+0x28)[0x4009bd]
/lib64/tls/libc.so.6(__libc_start_main+0xdb)[0x3a9b91c4bb]
./test[0x40086a]

This shows the load module, offset, and function that each frame in the stack came from. Here you can see the signal handler on top of the stack, and the libc functions before main in addition to main, foo, bar, and baz.

How to get the stacktrace of a DLL who crashes?

As said in comments, the best way to get the stack trace of a crashed process is to generate a dump file. To do it, you first need to edit the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps registry key. Here is an example to get a full dump of the Hello.exe application:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\Hello.exe]
"DumpCount"=dword:a
"DumpType"=dword:2

More informations about the available values can be found here. By default, the dump files will be store in %LOCALAPPDATA%\CrashDumps.

Then, you need to compile your application without any optimization option and you have to generate the .pdb file (with the /DEBUG option).

You can now run your program and get to dump file in the CrashDumps directory. To read it, you can use VisualStudio (but also other applications like WinDbg, for instance):

  1. Open the .dmp file with VisualStudio (you can drop the file into the opened solution)
  2. Add the .pdb file into the configuration of VisualStudio (Tools > Option > Debugging > Symbols)
  3. Click on "Run with native only"

You can now get the stack trace of all of your threads when the crash occurs but also read the value of the variables before your program stopped.

How to get a stack trace when C++ program crashes? (using msvc8/2005)

If you have a crash, you can get information about where the crash happened whether you have a debug or a release build. And you can see the call stack even if you are on a computer that does not have the source code.

To do this you need to use the PDB file that was built with your EXE. Put the PDB file inside the same directory as the EXE that crashed. Note: Even if you have the same source code, building twice and using the first EXE and the second PDB won't work. You need to use the exact PDB that was built with your EXE.

Then attach a debugger to the process that crashed. Example: windbg or VS.

Then simply checkout your call stack, while also having your threads window open. You will have to select the thread that crashed and check on the callstack for that thread. Each thread has a different call stack.

If you already have your VS debugger attached, it will automatically go to the source code that is causing the crash for you.

If the crash is happening inside a library you are using that you don't have the PDB for. There is nothing you can do.

How can I generate a C++23 stacktrace with GCC 12.1?

You need to link with -lstdc++_libbacktrace.

In order for this to work, gcc needs to have been configured with --enable-libstdcxx-backtrace.

How to create a program that crashes with a segfault, but without core dump

You could mess with signal.h

`

#include <signal.h>    

void sig_func(int sig)
{
exit(1);
}

int main (void)
{
signal(SIGSEGV, sig_func); // sets a new signal function for SIGSEGV
raise(SIGSEGV); // causes the signal function to be called

return 0;
}

`

in this example, it should exit with 1, printing nothing, change the sig_func to whatever you need.

By the way... With signal you're completely overwriting what happens when that signal is raised. If you got rid of the exit call the program would keep running, with whatever undefined behavior that constitutes.



Related Topics



Leave a reply



Submit