Skip to content
Search

Stack trace

lastmod 2026-09-02created 2015-10-1411 edits

A stack trace (also called stack backtrace or stack traceback) is a report of the stack frames at a certain point in time during the execution of a program. Memory is usually allocated dynamically in two places during program execution: the stack and the heap. As the name suggests, memory is allocated contiguously on the stack, but not on the heap. The stack is also regarded as a programming construct and is called the program's runtime stack. Technically, once a block of memory has been allocated on the stack, it cannot be easily removed, like the blocks allocated before it. Each time a function is called in a program, a block of memory called an activation record is allocated on top of the runtime stack. At a high level, an activation record allocates memory for the function's parameters and the local variables declared inside it.

Programmers commonly use stack traces in interactive post-mortem debugging. End users may see a stack trace as part of an on-screen error message and can then report it to the programmer.

A stack trace allows tracking the sequence of nested functions called up to the point where the stack trace is generated. In a post-mortem scenario, this extends up to the function where the failure occurred. Sibling function calls do not appear in a stack trace.

#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

Python gdb debugging

See Gdb#Python gdb debugging.

Libraries

See also

Favorite site

Simple project

Guide

author Zer0 sitemap