본문 바로가기
컴퓨터 관련/Linux || Unix

리눅스(Linux) gdb로 디버깅해보자 [1] - 시작 및 종료, 소스 출력

by _BlankSpace 2019. 7. 14.

요즘 같이 다양한 IDE가 나오면서, 리눅스에서 기본으로 사용할 수 있는 GDB를 사용하는 사람이 그리 많지는 않으리라 생각합니다.

 

하지만, 임베디드 개발자나 일부 서버 관련 작업을 하는 사람들은 여전히 VIM 및 GDB를 사용하는 사람들이 있습니다. 왜냐하면, 가볍기도 하고, GUI를 확인할 수 없는 작업에서는 결국 gdb를 이용한 디버깅이 최선이기 떄문입니다.

 

저 역시도 아직 사용하고 있습니다.. 아무래도 저의 개발 컴퓨터에서는 여러 창들을 킨 상태에서 Visual Studio Code를 사용하여 디버깅을 하려고 하니, 너무 버벅거려서 gdb를 사용하고 있습니다.

 

아무튼, gdb를 사용하는 것이 귀찮을 수는 있겠지만, 일단 배워놓으면 좋지 않을 것은 없다고 생각합니다. 그래서 이번 기회에 gdb 내용 관련해서 정리를 해보려 합니다.

 

정리하려는 포스팅 내용은 gdb 입문자에게 추천합니다. 또한, 문법을 잠시 잊어버리신 분도 참고 정도 하시면 좋을  것 같습니다.

 

 

먼저, 설명에 들어가기 앞서서 gdb로 디버깅을 하기 위한 프로그램 예제를 올릴려고 했으나, 이번 포스팅에서는 예제를 많이 사용하지 않을 것 같아서 간단하게나마 올렸습니다.

 

#include <stdio.h>

int main(void) {
	int a = 0, b = 2;
    printf("a + b = ", a, b);
	return 0;
}

 

gdb란?

이 포스팅을 검색하여 들어오신 분이라면 gdb가 무엇인 지는 어느정도 아실 것입니다.

혹시나, 모르시는 분을 위해서 간단하게 설명 드리자면, 프로그램을 만들 때에 원인 모를 문제로 제대로 동작하지 않는 경우가 있습니다.

이러한 경우에 보통 printf와 같은 함수로 라인 별로 출력하셨을거에요. 이것도 디버깅의 한 방법이라고 생각하시면 되겠습니다.

 

간단한 구구단 프로그램 정도면 printf와 같은 방법으로 한 줄씩 출력해도 큰 문제는 없었을 것입니다. 하지만, 10000 줄, 아니 2000줄만 되도 printf로 일일히 찍으면서 찾기가 쉬울까요? 물론, 찾을 수는 있더라도, 시간이 오래걸릴 것입니다.

 

이러한 문제를 해결하기 위해서 디버깅을 위한 툴이 있는데, 그 중 하나가 gdb 입니다. 대충, gdb가 무엇인지에 대한 느낌은 오셨을 것으로 생각하기 때문에 이제 gdb를 하기 위한 컴파일 방법을 설명하도록 하겠습니다.

 

gdb를 하기 위한 컴파일 방법

일반적으로 리눅스에서는 c 또는 c++ 프로그램을 컴파일 하기 위해, 터미널창에서 아래와 같은 명령어를 입력합니다.

gcc test.c // c언어 컴파일 방법.
g++ test.c // c++언어 컴파일 방법.

 

위와 같은 명령어는 프로그램 소스로 실행파일을 만드는 명령어라고 할 수 있습니다. 따라서, gdb로 돌릴 수 있는 파일이 아닙니다.

 

gdb로 돌리기 위해서는 위의 명령어에서 -g 옵션을 추가해야 합니다.

gcc -g test.c // c언어 컴파일 방법.
g++ -g test.c // c++언어 컴파일 방법.

 

위에 명령어가 성공하면 실행파일이 생성됩니다. 이제 이 실행파일로 gdb를 이용하여 디버깅을 해보도록 하겠습니다.

 

 

gdb 시작 및 종료 방법

이제 gdb를 실행해봐야겠죠? 실행 방법은 간단합니다. (실행파일의 이름은 test 라고 가정하겠습니다.)

실행 방법은 어떤 방식의 gdb를 실행할 것인 지에 따라 달라집니다.

 

실행 방법

