코어파일, gdb와gdbserver -...

8
들어가는 말 유닉스와 유사한 어떤 운영체제가 있을 때 여기에 배시 셸과 gcc를 이식하면 절반이 끝났다고 말한다. 하지만 디버깅을 위한 gdb까지 이식해야지만 정말로 절반이 끝났다고 볼 수 있다. 통합 IDE 환경이거나 vi-make-gcc(아니면 당신이 사용하는 GNU 컴 파일러)-gdb로 이어지는 순수한 개발 환경이던 상관없이, gdb는 소프트웨어 문제 해결 과정에서 도움을 주는 강력한 개발 도구이 므로 gdb의 사용법에 대해서는 확실하게 꿰뚫고 있어야 한다. 2회에서는 유닉스와 리눅스 세계에 들어오면 가장 먼저 의문 을 품게 되는 코어 파일 설명을 시작으로 gdb와 임베디드 환경 에서 대화식 디버거를 사용하도록 만드는 gdbserver를 소개하 며, 마지막으로 gdb 그림 사용자 인터페이스인 DDD와 Insight 를 소개하겠다. 가장 먼저 gdb의 이모저모에 대해 상위 단계에 서 살펴보기로 하자. gdb 이모저모 영문 위키피디아에서 gdb를 찾아보면 다음과 같은 짤막한 설 명을 볼 수 있다. 「GNU 디버거이며, 간략하게 줄여서 GDB라고 불리는 이 소 프트웨어는 GNU 소프트웨어 시스템을 위한 표준 디버거이다. GDB는 다양한 유닉스 계열 시스템에서 동작하며, C, C++, 포 트란을 비롯한 수많은 프로그래밍 언어를 디버깅하도록 도와주 는 이식성 높은 디버거이다.」 여기서‘이식성 높은’이라는 단어에 한 번 집중해보자. gdb 는알파, ARM, x86, x86-64, IA-64, 모토롤라68000, MIPS, PA-RISC, 파워PC, SuperH, Sparc과 같은 다양한 CPU에 이 식되어 있으며, gdb 컴파일러로 컴파일한 C, C++, 파스칼, Objective C, 자바, 포트란과 같은 다양한 프로그래밍 언어에 대한 디버깅을 지원하고 있다. 일반적인 유닉스 운영체제는 물 론이고 Cygwin에서 동작하도록 이식되어 있으므로 유닉스뿐 만 아니라 윈도우 환경에서도 사용할 수 있다. 코어(core) 파일이란? 처음 유닉스 계열 프로그램을 작성하는 도중에 누구나 한 번 씩은 코어 파일을 만들어본 경험이 있을 것이다. 코어는 과거 메 인 프레임 시절에 메모리를 구성하는 소자에서 따온 말이며, 코 어 파일은 응용 프로그램이 여러 가지 원인으로 인해 수행이 불 리눅스 개발자를 위한 디버깅 기법 ② 코어 파일, gdb와 gdbserver 76 TECHNICAL FEATURE ���� 대화식 디버거가 존재하지 않던 시절에는 콘솔 출력이나 UART 출력으로 필요한 값을 화면에 뿌려서 문제 위치를 파악하 방법을 주로 많이 사용했었다. 물론 요즘도 디버거를 사용할 수 없는 환경에서 여전히 이런 방법을 동원하기도 하지만, 생산성을 높이기 위해서는 대화식 디버거를 사용해야 한다. 대화식 디버거는 원시 코드를 보면서 프로그램을 추적하는 기 능을 제공하기에 시각적으로 다가갈 있기 때문이다. 대화식 디버거는 문제 해결뿐만 아니라 처음으로 분석하는 소프트웨어 내부를 탐험하는 과정에서도 상당한 도움을 준다. 실행 도중에 내부 상황을 모두 확인할 있기 때문이다. 이 연재 글에서는 x86 리눅스부터 시작해서 PowerPC 매킨토시 OS X에 이르기까지 다양한 플랫폼과 운영체제에서 실행되는 gdb를 소개하겠다. : 박재호 [email protected]

Upload: others

Post on 07-Sep-2019

2 views

Category:

Documents


0 download

TRANSCRIPT

들어가는 말

