神秘的Linux回溯和内存映射

4

在处理内存分配、valgrind和gdb时,我不得不编写一个带有无效释放的简单C程序:

#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;
}

这会产生所期望的错误:

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

我尝试通过将sdtoutstderr重定向到/dev/null来消除输出,但是发现仍然会打印输出,这让我感到困惑。

free()调用之前的指令处使用调试器停止程序,查找/proc/PID/fd目录,并尝试将所有列出的fd都重定向到/dev/null,但结果仍然相同。

我在网上搜索答案并询问了一些同事,但没有人能解释为什么会打印这个输出以及为什么无法将其重定向。

当然,关于操作系统/ Linux,我还有许多不知道的事情,但我希望你能帮助我理解这里发生了什么。
谢谢!

1个回答

4

在glibc中,回溯信息被打印到/dev/tty,这将是一个不同的文件描述符(在您的程序中将是3),而不是1和2,您的shell并不知道它。

Glibc提供了一个环境变量LIBC_FATAL_STDERR_,可以使用它将其重定向到其他地方。例如,您可以将回溯重定向到stderr:

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

如果你在strace下运行你的程序,你可以更好地理解它(以及如何编写回溯)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接