GDB-퀵 가이드
디버거는 다른 프로그램을 실행하는 프로그램으로, 사용자가 이러한 프로그램을 제어하고 문제가 발생할 때 변수를 검사 할 수 있습니다.
GNU 디버거라고도합니다. gdb, UNIX 시스템에서 C 및 C ++ 프로그램을 디버깅하는 데 가장 많이 사용되는 디버거입니다.
GNU 디버거는 다음에 대한 정보를 얻는 데 도움이됩니다.
코어 덤프가 발생한 경우 프로그램이 충돌 한 문이나 표현식은 무엇입니까?
함수를 실행하는 동안 오류가 발생하면 프로그램의 어떤 줄에 해당 함수에 대한 호출이 포함되며 매개 변수는 무엇입니까?
프로그램 실행 중 특정 지점에서 프로그램 변수의 값은 무엇입니까?
프로그램에서 특정 표현의 결과는 무엇입니까?
GDB는 어떻게 디버깅합니까?
GDB를 사용하면 특정 지점까지 프로그램을 실행 한 다음 해당 지점에서 특정 변수의 값을 중지하고 인쇄하거나 한 번에 한 줄씩 프로그램을 단계별로 실행하고 각 줄을 실행 한 후 각 변수의 값을 인쇄 할 수 있습니다.
GDB는 간단한 명령 줄 인터페이스를 사용합니다.
참고 사항
GDB는 메모리 누수 관련 버그를 찾는 데 도움이 될 수 있지만 메모리 누수를 감지하는 도구는 아닙니다.
GDB는 오류와 함께 컴파일되는 프로그램에는 사용할 수 없으며 이러한 오류를 수정하는 데 도움이되지 않습니다.
설치하기 전에 다음 명령을 실행하여 Unix 시스템에 gdb가 이미 설치되어 있는지 확인하십시오.
$gdb -help
GDB가 설치되어 있으면 GDB 내에서 사용 가능한 모든 옵션이 표시됩니다. GDB가 설치되지 않은 경우 새로 설치를 진행하십시오.
아래에 설명 된 간단한 단계에 따라 시스템에 GDB를 설치할 수 있습니다.
step 1: gdb 설치를위한 전제 조건이 있는지 확인하십시오.
ANSI 호환 C 컴파일러 (gcc 권장-gdb는 다른 컴파일러에서 생성 된 코드를 디버그 할 수 있음)
gdb를 빌드 할 파티션에 115MB의 디스크 여유 공간이 필요합니다.
gdb를 설치할 파티션에 20MB의 여유 디스크 공간이 필요합니다.
GNU의 압축 해제 프로그램, gzip
그만큼 make 유틸리티-GNU 버전은 문제없이 작동하는 것으로 알려져 있으며 다른 버전도 작동합니다.
step 2: 다음에서 gdb 소스 배포를 다운로드합니다. ftp.gnu.org/gnu/gdb. (우리는 사용했었다 gdb-6.6.tar.gz 이 지침을 참조하십시오.) 배포 파일을 빌드 디렉토리에 배치하십시오.
step 3:빌드 디렉토리에서 gdb-6.6.tar.gz의 압축을 풀고 아카이브에서 소스 파일을 추출하십시오. 파일 추출이 완료되면 작업 디렉토리를 빌드 디렉토리에 자동으로 생성 된 gdb-6.6 디렉토리로 변경합니다.
$ build> gzip -d gdb-6.6.tar.gz
$ build> tar xfv gdb-6.6.tar
$ build> cd gdb-6.6
step 4: 플랫폼의 소스 트리를 구성하려면 구성 스크립트를 실행하십시오.
$ gdb-6.6> .⁄configure
step 5: 다음을 사용하여 gdb를 빌드합니다. make 유용.
$ gdb-6.6> make
step 6: 루트로 로그인하고 다음 명령을 사용하여 gdb를 설치합니다.
$ gdb-6.6> make install
step 7: 필요한 경우 설치가 완료된 후 gdb 빌드 디렉토리와 아카이브 파일을 삭제하여 디스크 공간을 확보 할 수 있습니다.
$ gdb-6.6> cd ..
$ build> rm -r gdb-6.6
$ build> rm gdb-6.6.tar
이제 시스템에 gdb가 설치되었으며 사용할 준비가되었습니다.
ㅏ Debugging Symbol Table컴파일 된 바이너리 프로그램의 명령어를 해당 변수, 함수 또는 소스 코드의 행에 매핑합니다. 이 매핑은 다음과 같을 수 있습니다.
프로그램 명령 ⇒ 항목 이름, 항목 유형, 원본 파일, 정의 된 줄 번호.
기호 테이블은 프로그램에 포함되거나 별도의 파일로 저장 될 수 있습니다. 따라서 프로그램을 디버그하려는 경우 프로그램을 디버그하는 데 필요한 정보가있는 기호 테이블을 만들어야합니다.
심볼 테이블에 대해 다음과 같은 사실을 추론 할 수 있습니다.
기호 테이블은 프로그램의 특정 버전에 대해 작동합니다. 프로그램이 변경되면 새 테이블을 만들어야합니다.
디버그 빌드는 종종 소매 (디버그가 아닌) 빌드보다 크고 느립니다. 디버그 빌드에는 기호 테이블 및 기타 보조 정보가 포함됩니다.
직접 컴파일하지 않은 바이너리 프로그램을 디버깅하려면 작성자로부터 기호 테이블을 가져와야합니다.
GDB가 심볼 테이블에서 한 줄씩 모든 정보를 읽을 수 있도록하려면 조금 다르게 컴파일해야합니다. 일반적으로 우리는 프로그램을 다음과 같이 컴파일합니다.
gcc hello.cc -o hello
이를 수행하는 대신 아래와 같이 -g 플래그로 컴파일해야합니다.
gcc -g hello.cc -o hello
GDB는 많은 명령 목록을 제공하지만 다음 명령이 가장 자주 사용되는 명령입니다.
b main -프로그램 시작 부분에 중단 점을 둡니다.
b -현재 줄에 중단 점을 둡니다.
b N -라인 N에 중단 점을 둡니다.
b +N -현재 줄에서 중단 점 N 줄을 내려 놓습니다.
b fn -함수 "fn"의 시작 부분에 중단 점을 둡니다.
d N -중단 점 번호 N 삭제
info break -중단 점 나열
r -중단 점 또는 오류가 발생할 때까지 프로그램을 실행합니다.
c -다음 중단 점 또는 오류가 발생할 때까지 프로그램을 계속 실행합니다.
f -현재 기능이 끝날 때까지 실행
s -프로그램의 다음 줄을 실행합니다.
s N -프로그램의 다음 N 줄을 실행합니다.
n -s와 같지만 기능에 들어 가지 않습니다.
u N -현재 라인 앞에 N 라인이 나올 때까지 실행
p var -변수 "var"의 현재 값을 인쇄합니다.
bt -스택 추적을 인쇄합니다.
u -스택에서 한 단계 올라갑니다.
d -스택에서 한 단계 아래로 이동
q -gdb 종료
시작하기 : 시작 및 중지
gcc -g myprogram.c
디버깅 옵션 (-g)을 사용하여 myprogram.c를 컴파일합니다. 여전히 a.out을 얻지 만, 원시 메모리 위치가 아닌 GDB 내부에서 변수와 함수 이름을 사용할 수있는 디버깅 정보가 포함되어 있습니다 (재미 있지 않음).
gdb a.out
a.out 파일로 GDB를 열지 만 프로그램을 실행하지는 않습니다. 프롬프트 (gdb)가 표시됩니다. 모든 예제는이 프롬프트에서 가져온 것입니다.
r
r arg1 arg2
r <파일 1
이전에로드 된 "a.out"을 실행하는 세 가지 방법. 직접 실행 (r)하거나 인수를 전달 (r arg1 arg2)하거나 파일을 공급할 수 있습니다. 일반적으로 실행하기 전에 중단 점을 설정합니다.
help
h 중단 점
도움말 항목 (도움말)을 나열하거나 특정 항목에 대한 도움말을 얻습니다 (h 중단 점). GDB는 잘 문서화되어 있습니다.
q-GDB 종료
코드 단계별 실행
스테핑을 사용하면 프로그램의 경로를 추적하고 크래시되거나 잘못된 입력을 반환하는 코드에 집중할 수 있습니다.
l
내가 50
l 내 기능
현재 줄 (l), 특정 줄 (l 50) 또는 함수 (l myfunction)에 대한 10 줄의 소스 코드를 나열합니다.
다음
다음 줄까지 프로그램을 실행 한 다음 일시 중지합니다. 현재 줄이 함수이면 전체 함수를 실행 한 다음 일시 중지합니다.next 코드를 빠르게 살펴 보는 데 좋습니다.
단계
라인이 아닌 다음 명령어를 실행합니다. 현재 명령어가 변수를 설정하는 경우 다음과 같습니다.next. 함수 인 경우 함수로 점프하여 첫 번째 문을 실행 한 다음 일시 중지합니다.step 코드의 세부 사항을 살펴 보는 데 좋습니다.
끝
현재 기능 실행을 완료 한 다음 일시 중지 (탈출이라고도 함). 실수로 함수에 들어간 경우 유용합니다.
중단 점 또는 감시 점
중단 점은 디버깅에서 중요한 역할을합니다. 특정 지점에 도달하면 프로그램을 일시 중지 (중단)합니다. 변수를 검사 및 변경하고 실행을 재개 할 수 있습니다. 이는 일부 입력 실패가 발생하거나 입력을 테스트 할 때 유용합니다.
휴식 45
내 기능을 깰
- 45 행 또는 myfunction에 중단 점을 설정합니다. 중단 점에 도달하면 프로그램이 일시 중지됩니다.
시계 x == 3
조건이 변경 될 때 (x == 3이 변경 될 때) 프로그램을 일시 중지하는 감시 점을 설정합니다. 감시 점은 모든 함수 호출 에서 중단 할 필요없이 특정 입력 (myPtr! = NULL)에 적합 합니다 .
계속하다
중단 점 / 감시 점에 의해 일시 중지 된 후 실행을 다시 시작합니다. 프로그램은 다음 중단 점 / 감시 점에 도달 할 때까지 계속됩니다.
N 삭제
- 중단 점 N을 삭제합니다 (중단 점은 생성 될 때 번호가 매겨 짐).
변수 설정
런타임에 변수를보고 변경하는 것은 디버깅의 중요한 부분입니다. 함수에 잘못된 입력을 제공하거나 다른 테스트 케이스를 실행하여 문제의 근본 원인을 찾으십시오. 일반적으로 프로그램이 일시 중지 될 때 변수를 보거나 설정합니다.
x 인쇄
변수 x의 현재 값을 인쇄합니다. 원래 변수 이름을 사용할 수 있다는 것이 (-g) 플래그가 필요한 이유입니다. 정기적으로 컴파일 된 프로그램은이 정보를 제거합니다.
x = 3으로 설정
x = y로 설정
- x를 설정 값 (3) 또는 다른 변수 (y)로 설정합니다.
myfunction () 호출
myotherfunction (x) 호출
strlen (mystring) 호출
사용자 정의 또는 시스템 함수를 호출합니다. 이것은 매우 유용하지만 버그가있는 함수 호출에주의하십시오.
디스플레이 x
모든 단계 또는 일시 중지 후에 표시되는 변수 x의 값을 지속적으로 표시합니다. 특정 값을 지속적으로 확인하는 경우 유용합니다.
x 표시 해제
- display 명령으로 표시되는 변수의 상수 표시를 제거합니다.
역 추적 및 프레임 변경
스택은 현재 함수 호출 목록입니다. 프로그램에서 현재 위치를 보여줍니다. 프레임 등의 인수로 하나의 함수 호출의 세부 사항을 저장합니다.
bt
Backtraces또는 현재 프로그램에서 현재 위치를 표시하기 위해 현재 함수 스택을 인쇄합니다. main이 c ()를 호출하는 b ()를 호출하는 함수 a ()를 호출하면 역 추적은
c <= current location
b
a
main
up
하위
함수 스택에서 위 또는 아래로 다음 프레임으로 이동합니다. 당신이에 있다면c, 당신은 이동할 수 있습니다 b 또는 a 지역 변수를 조사합니다.
반환
- 현재 함수에서 반환합니다.
신호 처리
신호는 타이머 또는 오류와 같은 특정 이벤트 후에 발생하는 메시지입니다. GDB는 신호를 발견하면 일시 중지 할 수 있습니다. 대신 무시할 수 있습니다.
핸들 [신호명] [동작]
SIGUSR1 nostop 처리
SIGUSR1 noprint 처리
SIGUSR1 처리 무시
특정 신호 (SIGUSR1)가 발생하면 무시하도록 GDB에 지시합니다. 무시의 수준은 다양합니다.
다음 예제를 통해 프로그램 및 코어 덤프를 디버깅하는 절차를 이해하십시오.
디버깅 예 1
이 예제는 0으로 나누는 동안 발생한 예외로 인해 발생하는 오류를 캡처하는 방법을 보여줍니다.
디버깅 예 2
이 예제는 초기화되지 않은 메모리로 인해 코어를 덤프 할 수있는 프로그램을 보여줍니다.
두 프로그램 모두 C ++로 작성되었으며 서로 다른 이유로 코어 덤프를 생성합니다. 이 두 가지 예를 살펴본 후에는 코어 덤프를 생성하는 C 또는 C ++ 프로그램을 디버깅 할 수있는 위치에 있어야합니다.
이 자습서를 마친 후에는 GNU 디버거를 사용하여 C 또는 C ++ 프로그램을 디버깅하는 방법을 잘 이해해야합니다. 이제 다른 디버거의 기능은 GDB와 매우 유사하므로 매우 쉽게 배울 수 있습니다. 다른 디버거를 통해 해당 기능에 익숙해지는 것이 좋습니다.
시장에서 사용할 수있는 몇 가지 좋은 디버거가 있습니다.
DBX Debugger-이 디버거는 Sun Solaris와 함께 제공되며 dbx의 man 페이지, 즉 man dbx를 사용하여이 디버거에 대한 완전한 정보를 얻을 수 있습니다 .
DDD Debugger-이것은 dbx의 그래픽 버전이며 Linux에서 무료로 사용할 수 있습니다. 자세한 내용을 보려면 ddd의 man 페이지, 즉 man ddd를 사용하십시오 .
다음 링크에서 GNU Debugger에 대한 포괄적 인 세부 정보를 얻을 수 있습니다. Debugging with GDB