스택 추적이 segfault 인 경우 Linux의 모든 프로그램에서 스택 추적을 인쇄 할 수 있습니까?


20

쉘에서 프로그램을 실행하면 segfaults입니다.

$ buggy_program
Segmentation fault

그러나 프로그램에 백 트레이스를 인쇄하도록하는 방법이 있습니까? 아마 다음과 같이 실행하십시오.

$ print_backtrace_if_segfault buggy_program
Segfault in main.c:35
(rest of the backtrace)

나는 또한 그 종류의 정보에 대해 strace 또는 ltrace를 사용하지 않을 것입니다.

답변:


25

더 좋은 방법이있을 수 있지만 이런 종류의 방법으로 자동화합니다.

다음을 넣습니다 ~/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
신호 처리기 솔루션에 대한 귀하의 링크가 종료되었습니다-이것이 답변이 다른 자원에 링크되어서는 안되는 이유입니다.
josch

1
당신은 대신 "실행하도록 GDB에게 말한다 -x"아마 의미 "-x 출구에 GDB에게 말한다"
josch

19

2 년 후 여기에 와서 죄송합니다. 다른 것을 찾는 동안 우연히 발견되었습니다. 완전성을 위해 이것을 추가합니다.

1) 허용 된 답변이 훌륭하다고 생각하지만 gdb가 필요합니다. 내가 익숙한 방법은 libSegFault.so를 사용합니다.

앱을 실행하면

LD_PRELOAD = ... 경로 ... / libSegFault.so myapp

역 추적,로드 된 라이브러리 등이있는 보고서를 얻을 수 있습니다.

2) 주소를 파일 이름 + 행 번호로 변환 catchsegv하는 addr2line데 사용할 래퍼 스크립트 도 사용할 수 있습니다.

코어 파일이나 gdb보다 훨씬 가벼운 솔루션입니다 (예 : 임베디드 시스템에 적합)


실제로 LD_PRELOAD=libSegFault.sodl 경로에 있으면 괜찮습니다.
Fernando Silveira

1
@FernandoSilveira 좋아. 이 방법으로 답을 쓰면 독자에게 그 경로가 무엇인지 확인해야 함을 암시합니다.
nhed

6

모두의 친구 GDB가 필요합니다

gdb <program> [core file]

코어 파일을로드하면 'backtrace'명령 (bt로 축약 될 수 있음)이 현재 호출 스택을 제공합니다. gdb 내부에서 프로그램을 실행하면 임의의 중단 점을 설정하고 메모리 내용 등을 검사 할 수 있습니다.


백 트레이스를 인쇄하고 종료하는 방법이 있습니까?
Neil

5

catchsegv

그것은 또 다른 대답으로 언급되었지만 (어쨌든 집중하지는 않았습니다). glibc 프로젝트와 함께 제공되는 편리한 도구입니다. 프로그램이 실제로 segfault 인 경우에만 역 추적 (및 기타 유용한 디버그 정보)을 제공합니다 .

좋은 글쓰기가 여기에 있습니다 .

적합하다고 생각되면 자신의 스크립트에 포함시킬 수 있습니다.


3

프로젝트로 우분투는 Apport를 사용 하여이 작업을 수행합니다. 그들이 어떻게했는지 볼 수 있습니다.

https://wiki.ubuntu.com/Apport


2
+1 : Apport는 내가 익숙하지 않은 유용한 메커니즘을 언급합니다./proc/sys/kernel/core_pattern
RobM

2

다음은 Kyle Brandt의 약간 변형 된 스크립트입니다. 다음과 같은 방식으로 개선되었습니다.

  • 스택 추적이 긴 경우 수동 상호 작용이 필요하지 않습니다
  • 일부 코어 덤프는 이름 패턴 코어와 함께 저장됩니다.이 설정을 준수하십시오.
  • gdb를 위해 명시 적 명령 파일이 필요하지 않습니다 (임시 파일이 생성됩니다)
  • 백그라운드 작업을 기다립니다

스크립트:

#!/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

1
이러한 간단한 명령 체인을 -ex대신 사용 합니다. gdb ... -ex 'set pagination off' -ex backtrace -ex quit
Josh Stone
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.