【问题标题】:core dumped message is not captured in STDERR核心转储消息未在 STDERR 中捕获
【发布时间】:2015-10-26 07:14:46
【问题描述】:

我曾经在 bash shell 中使用这一行调用我的程序,以捕获日志文件中的所有 stdout 和 stderr 消息

./a.out input.txt 2>&1 | tee log

日志文件没有显示错误,但是通过检查日志,很明显有问题,程序在执行过程中突然终止。

我也试过这些,但结果是一样的:

./a.out input.txt > log 2>&1

./a.out input.txt |& tee log

当我在没有任何重定向的情况下运行它时:

./a.out input.txt

我在终端窗口最后看到错误消息:

*** Error in `./a.out': free(): invalid pointer: 0x000000000169b268 ***
Aborted (core dumped)

那么,为什么我无法在日志中捕获“核心转储”消息?我该怎么做?

【问题讨论】:

  • 某些程序仅在连接到 tty(文本终端,您可以将其解释为交互式 shell)时将某些消息打印到 stderr。当 stderr 连接到管道时,这些消息可能会被抑制。
  • 我的猜测是,在重定向输出的程序崩溃后,您的 shell 正在打印“x 中的错误:free()”等消息。您可以尝试在子 shell 中运行该进程:$( ./a.out ) > log > 2>&1 - 我会尝试但手边没有 Linux 机器。
  • 我写了这个程序,不管它是否连接到tty,我都没有做任何特别的事情。这是我编写的一个简单程序,用于使用动态数组进行递归合并排序并删除它们。我在 ubuntu 中用 g++ 编译。
  • 你不需要做任何特别的事情;它可能是编译器。
  • 你可以用一个伪 tty 试试这个,看看你是否收到消息。

标签: c++ linux bash


【解决方案1】:

这里有2条错误信息:

*** Error in `./a.out': free(): invalid pointer: 0x000000000169b268 ***

这来自 glibc,并打印在当前 tty(如果存在)上。

如果你想把它打印到 stderr(无论 stderr 被重定向到哪里),你必须设置 LIBC_FATAL_STDERR_ 在启动程序之前。 例如在 bash 中做:

export LIBC_FATAL_STDERR_=1

另一条消息

Aborted (core dumped)

这来自启动您的程序的外壳程序,外壳程序检查wait() 的状态。 如果程序不是由 shell 运行的,或者例如由已终止的 shell 运行,您将无法捕获该消息。即使 shell 没有终止,该 shell 的 stderr 也不会重定向到您的日志文件。

你可以通过这样做来解决这个问题:

 { ./a.out input.txt ; } >log 2>&1

另见redirection of ./a.out is not capturing segmentation fault)

【讨论】:

  • 关于LIBC_FATAL_STDERR_的第一个建议是对的。我现在在日志中看到“***错误...”。但是,第二个建议不起作用。即使有括号,“Aborted”消息仍在终端窗口中,而不是在日志中。
  • 是的,显然你需要护腕,而不是括号(产生一个子shell)。虽然目前还不清楚为什么子外壳不起作用。
猜你喜欢
  • 2016-02-04
  • 1970-01-01
  • 2022-01-12
  • 2013-10-28
  • 1970-01-01
  • 1970-01-01
  • 2019-07-11
  • 1970-01-01
  • 2011-12-05
相关资源
最近更新 更多