gdb 사용법

By | 2022년 5월 24일
Table of Contents

gdb 사용법

Segmentation Fault 가 발생하면, 오류가 발생한 파일명과 위치를 알려준다.

참조1

참조2

전제조건

  1. 컴파일시 g 옵션을 포함해야 한다.

  2. 실행파일과 소스파일이 같은 폴더에 있어야 한다.

컴파일하기

#include <stdio.h>

int main() {
    printf("Hello, World!\n");
}
gcc -g -o main main.c

gdb 실행 및 종료

실행하기(gdb)

# gdb [프로그램명]
gdb main

이미 실행중인 프로그램을 디버깅할 수 있다.

# gdb [프로그램명] [프로세스PID]
gdb main 1928

# or

gdb main
(gdb) attach 1928

종료하기(quit / q)

3가지 방법이 있다.

ctrl + d
(gdb) q
(gdb) quit

소스보기(list / l)

(gdb) l(list)
(gdb) list 10
(gdb) list [함수명]
(gdb) list -  // 이전 10라인을 출력한다.
(gdb) list [파일명]:[함수명]
(gdb) list [파일명]:10

표시 라인수는 디폴트로 10개이다.
표시 라인수를 늘리려면 아래 명령을 수행한다.

(gdb) set listsize 20

프로그램 실행하기(run / r)

브래이크 포인트가 없기 때문에 실행 후 즉시 종료된다.

(gdb) r
Starting program: /home/skyer9/test/main
Hello, World!
[Inferior 1 (process 2941096) exited normally]
(gdb)

프로그램 종료하기(kill / k)

(gdb) k(kill)

브레이크 포인트(break / b)

브레이크 목록보기(info break / i b)

(gdb) info break

기본 사용법

(gdb) b(break) [함수명]
(gdb) break 10
(gdb) break [파일명]:[함수명]
(gdb) break [파일명]:10
(gdb) break +2             // 현재 행에서 2개 행 이후 브레이크포인트 설정
(gdb) break -2             // 현재 행에서 2개 행 이전 브레이크포인트 설정
(gdb) break *0x8049000     // 메모리주소에 설정(어셈블리로 디버깅시 이용)

예제

(gdb) l
1       #include <stdio.h>
2
3       int main() {
4           printf("Hello, World!\n");
5       }
(gdb) b 4
Breakpoint 1 at 0x555555555151: file main.c, line 4.
(gdb) r
Starting program: /home/skyer9/test/main

Breakpoint 1, main () at main.c:4
4           printf("Hello, World!\n");

조건부 브레이크

특정 조건에서 브레이크가 발동하도록 할 수 있다.

(gdb) break 10 if var == 0  // var 변수의 값이 0일때 10번 행에 설정

이미 프로그램이 실행중인 상태에서 브레이크 포인트를 변경할 수 있다.

(gdb) condition [N] var == 0       // var변수가 0일때 N번 브레이크포인트 동작
(gdb) condition [N] func(i) > 5

예제 코드를 아래 내용으로 변경한다.

// gcc -g -o main main.c
#include <stdio.h>

int main() {
    for (int i = 0; i < 10; i++) {
        printf("Hello, World! %d\n", i);
    }
}

예제

(gdb) l
1       #include <stdio.h>
2
3       int main() {
4           for (int i = 0; i < 10; i++) {
5               printf("Hello, World! %d\n", i);
6           }
7       }
(gdb) b 5 if i == 5
Breakpoint 1 at 0x115e: file main.c, line 5.
(gdb) r
Starting program: /home/skyer9/work/hackrf/sniffingd/test/main
Hello, World! 0
Hello, World! 1
Hello, World! 2
Hello, World! 3
Hello, World! 4

Breakpoint 1, main () at main.c:5
5               printf("Hello, World! %d\n", i);

for 문과 같이 브레이크를 걸 수 없는 라인도 있다.

변수 조회 / 브레이크 진행

(gdb) whatis [변수명]
(gdb) print [변수명]               // 변수에 저장된 현재 값을 한번 출력
(gdb) display [변수명]             // 변수에 저장된 현재 값을 지속적으로 출력

(gdb) next(or n)                  // 현재 행 수행 후 정지, 함수 호출시 함수 수행 다음 행으로 넘어감
(gdb) next(or n) [횟수]           // next 를 횟수만큼 반복

(gdb) step(or s)                  // 함수를 만나면 함수안으로 들어가서 실행, 나머지는 next 와 동일

(gdb) c(continue)              // 다음 브레이크까지 계속 프로그램 실행

브레이크 삭제(delete / d) 또는 비활성화(disable / ensable)

(gdb) i b              // 브레이크번호 조회
(gdb) d [브레이크번호]
(gdb) d                // 모든 브레이크포인트 지움

(gdb) disable br       // 모든 브레이크포인트 비활성화
(gdb) disable br 1 3   // 1번, 3번 브레이크포인트 비활성화
(gdb) ensable br       // 모든 브레이크포인트 활성화
(gdb) ensable br 1 3   // 1번, 3번 브레이크포인트 활성화

delete 는 특정 브레이크번호 또는 전체를 삭제하고,
clear 는 특정 함수의 브레이크 전체를 삭제할 수 있다.

(gdb) cl(clear) [함수명]
(gdb) clear 10
(gdb) clear [파일명]:[함수명]
(gdb) clear [파일명]:10

layout 변경

아래 명령으로 소스코드 표시창을 추가할 수 있다.

(gdb) layout src

포커스가 소스창에 있는 경우,
상하 커서가 소스코드 이동으로 작동한다.
이전 명령을 찾고자 한다면 포커스를 명령창으로 이동해 준다.

(gdb) info win
        SRC     (36 lines)  <has focus>
        CMD     (18 lines)
(gdb) fs next
Focus set to CMD window.
(gdb) info win
        SRC     (36 lines)
        CMD     (18 lines)  <has focus>
(gdb) fs SRC
Focus set to SRC window.
(gdb)

답글 남기기