【问题标题】:G++ compiler: Segfault handlingG++ 编译器:段错误处理
【发布时间】:2011-07-27 11:42:28
【问题描述】:

我正在一个项目中调用一个触发段错误的函数。我解决了这个问题,但在此过程中我注意到以下问题。

当我的代码是格式时;

main(){
  ...
  std::cout << "Looking for segfault\n"; // this does not print
  buggyFunction(); // crashes in here
  ...
}

buggyFunction(){
  ...
  thing_that_causes_segfault;
  ...
}

“寻找段错误”行没有打印到 STD,并且程序在 buggyFunction 中崩溃。很好,但是当我在 buggyFunction(); 中添加一条 cout 行时;

main(){
  ...
  std::cout << "Looking for segfault\n"; // this now *does* print
  buggyFunction(); 
  ...
}

buggyFunction(){
  ...
  std::cout << "Now we're INSIDE buggy function\n"; // this prints too
  thing_that_causes_segfault;
  ...
}

在 buggy 函数中,两行都打印(然后崩溃)。

为什么我们会在输出中看到这种差异,这取决于添加了这个额外的输出调用?它与流的处理有关,还是与其他有关?我正在使用 g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3。

【问题讨论】:

    标签: c++ compiler-construction g++ stdout


    【解决方案1】:

    原因是cout 有一个缓冲区,它只会在缓冲区已满时传递给系统函数并写入控制台。您对cout 的第二次使用恰好溢出了缓冲区,因此它调用了操作系统并清空了缓冲区。如果要保证输出已经离开缓冲区,则必须使用std::flush。您可以使用std::endl 结束一行并刷新缓冲区。

    【讨论】:

    • 或者,您可以使用std::cerr,它是无缓冲的(大概是为了报错)。
    • 即使使用std::endl 而不是"\n" 仍然不能保证打印行,但是使用std::endl 打印行的几率要好得多。这仍然可能不起作用的两个原因:(1)很可能正在进行其他缓冲,以及(2)SEGFAULT 是对某种未定义行为的响应。对于未定义的行为,无法保证。
    • D'OH!!我以前有一个 endl(专门用于刷新流),但在调试的某个时候它被删除了,我忘了把它放回去 - 因为这个原因,我很少使用 \n。
    【解决方案2】:

    因为您的行可能不会立即打印出来,因为它已被缓存并且缓存未“刷新”。 std::endl 是换行符 + 刷新,因此强制立即打印输出:

    std::cout << "Looking for segfault" << std::endl;
    

    【讨论】:

      【解决方案3】:

      这与缓冲有关。您写入cout 的内容会附加到仅定期刷新的内部缓冲区。您可以通过将std::flush 写入流或将"\n" 替换为&lt;&lt; std::endl 来显式刷新缓冲区。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多