【问题标题】:Segmentation fault only when I redirect stdout to /dev/null?仅当我将标准输出重定向到 /dev/null 时出现分段错误?
【发布时间】:2009-10-11 05:39:13
【问题描述】:

我有一个 C++ 单元测试,它产生有用的输出到 stderr,主要是噪音(除非我正在调试)到标准输出,所以我想将标准输出重定向到 /dev/null。

奇怪的是,这样做似乎会导致分段错误。

是否有任何原因导致代码可能会出现 "> /dev/null" 段错误并运行正常?

输出完全由printfs 产生,如果有任何影响的话。

我很难发布有问题的代码,因为它是提交发表的研究。我希望根据这个描述有一个“明显”的可能原因。

验尸

段错误是由如下代码引起的:

ArrayElt* array = AllocateArrayOfSize(array_size);
int index = GetIndex(..) % array_size;
ArrayElt elt = array[index];

我已经无数次忘记了,当x 在 C/C++ 中为负数时,x % y 仍然是负数。

好的,那为什么只有在我重定向到/dev/null 时才会发生这种情况?我的猜测是,我正在访问的无效内存地址位于 stdout 的输出缓冲区中 - 并且在不需要时不会分配此缓冲区。

感谢您的精彩回答!

【问题讨论】:

  • 代码是多线程的吗?如果是这样,重定向标准输出可能会改变程序关键方面的时间并触发竞争条件错误。
  • 不是多线程的。如何在输出重定向的进程上启动 gdb? "gdb ./mybinary > /dev/null" 也会重定向 gdb 的标准输出。
  • 当任一操作数为负时,x % y 的符号是实现定义的,因此并不是说您不能可移植地依赖您所看到的行为。
  • @Tyler:如果您来自 LISP 领域或其他需要 (x mod y) 返回正数的地方,那么也许您应该为自己编写一个(模板?)函数来完成这项工作为您,并使用它来代替运营商?整数版本很简单;您可能需要为浮点数提供一种或多种特化。

标签: c++ redirect segmentation-fault stdout


【解决方案1】:

这并不能完全回答您的问题,但可以。您是否尝试过使用gdb?它是一个命令行调试工具,可以找到发生段错误的位置。它相当容易使用。 Here is a pretty in-depth tutorial on how to use it.

【讨论】:

  • 好主意 - 我以前用过一点。但是,当我运行“gdb ./my_binary > /dev/null”时,我也失去了 gdb 的接口 - 如何在我的进程上启动 gdb 并重定向其标准输出?
  • @Tyler:在命令行中检查运行在gdb:gdb ./my_binary 内的选项(如果有,请添加核心转储的名称),然后使用'运行程序运行 >/dev/null'。
【解决方案2】:

当标准输出重定向到 /dev/null 时,到 stdout 的 I/O 没有“正常”原因触发核心转储。

您很可能有一个杂散指针或缓冲区溢出,当发送到 /dev/null 而不是发送到标准输出时触发核心转储 - 但如果没有代码就很难发现问题。

将有用的信息放在标准输出上,把噪音放在标准错误上是很常规的。

【讨论】:

    【解决方案3】:

    可能是某些东西正在检查“isatty”,这可能会导致 /dev/null 出现不同的行为。

    可能是从标准输出读取某些东西,这对于/dev/null 会失败。

    【讨论】:

    • @Martin:如果 /dev/null 可以读取,那么您可以从中读取(但您没有得到任何信息 - 只是“EOF”)。如果有人希望从名义上只写的通道中读取(即代码正在从标准输出中读取),那么它就有严重的问题(但当标准输出是终端时,您通常可以侥幸逃脱)。跨度>
    猜你喜欢
    • 2012-08-15
    • 1970-01-01
    • 2017-11-29
    • 2021-03-17
    • 1970-01-01
    • 2020-02-10
    • 2021-03-30
    • 2017-05-13
    • 1970-01-01
    相关资源
    最近更新 更多