유닉스와 유사한 어떤 운 체제가 있을 때 여기에 배시 셸과

gcc를 이식하면 절반이 끝났다고 말한다. 하지만 디버깅을 위한

gdb까지 이식해야지만 정말로 절반이 끝났다고 볼 수 있다. 통합

IDE 환경이거나vi-make-gcc(아니면당신이사용하는GNU 컴

파일러)-gdb로 이어지는 순수한 개발 환경이던 상관없이, gdb는

소프트웨어 문제 해결 과정에서 도움을 주는 강력한 개발 도구이

므로gdb의사용법에 해서는확실하게꿰뚫고있어야한다.

2회에서는 유닉스와 리눅스 세계에 들어오면 가장 먼저 의문

을 품게 되는 코어 파일 설명을 시작으로 gdb와 임베디드 환경

에서 화식 디버거를 사용하도록 만드는 gdbserver를 소개하

며, 마지막으로gdb 그림사용자인터페이스인DDD와Insight

를 소개하겠다. 가장 먼저 gdb의 이모저모에 해 상위 단계에

서살펴보기로하자.

gdb 이모저모

문위키피디아에서gdb를찾아보면다음과같은짤막한설

명을볼수있다.

「GNU 디버거이며, 간략하게 줄여서 GDB라고 불리는 이 소

프트웨어는 GNU 소프트웨어 시스템을 위한 표준 디버거이다.

GDB는 다양한 유닉스 계열 시스템에서 동작하며, C, C++, 포

트란을 비롯한 수많은 프로그래밍 언어를 디버깅하도록 도와주

는이식성높은디버거이다.」

여기서‘이식성 높은’이라는 단어에 한 번 집중해보자. gdb

는알파, ARM, x86, x86-64, IA-64, 모토롤라68000, MIPS,

PA-RISC, 파워PC, SuperH, Sparc과 같은 다양한 CPU에 이

식되어 있으며, gdb 컴파일러로 컴파일한 C, C++, 파스칼,

Objective C, 자바, 포트란과 같은 다양한 프로그래밍 언어에

한 디버깅을 지원하고 있다. 일반적인 유닉스 운 체제는 물

론이고 Cygwin에서 동작하도록 이식되어 있으므로 유닉스뿐

만아니라윈도우환경에서도사용할수있다.

코어(core) 파일이란?

처음 유닉스 계열 프로그램을 작성하는 도중에 누구나 한 번

씩은코어파일을만들어본경험이있을것이다. 코어는과거메

인 프레임 시절에 메모리를 구성하는 소자에서 따온 말이며, 코

어 파일은 응용 프로그램이 여러 가지 원인으로 인해 수행이 불

리눅스개발자를위한디버깅기법②

코어파일, gdb와gdbserver

76

TTEECCHHNNIICCAALL FEATURE ����

화식 디버거가 존재하지 않던 시절에는 콘솔 출력이나 UART 출력으로 필요한 값을 화면에 뿌려서 문제 위치를 파악하

는 방법을 주로 많이 사용했었다. 물론 요즘도 디버거를 사용할 수 없는 환경에서 여전히 이런 방법을 동원하기도 하지만,

생산성을 높이기 위해서는 화식 디버거를 사용해야 한다. 화식 디버거는 원시 코드를 보면서 프로그램을 추적하는 기

능을 제공하기에 좀 더 시각적으로 다가갈 수 있기 때문이다. 화식 디버거는 문제 해결뿐만 아니라 처음으로 분석하는

소프트웨어 내부를 탐험하는 과정에서도 상당한 도움을 준다. 실행 도중에 내부 상황을 모두 확인할 수 있기 때문이다. 이

번 연재 에서는 x86 리눅스부터 시작해서 PowerPC 매킨토시 맥 OS X에 이르기까지 다양한 플랫폼과 운 체제에서

실행되는 gdb를 소개하겠다.

: 박재호

[email protected]

가능한 상황에 이를 경우 문제가 생긴 코어 내용을 그 로 덤프

한 파일이다. TLDP 문서(http://www.tldp.org/LDP/Linux-

Filesystem-Hierarchy/html/glossary.html) 정의에 따르면

코어파일은다음과같다.

