Bonjour, tout le monde!

lldb 사용법 본문

42

lldb 사용법

hygoni 2020. 11. 12. 02:39

맥을 쓰면 기본적으로 lldb라는 디버거가 설치되어있다. 나도 피씬 때 처음 써봤는데 익숙해지면 정말 좋다. 피씬 시험볼 때도 애용한 편.. 나는 시간이 지나면서 사람들이 디버거를 사용할 거라고 생각했는데, 그렇지 않았다. 그러니 내가 홍보해야지. 이 글은 lldb의 매우 기본적인 기능을 다룬다. 글 맨 아래 링크의 글에 더 많은 기능이 소개되어있다!

컴파일 옵션

우선 디버깅을 하려면 컴파일 할 때 -g 옵션을 줘야한다.

gcc -g main.c
g++ -g main.c 

이런 식으로. 그래야 디버깅을 할 때 코드를 볼 수 있다. 안 그러면 어셈블리로 디버깅하는 끔찍한 일이 벌어진다. 사실 끔찍하진 않다. 나는 좋아한다.

코드 보기

# 특정 함수 코드 보기
list main

# 특정 파일 코드 보기
list main.c

실행

# 길게 쓰면 run
run

# 짧게 쓰면 r
r

# argument를 넘길 수도 있다
# 이렇게 하면 argv[1]에 "hyeyoo"가 들어간다.

run "hyeyoo"

# 그런데 가끔 run 뒤에 argument를 넘기는 게 안될 때도 있다.
# 이유는 모른다. 안 되는 컴퓨터가 종종 있다. 그럴 땐

settings set target.run-args "hyeyoo"

 

그런데 그냥 실행하면 프로그램이 종료될 때까지 실행된다. 디버깅은 버그를 찾아낼 때 사용하는 건데, 프로그램이 끝날 때 까지 실행해버리면 내가 보고 싶은 코드가 어떻게 돌아가는지 볼 수 없다. 이럴 때 breakpoint를 사용하면 원하는 위치에서 프로그램을 멈추게 할 수 있다.

breakpoint

breakpoint는 기본적으로 실행시 어떤 코드에서 멈출지 정하는 용도로 사용한다. 예를 들어 memoryLeak()를 디버깅하려면 memoryLeak()이라는 함수에 breakpoint를 걸고 run을 하면 된다. 그럼 프로그램이 돌다가 memoryLeak 함수를 만나면 멈춘다. 아니면 함수 말고 소스코드의 n번째 줄에 걸 수도 있다.

# breakpoint main함수에 걸기
b main

# main.c의 7번째 라인에 걸기
list main.c
b 7

# main.c의 7번째 라인에 걸기
b main.c:7

# breakpoint 제거
br del (breakpoint 번호)

# 모든 breakpoint 제거
br del

next (n), step

breakpoint를 걸어서 멈추면, 코드를 한줄 씩 실행할 수 있는데 그게 next, step 명령어다. 차이점은

next : step over - 한 줄을 실행하되, 함수가 있다면 함수 안으로 들어가지 않는다.

step : step into - 한 줄을 실행하되, 함수가 있다면 함수 안으로 들어간다.

continue (conti), finish

그런데 한 줄씩 실행하는 건 좀 노가다일 때가 있다. (반복문 빠져나올 때...) 그래서 다음 breakpoint까지 쭉 실행하려면 continue를 하면 되고, 함수를 빠져나오려면 finish를 하면 된다.

 

print (p)

print는 변수의 값을 출력하는 명령어다. 사용법은 정말 간단하다.

# 변수 값 출력
print ptr

# 포인터 연산, 구조체 관련 연산도 가능하다. p는 print 줄인 것
p ptr
p *ptr
p ptr->next

# 형변환도 가능하다.
p (unsigned long long)ptr;
p (char)ptr;

memory leak 잡는 법

/* 주의 : 릭을 찾는 방법은 많다. 이건 그냥 내가 쓰는 방법이다. */

맥에는 leaks라고 실행중인 프로세스의 메모리 릭을 검사하는 도구가 있다. leaks (프로세스 id) 또는 leaks (실행파일 이름)을 실행하면 된다. 그래서 보통 leaks로 메모리 릭을 체크하려면 main문의 맨 마지막에 무한루프를 걸고, 프로그램을 실행시킨 후에 leaks로 검사한다.

 

lldb와 leaks를 사용하면 어디서 메모리 릭이 나는지 확인할 수 있다. 우선 lldb로 run을 하면 프로세스 id가 나오는데, 거기에 leaks를 실행하면 된다. 보통 나는 쉘을 2개 띄운 후, 한쪽에는 lldb를 실행하고, 나머지 한쪽에는 아래 명령어를 돌린다. (0.5초마다 leaks 돌리기)

 while true; do leaks (lldb에 나온 프로세스 id); sleep 0.5; done

그럼 코드를 한 줄씩 실행하다 릭이 나오면 아래 사진처럼 나온다.

 

참고하면 좋을 자료들

다음에는 더 advanced한 기능들을 글로 소개해볼 생각이다.

아래 튜토리얼들에도 좋은 기능들이 소개되어있다!

 

aaronbloomfield.github.io/pdr/docs/lldb_summary.html

 

PDR: Docs: LLDB Command Summary

PDR: Docs: LLDB Command Summary Go up to the main documents page (md) Assembly-specific commands stepi: step one MACHINE instruction (i.e. assembly instruction), instead of one C++ instruction (which is what step does) register read: display the values in

aaronbloomfield.github.io

aaronbloomfield.github.io/pdr/tutorials/02-lldb/index.html

 

PDR: LLDB Tutorial

PDR: LLDB Tutorial Go up to the Tutorials table of contents page This tutorial is meant to get you used to using the LLVM debugger, lldb. As you read through the first part of the tutorial, you are not expected to remember everything – there is a referen

aaronbloomfield.github.io

lldb.llvm.org/use/tutorial.html

 

Tutorial — The LLDB Debugger

Tutorial Here’s a short precis of how to run lldb if you are familiar with the gdb command set. We will start with some details on lldb command structure and syntax to help orient you. Unlike gdb’s command set, which is rather free-form, we tried to ma

lldb.llvm.org

lldb.llvm.org/use/map.html

 

GDB to LLDB command map — The LLDB Debugger

GDB to LLDB command map Below is a table of GDB commands with the LLDB counterparts. The built in GDB-compatibility aliases in LLDB are also listed. The full lldb command names are often long, but any unique short form can be used. Instead of “breakpoint

lldb.llvm.org

 

'42' 카테고리의 다른 글

lldb 사용법  (0) 2020.11.12
42의 동료 평가, 그리고 시행착오  (1) 2020.10.28
0 Comments
댓글쓰기 폼