我有一个偶然抛出致命错误的二进制文件。我无权访问源代码,但它可能类似于编译为C++
的以下test.a
代码:
#include <ctime>
int main() {
int *a = new int;
delete a;
time_t t=time(0);
if (t%2==0)
delete a;
return 0;
}
在大约50%的运行中,它会导致错误。重要的是,通过重定向stderr
:
$ ./test.a 2>/tmp/Error
*** Error in `./test.a': double free or corruption (fasttop): 0x00000000007de010 ***
Aborted (core dumped)
当我问及为什么会发生这种情况时,我收到了一个答案&#34; gcc
(可能glibc
)直接打开/dev/tty
来输出绕过IO重定向的致命错误&# 34。
但是,有一种方法可以从脚本中捕获此错误。因为它是随机发生的而不是所有时间,所以重试是有用的,例如:
while :; do
./test.a 2>/tmp/Error
ERROR="$(</tmp/Error)"
if [ -z "$ERROR" ]; then
echo "Smooth run!"
break
else
echo "Error occured. Retry!"
fi
done
这当然不起作用,在50%的情况下输出:
*** Error in `./test.a': double free or corruption (fasttop): 0x0000000000df3010 ***
./test.sh: line 10: 16788 Aborted (core dumped) ./test.a 2> /tmp/Error
Smooth run!
因此,我想知道,如果有办法捕获致命错误,然后重试运行bugged二进制文件(我主要寻找Linux解决方案)?
修改
如果直接从脚本调用二进制文件,则可以通过检查退出状态来实现所需的行为:
while :; do
./test.a
if (( $? == 0 )); then
echo "Smooth run!"
break
else
echo "Error occured. Retry!"
fi
done
当然,要使其正常工作,必须正确编写可调用的可执行文件。例如,在我的实际情况中,导致错误的二进制文件本身是从另一个二进制文件调用的。让我们将test2.a
视为编译以下代码的结果:
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
std::system("./test.a");
cout<<"Execution of test.a finished"<<endl;
return 0;
}
在这种情况下,./test2.a
的调用始终以状态0
退出,因为system()
调用期间的崩溃不会中断二进制文件的执行:
*** Error in `./test.a': double free or corruption (fasttop): 0x0000000002431010 ***
Aborted (core dumped)
Execution of test.a finished
Smooth run!
如何规避这一点(因为我无法修改二进制文件)我仍然不知道。