웹사이트 검색

GNU 디버거 또는 GDB: Linux 프로그램을 위한 강력한 소스 코드 디버깅 도구


디버거는 모든 소프트웨어 개발 시스템에서 중요한 역할을 합니다. 누구도 버그 없는 코드를 한꺼번에 작성할 수는 없습니다. 개발 과정에서 버그가 제기되고 있으며, 향후 개선을 위해 개선이 필요합니다. 디버거가 없으면 개발 시스템이 불완전합니다. 오픈 소스 개발자 커뮤니티를 고려하면 GNU Debugger가 최선의 선택입니다. 또한 UNIX 유형 플랫폼에서 상용 소프트웨어 개발에도 사용됩니다.

gdb라고도 알려진 GNU 디버거를 사용하면 코드가 실행되는 동안이나 프로그램이 충돌하기 직전에 무엇을 하려고 했는지 엿볼 수 있습니다. GDB는 기본적으로 소스 코드의 결함을 잡기 위해 네 가지 주요 작업을 수행하는 데 도움이 됩니다.

  1. 일반 동작에 영향을 미칠 수 있는 인수를 지정하여 프로그램을 시작합니다.
  2. 지정된 조건에서 프로그램을 중지합니다.
  3. 충돌이나 프로그램이 중지된 시기를 조사합니다.
  4. 코드를 변경하고 수정된 코드를 즉시 실험해 보세요.

우리는 큰 노력 없이도 gdb를 사용하여 C 및 C++로 작성된 프로그램을 디버깅할 수 있습니다. 현재 D, Modula-2, Fortran과 같은 다른 프로그래밍 언어에 대한 지원은 부분적입니다.

GNU 디버거 또는 GDB 시작하기

GDBgdb 명령을 사용하여 호출됩니다. gdb를 실행하면 플랫폼에 대한 일부 정보가 표시되고 아래와 같이 (gdb) 프롬프트로 이동합니다. .

[root@fedora20 ~]# gdb
샘플 출력
GNU gdb (GDB) Fedora 7.6.50.20130731-19.fc20 
Copyright (C) 2013 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law.  Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "x86_64-redhat-linux-gnu". 
Type "show configuration" for configuration details. 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>. 
Find the GDB manual and other documentation resources online at: 
<http://www.gnu.org/software/gdb/documentation/>. 
For help, type "help". 
Type "apropos word" to search for commands related to "word". 
(gdb)

gdb 내에서 사용할 수 있는 다양한 명령 클래스를 보려면 help 목록을 입력하세요. 해당 클래스의 명령 목록을 보려면 help 뒤에 클래스 이름을 입력하세요. 모든 명령 목록을 보려면 help all을 입력하세요. 명령 이름 약어는 명확할 경우 허용됩니다. 예를 들어 next 또는 cn을 입력할 수 있습니다. > 계속 등입니다.

가장 일반적으로 사용되는 GDB 명령

일반적으로 사용되는 gdb 명령은 다음 표에 나열되어 있습니다. 이 명령은 gdb 명령 프롬프트(gdb)에서 사용됩니다.

Command

설명

run

프로그램 실행 시작

quit

gdb 종료

print expr

expr 변수 이름일 수도 있는 표현식 인쇄

next

다음 줄로 이동

step

다음 줄로 이동

continue

현재 줄부터 프로그램 끝이나 다음 중단점까지 계속

두 명령 stepnext의 차이점에 유의하세요. 다음 줄이 함수 호출인 경우 next 명령은 함수 내부로 들어가지 않습니다. 반면 step 명령은 함수 내부로 들어가서 무슨 일이 일어나는지 확인할 수 있습니다.

GDB를 사용한 샘플 세션

다음 소스 코드를 고려하십시오.


// sum.c
#include <stdio.h> 

int sum (int a, int b) { 
	int c; 
	c = a + b; 
	return c; 
} 

int main() { 
	int x, y, z; 
	printf("\nEnter the first number: "); 
	scanf("%d", &x); 
	printf("Enter the second number: "); 
	scanf("%d", &y); 
	z = sum (x, y); 
	printf("The sum is %d\n\n", z); 
	return 0; 
}

출력 파일을 디버그하려면 다음과 같이 -g 옵션을 사용하여 gcc로 컴파일해야 합니다.

gcc -g sum.c -o sum

출력 파일 sum은 다음 두 가지 방법 중 하나를 통해 gdb에 첨부할 수 있습니다.

1. 출력 파일을 gdb에 대한 인수로 지정합니다.

gdb sum

2. file 명령을 사용하여 gdb 내에서 출력 파일을 실행합니다.

gdb
(gdb) file sum

list 명령은 소스 코드 파일의 행을 나열하고 포인터를 이동합니다. 따라서 첫 번째 목록 은 처음 10줄을 표시하고 다음 목록은 다음 10줄을 표시합니다.

