如何在 bash 中捕获返回 139(分段错误)的程序?

Pit*_*kos 12 bash signals segmentation-fault trap

我有一个 bash 脚本来测试一些程序,其中一个程序返回,Segmentation fault所以我试图在我的脚本的头部添加一个陷阱:

trap "echo 'segfault occured!'" SIGSEGV
Run Code Online (Sandbox Code Playgroud)

然而这并没有起到任何作用。我用了

echo $?
Run Code Online (Sandbox Code Playgroud)

就在产生段错误的程序之后,我得到139作为输出。如何为该特定错误代码添加陷阱?

Gil*_*il' 8

trap "$instructions" SIGSEGV 在外壳本身中捕获分段错误。

如果在 下运行脚本set -e,则可以在EXIT(或0)上设置陷阱。它将在您的脚本终止时执行(无论是由于命令返回非零状态,还是通过显式调用exit或从脚本的末尾脱落)。要测试分段错误,请检查$?陷阱的入口。(请注意,这$?可能是 139,因为程序以状态 139 正常返回;如果您在 shell 中进行处理,这是可以避免的。)

set -e
trap 'case $? in
        139) echo "segfault occurred";;
      esac' EXIT
Run Code Online (Sandbox Code Playgroud)

在 bash 或 ksh 或 zsh 中,您不需要使用set -e在每个返回非零状态的命令之后执行陷阱,而是可以设置陷阱ERR。和以前一样,您需要检查$?陷阱的入口,139 可以(但很少这样做)意味着程序返回了此状态。


sr_*_*sr_ 6

来自man bash

   trap [-lp] [[arg] sigspec ...]
          The command arg is to  be  read  and  executed  when  the  shell
          receives  signal(s)  sigspec.
Run Code Online (Sandbox Code Playgroud)

当您的程序出现段错误时,您的 bash 只会SIGCHLD因为某个孩子退出(以任何方式)而得到一个。

但是,您可以$?在某些条件和陷阱中使用存储在 中的退出代码SIGCHLD

trap 'if [[ $? -eq 139 ]]; then echo "segfault !"; fi' CHLD
Run Code Online (Sandbox Code Playgroud)

请注意,set -bm如果在非交互式 bash(例如脚本)中使用它(它可能会做什么),则可能需要这样做。

编辑:另请参阅this (Gilles') answer on a similar issue using bashand trap