「코어 파일은 버그나 기타 운 체제나 하드웨어 보호 매커니

즘을 위반하여 비정상적으로 프로그램이 종료할 때 만들어진

다. 운 체제는문제가발생한응용프로그램을죽이며, 코어파

일을 만들어 프로그래머가 무엇이 잘못되었는지를 판단하도록

도와준다. 코어 파일은 프로그램이 죽었을 시점에서 프로그램

상태가 어떤지를 세부적으로 기술하는 정보를 포함한다. 어떤

프로그램이 코어 파일을 만들었는지 알고 싶다면 file 명령어를

사용하면된다. 코어덤프를일으킨명령어를알아내면, 해당프

로그래머를 관리하는 사람에게 core를 제출하는 방법으로 문제

점을알려줄수있다.」

코어라는 이름이 주는 묘한 중요성 때문에 병아리 개발자들

은 코어 파일을 응용 프로그램이 수행하는 과정에 반드시 필요

한 핵심 파일로 착각하고 백업을 받아두기까지 한다. 심지어 개

발자 입장일 경우에도 착각이 일어나는 판국이니, 일반 사용자

입장에서는 코어 파일이 무척 성가신 존재인 셈이다. 따라서 일

반 리눅스 배포판은 코어 파일이 만들어지지 않도록 코어 크기

를0으로만들어놓았다.

하지만 개발 과정에서 디버깅을 위해 코어 파일이 반드시 필

요하므로 코어 파일 크기와 각종 환경 설정 작업이 필요하다.

http://www.novell.com/coolsolutions/feature/16257.html

를참조해서몇가지유용한사항을정리해보았다.

코어 파일 크기 확인과 조정: ulimit 명령을 사용해서 코어

파일크기를확인하고변경할수있다.

# ulimit -c -> 코어파일크기를확인한다

# ulimit -c 500000 -> 코어 파일 크기를 500000 바이

트로설정한다

# ulimit -c unlimited -> 코어 파일 크기를 무제한으로 설

정한다

코어 파일 이름 설정: /proc 파일 시스템을 활용해서 코어

파일뒤에프로세스식별자를붙일수있다.

# echo 1 > /proc/sys/kernel/core_uses_pid

또한/proc 파일시스템을활용해서이름패턴을정의할수도

있다. /proc/sys/kernel/core_pattern에%p(프로세스 식별자),

%u(덤프된 프로세스의 진짜 사용자 식별자), %g(덤프된 프로

세스의 진짜 그룹 식별자), %s(덤프를 초래한 신호 번호), %t

(ephoc 기준으로 덤프 시각), %h(호스트 이름), %e(실행 파일

이름)를넣으면코어파일이름을관리가편한방법 로바꿀수

있다. 예를들면다음과같이코어파일이름을실행파일이름-

프로세스식별자-덤프시각으로바꾼다.

77Embedded World

� 연재순서

리눅스 개발자를 위한 디버깅 기법

1회 리눅스 디버깅 개괄

2회 core 파일, gdb와 gdbserver

3회 커널 웁스, kdb와 kgdb

4회 내부를 들어다 보는 창인 /proc 파일 시스템 분석

5회 메모리 관리 디버깅 기법 소개

6회 소프트웨어 탐침: 동적 프로브 소개

컴퓨터와 책에 얽힌 재미있는 이야기를 다루는

‘컴퓨터 vs 책’이라는 블로그 (http://blog.ya

hoo.co.kr/jhrogue)를운 하고있으며, 회사에서는임베디드리

눅스를사용한제품개발에몰두하고있다. 최근임베디드리눅스

개발자를 위한필독서인 리눅스 디바이스드라이버 3판(한빛미디

어)과리눅스디버깅과성능튜닝: 오픈소스도구를사용한문제

진단분석과해결(에이콘)을번역했다.

필 / 자 / 소 / 개

박재호([email protected])

78

# echo core-%e-%p-%t > /proc/sys/kernel/core_pattern

코어 파일은 gdb와 같은 디버거에서 인식하기 때문에 응용

프로그램이 비정상적인 상황으로 종료됐을 때 디버깅 정보가

붙어있는 실행 파일인 경우 gdb에서 코어 파일을 읽기만 하면