1. gdb [프로그램명] // 일반적인 gdb 실행 방법.
2. gdb [프로그램명] [core 파일명] // core 덤프를 이용한 gdb 실행 방법.
3. gdb [프로그램명] [실행 중인 프로세스 PID] // 프로세스 PID를 이용한 gdb 실행 방법.

위에 명령어 처럼 3가지로 크게 나눌 수 있는 데, 우리는 가장 기본적인 첫 번째 방법으로 gdb 디버깅을 하겠습니다.

나머지 방법은 추후에 정리하도록 하겠습니다.

 

명령어를 터미널창에서 실행하면, 아래와 같은 화면이 나올 것입니다.

 

 

위와 같은 내용이 출력되었다면, gdb가 정상적으로 시작되었다는 뜻입니다. 이제, gdb를 실행해봤으니, 종료하는 방법도 알아야겠죠?

 

종료 방법

아래처럼 두 가지 방법으로 종료할 수 있습니다. 보통 q 를 입력하여 gdb를 종료합니다.

1. (gdb) q
2. ctrl + d

 

프로그램 소스 코드 보기

gdb를 막상 실행했는데, 별 다른 것은 볼 수 없고, 이상한 영어만 가득해서 당황하셨을 것입니다.

이제, gdb의 명령어를 하나씩 익혀가야 할 것입니다.

 

그 중, 가장 먼저 볼 것은 gdb에서 프로그램의 소스코드를 보는 방법 입니다.

먼저, 명령어는 아래처럼 정리할 수 있습니다.

명령어

설명

l

main 함수를 기준으로 소스를 출력함.

l 20

20행을 기준으로 소스를 출력함.

l func

func 함수의 소스를 출력함.

l -

출력된 행의 이전 행을 출력함.

l test.c:func

test.c 파일의 func 함수 소스를 출력함,

l test.c:20

test.c의 20행을 기준으로 출력함.

이 중, l test.c:func 나 l test.c:20 명령어 같은 경우에는 gdb를 실행해야 사용할 수 있습니다. 이 점 참고해주세요.

간단한 사용 방법은 아래 내용을 참고해주세요.

 

아래 예제는 위에서 올린 예제와 다른 코드이므로, 이런 식으로 출력된다라고 참고하시면 좋을 것 같습니다.

 

(gdb) l 20
15	    printf("Age = %d\n", s->age);
16	    printf("score = %d\n", s->score);
17	}
18	
19	char getStudentGrade(int score) {
20	    if (score >= 90) return 'A';
21	    else if (score >= 80) return 'B';
22	    else if (score >= 70) return 'C';
23	    else if (score >= 60) return 'D';
24	    else return 'F';
(gdb) l main
22	    else if (score >= 70) return 'C';
23	    else if (score >= 60) return 'D';
24	    else return 'F';
25	}
26	
27	int main(void) {
28	    Student s[3] = {{"John", 15, 80}, {"Eric", 15, 65}, {"Chris", 15, 50}};
29	
30	    for (int i = 0; i < MAX_STUDENTS; i++) {
31	        printStudant(&s[i]);
(gdb) l -
12	int printStudant(Student* s) {
13	    printf("----- Student Status -----\n");
14	    printf("Name = %s\n", s->name);
15	    printf("Age = %d\n", s->age);
16	    printf("score = %d\n", s->score);
17	}
18	
19	char getStudentGrade(int score) {
20	    if (score >= 90) return 'A';
21	    else if (score >= 80) return 'B';

 

l 명령어의 한 가지 팁이 있다면, 보통 기본 디폴트 출력 행이 10으로 설정되어 있을 것입니다. 이것은 아래 명령어로 늘리거나 줄일 수 있습니다.

set listsize 30

 

이쯤에서 gdb로 디버깅을 하기 위한 첫 번째 포스팅을 마치도록 하겠습니다. 사실 이번 포스팅에 브레이크 포인트까지 넣으려고 했으나, 너무 길어질 것 같아서 다음 포스팅으로 정리하는 것이 좋을 것 같다는 생각에 글을 줄였습니다.

 

계속해서 gdb 디버깅에 대한 포스팅 글을 읽어주시면 감사하겠습니다.

 

이상으로 포스팅을 마치겠습니다.

저의 글이 도움이 되셨다면, 공감 버튼 한번 씩 눌러주시면 감사하겠습니다! :)

댓글