Daniel Lemire's blog

, 7 min read

Under Linux, libSegFault and addr2line are underrated

10 thoughts on “Under Linux, libSegFault and addr2line are underrated”

  1. Roberto Natella says:

    It seems that libSegFault was removed from the GNU C library (https://savannah.gnu.org/forum/forum.php?forum_id=10111). On Ubuntu, you can still get it by installing “glibc-tools”.

  2. Valerio Messina says:

    in your article it is not clear which compiler you use under Linux, but GCC since v4.8 from 2013/03, see

    https://gcc.gnu.org/gcc-4.8/changes.html

    (and CLang/LLVM since its first version) has implemented support for “address sanitizer”, which in addition to finding seg faults, finds double frees, uses after free, vector overruns, and much more at runtime.
    Just build in with:

    CFLAGS=-O1 -g -fsanitize=address
    LDFLAGS=-fsanitize=address

    and at the price of a binary enlargement and a slight execution slowdown, when the error occurs, it shows you a clear backtrace and the C source line where the error is generated, and where the memory was allocated. I always use it when build a debug binary

    1. You might find the following blog posts interesting:

      https://lemire.me/blog/2022/08/20/catching-sanitizer-errors-programmatically/

      https://lemire.me/blog/2016/04/20/no-more-leaks-with-sanitize-flags-in-gcc-and-clang/

      I love sanitizers and I think that they ought to be enabled by default when debugging.

  3. Valerio Messina says:

    yes, C built with ASAN is slow like Java or .Net languages.
    Once cleaned from bugs, rebuild without ASAN and you get all the power of C

  4. Atanas Palavrov says:

    For deeply embedded systems sometimes it is really valuable to get the stack back trace on error or for all running thread when there is a thread deadlock. The problem is that -fomit-frame-pointer makes function stack frames chaining unstable so you need to disable this optimization. But sometimes even that is not enough as for example for ARM Thumb2 GCC even with -fno-omit-frame-pointer still doesn’t generate predictable frames chaining to avoid generation of one additional instruction in the function prologue/epilogue. The only solution is to patch GCC or to switch to CLANG if your platform allows it.

    Not sure how this will work with address sanitizing.

  5. Maks Verver says:

    Note that you can also compile with -Og which is like -O1 except it prevents certain optimizations that make debugging harder.

    Similarly, GCC supports different levels of debug information, from -g0 (no debug information) to -g3, with -g equivalent to -g2. For maximum debugability the optimal flags are probably something like -Og -g3 , though beware this may slow down compilation and/or make your binaries larger.

  6. Marko says:

    One can also achieve this by linking against glog (Google logging library) and installing failure signal handler.

    When writing c or c++ programs I always link against glog, gflags, googletest and Google benchmark by default. These are statically linked and the whole program compiled with “-g -O2”. This is a pretty safe place to start from.

  7. azelcer says:

    Minor comment: The code in the post and in github do not coincide. Github’s code will indeed trigger a segfault on line 6, but the code in the post does not have an empty line before the definition of the go function and will trigger it in line 5.

  8. Valerio Messina says:

    the developer of ASAN suggest use “-O1 -g” with -fsanitize=address
    and optionally add -fno-omit-frame-pointer to get better stacktrace

  9. Michael Day says:

    Turning on optimizations resulted in addr2line giving me the incorrect line for me.