문제가 발생한 정확한 지점과 스택 역추적 정보를 바로 확인할

수있다. 디버깅정보가붙어있지않은실행파일일경우에는아

쉽지만 소스코드가 아니라 역 어셈블 목록을 출력하므로 디버

깅정보를붙여서(예: gcc의-g 옵션) 다시한번컴파일한다음

에문제를재연해야한다.

gdb 활용하기

지금부터는간략하게기본적인gdb 활용방안을살펴보기로하

자. 앞서언급한바와같이gdb를사용하기전에반드시-g 옵션

을사용해서다음예와같이프로그램을컴파일해야한다. -g 옵

션을 붙이지 않으면 심볼릭 정보가 프로그램에 포함되지 않으므

로gdb를사용해서원시코드단계에서디버깅을할수없다.

$ gcc -g -o my_prog myprog.c

정지점 설정

지정한 지점(정지점)에서 프로그램 실행을 일시적으로 중단

하는 기능이다. 정지점에서 프로그램을 중단한 다음에 다른

gdb 명령을 사용하면 된다. 정지점 설정에 사용하는 명령어는

break(줄여서b), condition(조건부정지점) 등이있다.

break 명령어는 함수를 매개변수로 받아들여서 해당 함수를

호출하는 시점에서멈추도록만든다. 다음예는main 함수에서

gdb가 수행을 멈추도록 지시한다. (gdb)는 gdb 프롬프트를 의

미하므로타이핑하면안된다.

(gdb) break main

condition 명령어는 정지점 번호와 조건을 매개변수로 받아

들여서 조건부로 정지점에 멈추도록 만든다. 다음 예는 day가

365가될경우정지점2번에멈추도록만든다.

(gdb) condition 2 day == 365

정지점 정보를 보고 싶으면 info breakpoint 명령을 내리면

된다. 정지점번호와정지점주소를출력한다.

(gdb) info breakpoint

하드웨어 감시점

일부 프로세서에서는 하드웨어를 사용하여 특정 메모리값이

변하는지감시할수있다. 이과정은하드웨어가수행하므로, 메

모리값이 변할 때까지 프로그램은 정상 속력으로 동작한다. 하

드웨어감시점설정에사용하는명령어는watch가있다.

watch 명령어는 변수 이름을 매개변수로 받아들여서 해당

변수가 변할 때 해당 값을 출력하며 멈춘다. 다음 예는 day라는

변수값이바뀌는시점에서멈추도록만든다.

(gdb) watch day

프로그램 실행

중단점을 걸었을 때 계속해서 프로그램을 수행하거나 단계적

으로 프로그램을 실행해야 한다. 이렇게 프로그램 실행 과정에

서 사용하는 명령어는 run(줄여서 r), next(줄여서 n), step(줄

여서s), continue(줄여서c), finish 등이있다.

run 명령어는프로그램을처음부터시작한다.

(gdb) run

next 명령어는다음소스코드행을실행하는데, 함수내부로

는 진입하지 않는다. next 뒤에 숫자를 넘기면, 해당 숫자만큼

next를반복한다.

(gdb) next

step 명령어는 다음 소스 코드 행을 실행하는데, 함수 내부로

진입한다. 역시 step 뒤에 숫자를 넘기면 해당 숫자만큼 step을

TTEECCHHNNIICCAALL FEATURE ����

반복한다.

(gdb) step

continue 명령어는 실행을 복귀하는 명령이다. 다음 정지점

을만날때까지계속수행한다.

(gdb) continue

finish 명령어는 현재 스택 프레임이 끝날 때까지만 계속 수

행한다. 즉들어간함수내부실행이끝날때까지유효하다.

(gdb) finish

변수값 출력

현재 스택 프레임에서 유효한 변수값을 출력한다. 다양한 용

법을 제공하는 print 명령을 사용한다. day 변수값을 16진수로

출력하려면다음과같이/x 매개변수를넘긴다.

(gdb) print /x day

변수나 문자열을 포매팅해서 보려면 printf와 유사한 포매팅

문자열을사용한다.

(gdb) print “%s\n”, const_str

직전에print 명령으로출력한결과를재사용하려면$1, $2와

