捕获gcc / glibc致命错误

时间:2015-09-04 12:38:03

标签: io

我有一个偶然抛出致命错误的二进制文件。我无权访问源代码,但它可能类似于编译为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!

如何规避这一点(因为我无法修改二进制文件)我仍然不知道。

0 个答案:

没有答案