神秘的 linux 回溯和内存映射

Mysterious linux backtrace and memory map

在处理内存分配、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但我希望你能帮助我理解这里发生了什么。
谢谢!

回溯(在 glibc 中)are printed to /dev/tty,这将是一个与 1 和 2 不同的文件描述符(在您的程序中为 3),而您的 shell 不是了解一下。

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

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

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