같은 $ 표기법을 사용한다. $값은 print 명령 수행 직후에 결과

를출력하는과정에서확인이가능하다.

(gdb) print $1 + 300

여기서 초보자가 한 가지 주의할 사항이 있는데, print 문으

로는매크로로치환된값을보지못한다. 따라서매크로값을확

인하려면 소스 코드를 뒤져야 하는 불편함이 있다. 이런 문제를

근본적으로 해결하려면 매크로 치환 신에 const를 사용한 상

수선언을사용해야한다.

스택 추적

스택은 프로세스가 실행 중에 코드 어디에 위치하는지를 알

려주는 정보를 포함하고 있으므로 매우 중요하다. 현재 수행 위

치를 파악하려면 반드시 스택 정보를 사용해야 하며, 다행히도

gdb는 스택 추적에 필요한 여러 명령어를 제공하고 있다. 많이

사용하는 명령은 backtrace(줄여서 bt), frame, up, down 등

이있다.

backtrace 명령어는 현재 디버깅중인 프로세서에 한 스택

추적을 덤프해준다. backtrace 명령 결과는 함수 호출 체인을

보여주므로, 어떤 경로를 통해 현재 함수를 호출했는지 한눈에

살펴볼 수 있다. 코어 파일을 읽은 직후에 backtrace 명령을 한

번 내려주면 코어가 발생한 지점을 바로 출력한다. 참고로

backtrace에서 출력하는 정보에는 각 함수마다 매개변수로 넘

어간 값이 포함되어 있으므로 디버깅 과정에서 일일이 개별 함

수호출에따른매개변수점검과정을생략할수있다.

(gdb) backtrace

frame 명령어는 현재 스택 프레임을 다른 곳으로 이동하는

데 사용한다. C와 같은 언어는 현재 함수 내부의 변수만 보이므

로(물론전역변수는어느함수에서도보인다), 특정함수내부에

존재하는 변수를 살펴보기 위해서는 스택 프레임 이동이 필수

적이다. frame 명령어 뒤에 프레임 번호를 붙이면 해당 프레임

으로 바로 이동하며, 이 프레임 번호는 backtrace 명령어 결과

에서확인이가능하다.

(gdb) frame 2

프레임을 한 단계씩 위아래로 오르내리도록 만들려면 up과

down을사용한다.

(gdb) up

79Embedded World

���� 리눅스 개발자를 위한 디버깅 기법 ②

82

(gdb) down

gdb는절 로스택처음과끝을지나치도록허용하지않으므

로 스택 오버플로우나 스택 언더플로우 걱정은 할 필요가 전혀

없다. 마지막으로 스택 정보를 확인하려면 만능 재주꾼인 info

를다음과같이사용한다.

(gdb) info frame 2

코어 읽기와 쓰기

코어 파일이 만들어졌을 경우 gdb를 사용해서 이 코어 파일

을 읽을 수 있다. 가장 손쉬운 방법으로 gdb 명령을 내리면서

코어파일이름을지정하면된다.

$ gdb my_prog core

여기서 core는 코어 파일 이름이며, 만일 core_pattern을 사

용해서 코어 이름을 변경했다면 바뀐 코어 파일 이름을 지정해

야한다.

gdb를사용해서현재디버깅중인프로세스의상태를덤프할

수 있다. gdb 내장 명령어인 generate-core-file를 사용하면

현제 실행 중인 디버깅 세션을 그 로 코어 파일로 만들어준다.

이런 기능은 불가피한 사유로 디버깅 도중에 컴퓨터를 꺼야 할

때 위력을 발휘한다. 나중에 전원을 넣고 컴퓨터를 시동한 상태

에서 디버깅을 위한 gdb 세션을 준비할 때 저장했던 코어 파일

을읽으면직전디버깅상태그 로복원이가능하기때문이다.

(gdb) generate-core-file

gdbserver

임베디드 환경에서는 하드웨어적인 디버거를 사용하지 않으

면 소프트웨어적인 프로그램 추적이 불가능하므로, 임베디드

개발자들은 프로그램 개발 초기를 제외하고 디버거 사용을 꺼

려하는 경향이 있다. 디버깅은 주로 UART와 같은 직렬 통신을

