如何识别导致程序段错误的输入?

如何识别导致程序段错误的输入?

我有一些运行程序的脚本(不是我编写的),有些脚本在一些输入上出现了段错误。我批量执行这些操作,运行时间长达一周,我想知道哪些输入触发了问题。目前,我收到 Bash 的通知,说我的某个脚本出现了段错误。但问题不在于脚本,而在于第三方程序及其输入。如果我有输入的名称,我就可以解决这个问题。

我的 Bash 脚本中调用的当前形式是(例如程序“autofix”)

  for indata in base*.fix; do        
      autofix $indata >${indata/.fix/.stdout} &                                                                                               
  done

如您所见,它们是在后台启动的,在我的主力服务器上,一次启动的可能多达 100 个左右,所以我无法判断哪一个失败了,而且我没有足够的耐心一次尝试所有 100 个,因为每个可能都要花一个小时。捕获 stderr 不会捕获任何内容,所以我正在寻找其他想法。

答案1

我找到了一个内联解决方案,只需尝试一下我在 Bash 中已经知道的东西(或者至少习惯遇到的东西)。为了测试和说明,我使用了一个我编写的只会导致 SEGFAULT 的小型 C 程序:

// Cause a seg fault

#include <stdlib.h>
#include <stdio.h>

int main() {
    char *zero = 0;
    *zero = 0;
    printf("Hey, how did I get away with this?");
    exit(EXIT_SUCCESS);
}

然后经过一些尝试(见下面的评论)我最终在 Bash 中得到了这个简单的模式(它可能只有一行,但我提供了一种更易读的形式):

   if ./segfault
   then
      echo strange success
   else
      echo this died with return code $?
   fi

这不会因为 SEGFAULT 而死掉,而只是注意到了这一点。因此输出是“此进程死掉”,而不是“奇怪的成功”或整个进程故障。

如果需要,这种方法可以显示区分 SEGFAULT 和其他形式的进程故障的错误代码。

最后,在决定我需要更多信息之后,我想出了这种形式的解决方案(简化了一些细节):

// expecting input files with names beginning with "input".
// the names become prefixes for the output file names.
for input in input*; do
  dodgy-code ${input} >${input}-stdout 2>${input}-stderr ||
    echo Error in ${input} with code $?  >>error-list
done
// clean up empty report files
for report in *stderr ; do
  if [ -f $report && ! -s $report ] then 
    rm $report
  fi
done

// now there are stdout files for all inputs, stderr files for
// the ones that returned an error code and an "error-list" file
// listing the inputs that caused problems and the error code returned.

相关内容