답변:
더 좋은 방법이있을 수 있지만 이런 종류의 방법으로 자동화합니다.
다음을 넣습니다 ~/backtrace
.
backtrace
quit
이것을 seg_wrapper.sh
경로의 디렉토리 에있는 스크립트에 넣으십시오 .
#!/bin/bash
ulimit -c unlimited
"$@"
if [[ $? -eq 139 ]]; then
gdb -q $1 core -x ~/backtrace
fi
이 ulimit
명령으로 코어가 덤프됩니다. "$@"
스크립트에 주어진 인수이므로 프로그램과 인수가 될 것입니다. $?
종료 상태를 유지합니다. 139는 segfault에 대한 내 컴퓨터의 기본 종료 상태 인 것 같습니다.
의 경우 gdb
, -q
조용한 (인트로 메시지 없음 )을 의미하고 주어진 파일에서 명령을 실행하도록 -x
지시 gdb
합니다.
그래서 그것을 사용하려면 다음과 같이하십시오.
seg_wrapper.sh ./mycommand and its arguments
이 작업을 수행하는 신호 처리기를 작성할 수도 있습니다 ( 이 링크 참조) .
2 년 후 여기에 와서 죄송합니다. 다른 것을 찾는 동안 우연히 발견되었습니다. 완전성을 위해 이것을 추가합니다.
1) 허용 된 답변이 훌륭하다고 생각하지만 gdb가 필요합니다. 내가 익숙한 방법은 libSegFault.so를 사용합니다.
앱을 실행하면
LD_PRELOAD = ... 경로 ... / libSegFault.so myapp
역 추적,로드 된 라이브러리 등이있는 보고서를 얻을 수 있습니다.
2) 주소를 파일 이름 + 행 번호로 변환 catchsegv
하는 addr2line
데 사용할 래퍼 스크립트 도 사용할 수 있습니다.
코어 파일이나 gdb보다 훨씬 가벼운 솔루션입니다 (예 : 임베디드 시스템에 적합)
LD_PRELOAD=libSegFault.so
dl 경로에 있으면 괜찮습니다.
프로젝트로 우분투는 Apport를 사용 하여이 작업을 수행합니다. 그들이 어떻게했는지 볼 수 있습니다.
/proc/sys/kernel/core_pattern
다음은 Kyle Brandt의 약간 변형 된 스크립트입니다. 다음과 같은 방식으로 개선되었습니다.
#!/bin/bash
gdbcommandfile=$(tempfile)
usepid=$(cat /proc/sys/kernel/core_uses_pid)
printf "set pagination off\nbacktrace\nquit\n" > $gdbcommandfile
ulimit -c unlimited
"$@"&
pid=$!
wait $!
if [[ $? -eq 139 ]]; then
if [[ $usepid == 1 ]]; then
gdb -q $1 core.$pid -x $gdbcommandfile
else
gdb -q $1 core -x $gdbcommandfile
fi
fi
rm $gdbcommandfile
-ex
대신 사용 합니다. gdb ... -ex 'set pagination off' -ex backtrace -ex quit