在SIGABRT c ++信号之后继续运行程序

时间:2018-02-23 06:14:38

标签: c++ qt

我在我的c ++程序中使用第三个库,在某些情况下会发出template信号。我知道尝试释放非初始化指针或类似的东西可能是这个信号的原因。不过,我希望在发出此信号后继续运行我的程序,以显示消息并允许用户更改设置,以便处理此信号。
(我使用QT进行开发。)

我该怎么做?

4 个答案:

答案 0 :(得分:5)

  

我在我的c ++程序中使用第三个库,在某些情况下会发出SIGABRT信号

如果您拥有该库的源代码,则需要更正错误(错误可能在您的代码中)。

BTW,可能SIGABRT发生,因为abort(3)间接调用(可能是因为您违反了该库的某些约定或不变量,可能使用assert(3) - 并间接调用abort)。我想在caffe中,各种CHECK*宏可以间接调用abort。我让你去调查一下。

如果您没有源代码或没有足够的时间来修复该第三方库中的错误,您应该放弃使用该库并使用其他内容。

在许多情况下,您应该信任外部库而不是您自己的代码。可能是你滥用或滥用该库。仔细阅读其文档,并确保您自己的代码正确使用该库并尊重其不变量和约定。 该错误可能在您自己的代码中,在其他地方。

  

我想继续运行我的程序

这是不可能的(或非常不可靠,如此不合理)。我猜你的程序有一些undefined behavior非常 scared,并努力避免使用UB。

您需要提高调试技巧。更好地了解如何use the gdb debuggervalgrind,GCC消毒剂(例如-fsanitize=address-fsanitize=undefinedSIGABRT等等...

即使原则上你可能也不应该尝试处理SIGABRT(但请仔细阅读instrumentation optionssignal(7)并提示signal-safety(7)。我强烈建议您尽量避免尝试捕获$data = array( array("name" => "item1", "size" => "2 x 2", "thickness" => ".020", "price" => "$25"), array("name" => "item2", "size" => "2 x 2", "thickness" => ".025", "price" => "$28"), array("name" => "item6", "size" => "2 x 2", "thickness" => ".080", "price" => "$50"), array("name" => "item3", "size" => "2 x 2", "thickness" => ".030", "price" => "$30"), array("name" => "item4", "size" => "2 x 2", "thickness" => ".040", "price" => "$40"), array("name" => "item5", "size" => "3 x 2", "thickness" => ".050", "price" => "$43"), array("name" => "item6", "size" => "3 x 2", "thickness" => ".050", "price" => "$43"), array("name" => "item7", "size" => "3 x 2", "thickness" => ".050", "price" => "$43"), array("name" => "item8", "size" => "3 x 2", "thickness" => ".050", "price" => "$43"), array("name" => "item9", "size" => "4 x 2", "thickness" => ".050", "price" => "$43"), array("name" => "item10", "size" => "4 x 2", "thickness" => ".050", "price" => "$43"), array("name" => "item11", "size" => "4 x 2", "thickness" => ".050", "price" => "$43"), ); # Create storage array $transfer = []; # Loop $data foreach($data as $row) { # Make the size the key value $transfer[$row['size']][] = $row; } # Now just loop over the first array which is the grouping ?> <table> <?php foreach($transfer as $block => $rows): ?> <tr> <th>Name</th> <th>Size</th> <th>Thickness</th> <th>Price</th> </tr> <?php # Set the default rowspan as empty $rowspan = false; # This indicates an easy way to note that you need a new header row $start = true; # This will be set on each new thickness, but you want to reset it on # each size group as well. if(isset($thickness)) unset($thickness); # Loop each rows now foreach($rows as $row): if(!empty($start)) { # Assign rowspan $rowspan = count($rows); # This is the first row, so make sure the start is set false # for subsequent rows $start = false; } # Create the rowspan here for thickness $thickrowcount = $new = false; # If not set, set it (indicates first use of thickness) if(!isset($thickness)) { $thickness = $row['thickness']; $new = true; } # If it's already set and doesn't match, consider it's new if(($row['thickness'] != $thickness)) { $thickness = $row['thickness']; $new = true; } # Iterate the rows in this group and determine how many are this thickness. if($new) $thickrowcount = array_sum(array_map(function($v) use ($thickness){ return ($v['thickness'] == $thickness)? 1 : 0; },$rows)); ?> <tr> <td><?php echo $row['name'] ?></td> <?php if(!empty($rowspan)): ?> <td rowspan="<?php echo $rowspan; $rowspan = false; ?>"><?php echo $row['size'] ?></td> <?php endif ?> <?php if(!empty($thickrowcount)): # Write rowspan here ?> <td<?php if($thickrowcount > 1): ?> rowspan="<?php echo $thickrowcount ?>"<?php endif ?>><?php echo $row['thickness'] ?></td> <?php endif ?> <td><?php echo $row['price'] ?></td> </tr> <?php endforeach ?> <?php endforeach ?> </table>

答案 1 :(得分:3)

不幸的是,你不能。 SIGABRT信号本身就在abort()

之后发送

价: https://stackoverflow.com/a/3413215/9332965

答案 2 :(得分:0)

可以处理SIGABRT,但你可能不应该

&#34; can&#34;很简单 - 只需使用signal()以常规方式捕获它。你不想从这个信号处理程序返回 - 你可能从abort()来到这里 - 可能最初来自assert() - 该功能将在提升信号后退出。但是,你可以longjmp()回到你之前设置的状态。

&#34;不应该&#34;#34;是因为一旦SIGABRT被提出,你的数据结构(包括Qt和任何其他库的数据结构)可能处于不一致的状态,并且实际上使用你的任何程序的状态最多可能是不可预测的。除了立即退出之外,除了exec()更换计划以接管一个理智的初始状态之外,你做的事情并不多。

如果你只是想展示一个友好的消息,那么你或许可以exec()一个小程序来做那个(或者只是使用xmessage),但要注意退出这个以你成功的状态否则会有SIGABRT的指示。

答案 3 :(得分:-2)

遗憾的是,您无法阻止SIGABRT终止您的程序。并非没有修改一些希望由您编写的代码。

您可能需要更改代码以避免中止,或者您必须生成运行代码而不是当前进程的新进程。我不建议您使用子进程来解决此问题。这很可能是由于滥用api或计算机资源造成的,例如内存不足。