我在我的c ++程序中使用第三个库,在某些情况下会发出template
信号。我知道尝试释放非初始化指针或类似的东西可能是这个信号的原因。不过,我希望在发出此信号后继续运行我的程序,以显示消息并允许用户更改设置,以便处理此信号。
(我使用QT进行开发。)
我该怎么做?
答案 0 :(得分:5)
我在我的c ++程序中使用第三个库,在某些情况下会发出SIGABRT信号
如果您拥有该库的源代码,则需要更正错误(错误可能在您的代码中)。
BTW,可能SIGABRT
发生,因为abort(3)被间接调用(可能是因为您违反了该库的某些约定或不变量,可能使用assert(3) - 并间接调用abort
)。我想在caffe中,各种CHECK*
宏可以间接调用abort
。我让你去调查一下。
如果您没有源代码或没有足够的时间来修复该第三方库中的错误,您应该放弃使用该库并使用其他内容。
在许多情况下,您应该信任外部库而不是您自己的代码。可能是你滥用或滥用该库。仔细阅读其文档,并确保您自己的代码正确使用该库并尊重其不变量和约定。 该错误可能在您自己的代码中,在其他地方。
我想继续运行我的程序
这是不可能的(或非常不可靠,如此不合理)。我猜你的程序有一些undefined behavior。 非常 scared,并努力避免使用UB。
您需要提高调试技巧。更好地了解如何use the gdb
debugger,valgrind,GCC消毒剂(例如-fsanitize=address
,-fsanitize=undefined
,SIGABRT
等等...
即使原则上你可能也不应该尝试处理SIGABRT
(但请仔细阅读instrumentation options,signal(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()
之后发送答案 2 :(得分:0)
你可以处理SIGABRT
,但你可能不应该。
&#34; can&#34;很简单 - 只需使用signal()
以常规方式捕获它。你不想从这个信号处理程序返回 - 你可能从abort()
来到这里 - 可能最初来自assert()
- 该功能将在提升信号后退出。但是,你可以longjmp()
回到你之前设置的状态。
&#34;不应该&#34;#34;是因为一旦SIGABRT
被提出,你的数据结构(包括Qt和任何其他库的数据结构)可能处于不一致的状态,并且实际上使用你的任何程序的状态最多可能是不可预测的。除了立即退出之外,除了exec()
更换计划以接管一个理智的初始状态之外,你做的事情并不多。
如果你只是想展示一个友好的消息,那么你或许可以exec()
一个小程序来做那个(或者只是使用xmessage
),但要注意退出这个以你成功的状态否则会有SIGABRT
的指示。
答案 3 :(得分:-2)
遗憾的是,您无法阻止SIGABRT终止您的程序。并非没有修改一些希望由您编写的代码。
您可能需要更改代码以避免中止,或者您必须生成运行代码而不是当前进程的新进程。我不建议您使用子进程来解决此问题。这很可能是由于滥用api或计算机资源造成的,例如内存不足。