(gdb) list
1	#include <stdio.h>   
2	 
3	int sum (int a, int b) { 
4		int c; 
5		c = a + b; 
6		return c; 
7	} 
8	 
9	int main() { 
10		int x, y, z;

실행을 시작하려면 run 명령을 실행하세요. 이제 프로그램이 정상적으로 실행됩니다. 하지만 디버깅을 위해 소스 코드에 중단점을 두는 것을 잊었습니다. 그렇죠? 이러한 중단점은 함수 또는 지정된 줄에 지정할 수 있습니다.

(gdb) b main

참고: break에 약어 b를 사용했습니다.

주 기능에서 중단점을 설정한 후 프로그램을 다시 실행하면 11번째 줄에서 중지됩니다. 이전에 줄 번호를 알고 있는 경우에도 동일한 효과를 얻을 수 있습니다.

(gdb) b sum.c:11

이제 next 또는 n 명령을 사용하여 코드 줄을 단계별로 살펴보세요. next 명령은 함수에 중단점이 설정되어 있지 않으면 함수 코드 안으로 들어가지 않는다는 점에 유의하는 것이 중요합니다. 이제 print 명령을 시험해 보겠습니다. 함수 sum에 중단점을 아래와 같이 설정합니다.

(gdb) b sum 
Breakpoint 1 at 0x4005aa: file sum.c, line 5. 
(gdb) r 
Starting program: /root/sum 

Enter the first number: 2 
Enter the second number: 3 

Breakpoint 1, sum (a=2, b=3) at sum.c:5 
5		c = a + b; 
(gdb) p a 
$1 = 2 
(gdb) p b 
$2 = 3
(gdb) c 
Continuing. 
The sum is 5 

[Inferior 1 (process 3444) exited normally]

실행 중인 프로그램에 명령줄 매개변수가 필요한 경우 run 명령과 함께 동일한 매개변수를 제공하세요.

(gdb) run   . . .

현재 실행 중인 프로그램과 관련된 공유 라이브러리 파일은 다음과 같이 나열될 수 있습니다.

(gdb) info share 
From                To                  Syms Read   Shared Object Library 
0x00000035a6000b10  0x00000035a6019c70  Yes         /lib64/ld-linux-x86-64.so.2 
0x00000035a641f560  0x00000035a6560bb4  Yes         /lib64/libc.so.6

변수 수정

GDB는 프로그램 실행 전반에 걸쳐 변수를 수정할 수도 있습니다. 이것을 시험해 봅시다. 위에서 언급한 대로 16번째 줄에 중단점을 설정하고 프로그램을 실행합니다.

(gdb) r 
Starting program: /root/sum 

Enter the first number: 1 
Enter the second number: 2 

Breakpoint 1, main ( ) at sum.c:16 
16		printf("The sum is %d\n\n", z); 
(gdb) set z=4 
(gdb) c 
Continuing. 
The sum is 4

이제 a=1, b=2이고 결과는 z=3이어야 합니다. 하지만 여기서는 주 함수에서 최종 결과를 z=4로 변경했습니다. 이런 방식으로 gdb를 사용하면 디버깅이 더 쉬워집니다.

중단점 활성화/비활성화

모든 중단점 목록을 얻으려면 info breakpoints를 입력하세요.

(gdb) info breakpoints 
Num     Type           Disp Enb Address            What 
1       breakpoint     keep y   0x00000000004005c2 in main at sum.c:11

여기에는 단 하나의 중단점이 있으며 이는 To입니다. 활성화 중단점 비활성화 비활성화 명령과 함께 중단점 번호를 지정합니다. 나중에 활성화하려면 enable 명령을 사용하세요.

(gdb) disable 1 
(gdb) info breakpoints 
Num     Type           Disp Enb Address            What 
1       breakpoint     keep n   0x00000000004005c2 in main at sum.c:11

삭제 명령을 사용하여 중단점을 삭제할 수도 있습니다.

실행 중인 프로세스 디버깅

GNU/Linux 시스템에서는 수많은 프로세스가 백그라운드에서 실행되고 있습니다. 실행 중인 프로세스를 디버깅하려면 먼저 해당 특정 프로세스의 프로세스 ID를 찾아야 합니다. pidof 명령은 프로세스의 pid를 제공합니다.

pidof <process_name>

이제 이 pid를 gdb에 연결해야 합니다. 두 가지 방법이 있습니다.

1. gdb와 함께 pid를 지정합니다.

gdb -p <pid>

2. gdb에서 attach 명령을 사용합니다.

(gdb) attach <pid>

지금은 여기까지입니다. 이는 소스 코드 디버깅을 시작하기 위한 gdb의 기본 사항일 뿐이며 위에서 설명한 것보다 훨씬 더 많은 내용을 담고 있습니다. 예를 들어 스택 정보, 환경 변수 등을 사용하여 디버깅할 수 있습니다. 이 모든 것들을 가지고 놀아보십시오…