사용한 상태 출력(일반 프로그램에서 printf로 조건을 콘솔로

출력하며디버깅하는작업과유사하다)에의존한다.

임베디드 리눅스 환경에서는 일반 리눅스 개발 환경에서 사

용하는 디버깅 환경(최강의 디버거인 gdb)을 그 로 쓸 수 있으

므로 상당한 강점으로 작용한다. 물론 gdb 자체를 교차 컴파일

해서목표 컴퓨터로 가져간 다음 실행할수도 있다. 하지만 gdb

가상당히덩치가크며메모리를많이잡아먹기때문에교차디

버깅이라는 좀더 효과적인 방법을 고안했다. gdb를 교차 디버

깅이 가능하도록 컴파일한(주의: 이 때 교차 gdb는 일반적인 교

차 개발 환경과 마찬가지로 호스트 컴퓨터에서 동작한다) 다음

에호스트컴퓨터에서 돌리며, gdbserver라는작은프로그램을

목표 컴퓨터에서 돌리면 gdb가 gdbserver에 필요한 명령을 내

리고gdbserver는이명령에따라수행한결과를gdb에되돌려

준다. 호스트 컴퓨터에서는 마치 지역 컴퓨터에서 프로그램을

돌리는 느낌으로 디버깅할 수 있다. 목표 보드 쪽에서 수행하는

프로그램은 심지어 공간을 줄이기 위해 strip 명령으로 디버깅

에필요한심볼정보를빼버려도된다. 이런특질은심볼정보가

상당히큰c++ 프로그래밍언어로개발한프로그램을디버깅할

때특히유용하다.

그림 1에 교차 디버깅 환경을 예시하 다. 그림에서 나타난

바와 같이 gdb와 gdbserver는 직렬 통신이나 TCP/IP를 사용

해서 통신하므로, 교차 디버거를 사용하기 위해서는 반드시 목

표 컴퓨터에 직렬이나 네트워크 장치를 연결해야 한다. 포트 번

TTEECCHHNNIICCAALL FEATURE ����

그림 1. 교차 디버깅 환경(gdb와 gdbserver)

호스트 컴퓨터

(x86)

gdb

목표 컴퓨터

(x86, arm, mpc)

gdbserver

네트워크 연결(gdb 서버와 gdb 통신)

직렬/USB 연결(터미널 - 콘솔 출력)

네트워크 연결(터미널 - 텔넷/웹 접속)

네트워크 연결NFS 마운트/(T)FTP

HDD

호를 양쪽에서 똑같이 지정한 다음에 gdb와 gdbserver를 동작

시키기만하면자동으로연결이이뤄진다.

gdb와 gdbserver를 사용하려면 클라이언트/서버 사이 통신

을 위해 TCP/IP 네트워크나 직렬 통신 설정이 필요하다. 여기

서는 TCP/IP 네트워크를 사용한다고 보고 192.168.114.1을 개

발 호스트로, 192.168.114.2를 목표 컴퓨터로 가정한다. 물론

gdbserver와 교차 컴파일한(x86 환경이라면 일반적으로 컴파

일한) 프로그램은교차컴파일후목표컴퓨터로미리복사해놓

아야한다. 다음과같은방법으로목표보드와개발호스트쪽디

버깅환경을설정하자.

●목표 보드쪽 설정: 목표 보드 쪽에서는 gdbserver만 띄워

놓으면 모든 작업이 끝난다. 여기서 미리 네트워크 설정을

잡아놓아야한다는사실을기억하기바란다.

- 포트 번호 9012는 시스템에서 사용하지 않는 임의로 정한

값이다. 시스템 관리자가 아닌 일반 사용자는 반드시 포트

번호를1024 이상으로지정해야한다.

- pid 값은수행할때마다달라질수있다.

- 직렬 포트를 통해 디버깅을 하려면 다음과 같이 명령을 내

린다. /dev/ttyS0는상황에맞춰서변경하기바란다.

$ ./gdbserver /dev/ttyS0 debug

● 개발 호스트쪽 디버깅: 개발 호스트쪽에서는 gdb를 사용

해서 실제 디버깅 작업을 벌인다. gdb 프롬프트가 떨어지면 다

