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作为输出。如何为该特定错误代码添加陷阱?
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 可以(但很少这样做)意味着程序返回了此状态。
来自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。