GabbaGandalf
GabbaGandalf

Reputation: 119

Mysterious linux backtrace and memory map

While dealing with memory allocation, valgrind and gdb, i had to write a simple c program with an invalid free:

#include <stdlib.h>
#include <stdio.h>

int main (void)
{
    int* arr = (void*) malloc(100 * sizeof(int));
    arr[50] = 10;
    free(arr + (20 * sizeof(int)));
    printf("arr[50] = %d\n", arr[50]);
    return 0;
}

Which produces an error as desired:

*** Error in `./allocWithFunnyFree': free(): invalid pointer: ... ***
======= Backtrace: =========
...
======= Memory map: ========
...

Then i tried to get rid of the output by redirecting sdtout and stderr to /dev/null but noticed the output would still be printed which left me baffled.

I stoped the program an instruction before the free() call with a debugger, looked up the /proc/PID/fd dir and tried again redirecting all listed fd's to /dev/null but still same result..

I searched online for answers and asked some of my colleagues but nobody could explain to me how this output is printed and why it cannot be redirected.

For sure there still are many things i do not know about operating systems / linux but i hope you can help me understand what is going on here.
Thanks!

Upvotes: 4

Views: 579

Answers (1)

P.P
P.P

Reputation: 121407

The backtraces (in glibc) are printed to /dev/tty, which is going to be a different file descriptor (it's going to be 3 in your program) than 1 and 2 and your shell doesn't know about it.

Glibc provides an environment variable LIBC_FATAL_STDERR_ using which you can redirect it elsewhere. For example, you can redirect backtraces to stderr with:

$ export LIBC_FATAL_STDERR_=2
$ ./allocWithFunnyFre 2>free_backtrace

If you run your program under strace, you can understand it better (and how the backtraces are written).

Upvotes: 4

Related Questions