음과같은명령을내려서디버깅서버에접속하자.

- “target remote 192.168.114.2:9012”에서 9012는 직전에

gdbserver에서정의한포트번호이다.

- 직렬 포트를 통해 디버깅을 하려면 다음과 같이 target 명

령을 내린다. 앞서 gdbserver와 마찬가지로 /dev/ttyS0는

상황에맞춰서변경하기바란다.

(gdb) target remote /dev/ttyS0

gdbserver는 gdb 패키지 내부에 들어있으므로, 별도로 내려

받을필요는없다. 교차개발환경에맞춰서컴파일만해주면끝

난다. 또한gdbserver에서도웬만한gdb 명령은똑같은방식으

로 내릴수 있으므로, gdb에 익숙한 개발자라면 처음 시작할때

내리는 몇 가지 명령어를 제외하고는 다른 특별한 내용을 배울

필요가없다.

DDD와 인사이트(Insight)

윈도우 환경에서 IDE를 사용하다가 처음으로 순수 gdb를 보

면저절로비명이튀어나오기마련이다. 전형적인CUI(Charac-

ter User Interface)를 따르고 있기에 외부에서 터미널 연결만

가능하면 언제 어디서나 디버깅 작업을 진행할 수 있다는 장점

이 있긴 하지만, gdb는 모든 명령어를 키보드로 입력해야 하기

때문에 익숙해지기까지 상당한 시간을 요한다. 이런 문제점을

해결하기 위해 오픈 소스 개발자들은 gdb와 통신하면서 필요한

기능을 마우스와 아이콘으로 수행 가능하도록 만들어주는 그림

사용자 인터페이스를 덧붙이는 프론트 엔드를 개발하는 작업을

시작했다.

gdb 프론트 엔드 중에초창기에 나온 소프트웨어로 xxgdb를

빼놓을 수 없다. xxgdb는 gdb가 나오기 전에 한 시절을 풍미했

던 dbx의 프론트 엔드인 xgdb를 gdb용으로 만든 프론트 엔드

이며, X11/Xt의 표준 위젯 집합인 아데나를 사용하고 있으므로

요즘 보면 상당히촌스러운 느낌이 난다. 몇몇 gdb 프론트 엔드

변종이 있었지만, 모티프를 기반으로 획기적인 사용자 인터페

이스로 무장한 DDD가 등장하면서 gdb 프론트 엔드 소프트웨

어를하나로통일해버리게된다.

DDD는 모티프 라이선스 문제로 초기에는 상용 모티프 라이

83Embedded World

���� 리눅스 개발자를 위한 디버깅 기법 ②

[jrogue@remote gdbserver]$ ./gdbserver 192.168.114.

1:9012 debug

Process debug created; pid = 1028

(gdb) target remote 192.168.114.2:9012

192.168.114.2:9012: Success

84

브러리를 장착한 워크스테이션 급 컴퓨터에서만 돌아갔다(계속

해서 xxgdb 개발이 이뤄졌다). 하지만 모티프 클론인 레스티프

가 등장하고 모티프 자체도 오픈 소스로 풀리면서 오픈 모티프

로 거듭났기 때문에 요즘에는 리눅스와 같은 공개 소스 운 체

제에서도동작한다. DDD는Data Display Debugger라는이름

에걸맞게자료구조시각화에상당한위력을발휘한다. 자료구

조를 시각적인 다이어그램으로 보여주므로 연결 리스트와 같은

복잡한 자료 구조나 그래프도 종이와 연필을 사용하지 않고 컴

퓨터 화면에서 바로 파악이 가능하다. 아래 소개하는 그림을 보

면알겠지만복잡한자료구조를알기쉽게그림으로보여준다.

모티프 인터페이스를 기반으로 만들었으며 gdb 프론트 엔드

로 동작하는 DDD와 달리 인사이트는 Tcl/Tk를 사용해서 새롭

게 만든 gdb 변종이다. 인사이트는 Cygwin에서 gdb를 동작시

키기 위해 시작한 프로젝트이며 레드햇과 시그너스에서 개발하

고있다. Cygwin만이Tcl/Tk를돌릴수있는환경으로이식가

능하지만 독립적으로 동작하는 특성상 주로 Cygwin에서 많이

사용하고있다.

DDD나 인사이트 모두 복잡한 gdb 명령어를 암기할 필요없

이 다중 윈도우 환경에서 메뉴,아이콘과 마우스만으로 필요한

gdb 명령을 내릴 수 있으며, 필요하다면 gdb 콘솔 창을 열어서

직접 gdb 명령을 내리거나(예: 임베디드 디버깅을 위한 gdb-

server와 연결하기 위한 명령), 그림 사용자 인터페이스로 내린

명령이 어떻게 진짜 gdb 명령으로 탈바꿈하는지 콘솔 창에서

직접확인할수도있다.

끝 말

gdb 명령어 종류는 워낙 많고 활용법도 다양하므로 한정된

지면에서 모든 내용을 소개하기란 불가능에 가깝다(실제 PDF

로 만든 공식 GDB 매뉴얼은 400페이지를 가뿐하게 넘어선다).

따라서 이번 연재에서는 기본적인 gdb 활용법과 임베디드 환경

에서gdb를 활용하는 방법에 집중했다. 좀더 고급 정보가 필요

하다면참고문헌에나와있는다양한정보를활용하기바란다.

아무리 도구가 좋더라도 결국 디버깅은 사람 머리로 수행하는

작업이므로 gdb 사용법에 너무 집착해서 정작 중요한 디버깅 본

질을 놓치면 곤란하다. 리눅스 토발즈를 커널 내부에 탑재한 디

버거가커널소스코드개발자에게편법을조장하거나새로운기

능을 추가한 코드에 한 이해도를 떨어뜨리는 도구로 전락할까

TTEECCHHNNIICCAALL FEATURE ����

그림 2. DDD에서 연결 리스트를 시각적으로 보여주는 화면 그림 3. DDD에서 자료를 그래프 형식으로 보여주는 화면

두렵다(‘리눅스 디버깅과 성능 튜닝’13장 커널 디버거 참조)고

지적했듯이 디버거는 잘못 사용하면 독이 될 가능성이 높다. 따

라서디버거는코드를충분히이해한다음에디버깅생산성을높

이기위해사용해야지처음부터코드가어떤일을하는지도모르

는상태에서는막무가내로사용하지않기바란다.

85Embedded World

���� 리눅스 개발자를 위한 디버깅 기법 ②

* 리눅스 디바이스 드라이버 3판(번역서, 한빛미디어) : 디바이스 드

라이버 디버깅을 위해서는 4장 디버깅 기술을 참조하기 바란다.

* 리눅스 디버깅과 성능 튜닝: 오픈 소스 도구를 사용한 문제 진단

분석과 해결(번역서, 에이콘): 디버깅과 관련한 무척 흥미로운 주

제를 단계별로 차근차근 다루고 있다. 리눅스 초급 개발자라면

제 로 된 디버깅을 위해 반드시 한번 읽어봐야 한다.

* Self-Service Linux: Mastering the Art of Problem Deter-

mination(원서, Prentice Hall PTR): 리눅스 디버깅과 성능 튜닝

보다 좀더 고급 주제를 다룬다. 본문 중 gdb와 스택 동작 원리

설명은 이 책의 백미이다.

* 위키피디아 gdb 소개: http://en.wikipedia.org/wiki/Gdb

* gdb 빠른 참조 가이드: http://refcards.com/refcards/gdb/

index.html

* DDD 홈페이지: http://www.gnu.org/software/ddd/

* 인사이트 홈페이지: http://sourceware.org/insight/

참고문헌

그림 4. 인사이트에서 제공하는 다양한 창

02-2026-5700www.embeddedworld.co.kr

인터넷에서읽는

Embedded Worlde-Magazine

Embedded World의 특징은 제작비용 및 유통비용, 판매가격이 상 적으

로 인쇄책자보다 저렴하며 수정 및 재가공이 가능합니다. 또한 멀티미디어

기능이 있어 표현이 다양하고 광고효과가 뛰어난 장점을 지니고 있습니다.

Embedded World를 www.EmbeddedWorld.co.kr에서 이용하시려면

Adobe Acrobat eBook Reader를 설치해야 합니다.(eBook Service 참조)