Q) 그냥 프로그램이 실행되고 끝나요!
A) run 명령어를 입력하기 전에, 살펴보고자 하는 함수의 이름이나 위치에 브레이크포인트를 걸어보세요.
(lldb) b get_next_line
Breakpoint 1: where = app.out`get_next_line, address = 0x0000000100003610`
(lldb) run
Process 12345 launched: '<your/program/path>' (x86_64)
Process 12345 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x000000010000251b app.out`get_next_line(fd=4) at get_next_line.c:103:9
100 char *line;
101 char *temp;
102
-> 103 if (fd < 0 || BUFFER_SIZE < 1)
104 return (NULL);
105 node = gnl_lstset(&head, fd);
106 if (node == NULL)
Target 0: (app.out) stopped.
Shell
복사
Q) 디버깅이 레지스터 명령어 단위로 실행돼요!
A) 컴파일을 할 때, 디버깅 옵션(-g)를 붙여주세요.
# gcc main.c
> lldb a.out
...
Process 12345 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100003610 app.out`get_next_line
app.out`get_next_line:
-> 0x100003610 <+0>: pushq %rbp
0x100003611 <+1>: movq %rsp, %rbp
0x100003614 <+4>: subq $0x30, %rsp
0x100003618 <+8>: movl %edi, -0xc(%rbp)
Target 0: (app.out) stopped.
Shell
복사
# gcc -g main.c
> lldb a.out
...
Process 12345 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x000000010000251b app.out`get_next_line(fd=4) at get_next_line.c:103:9
100 char *line;
101 char *temp;
102
-> 103 if (fd < 0 || BUFFER_SIZE < 1)
104 return (NULL);
105 node = gnl_lstset(&head, fd);
106 if (node == NULL)
Target 0: (app.out) stopped.
Shell
복사
Q) 매번 명령어를 실행할 때마다 fr v 를 입력하는게 너무 귀찮아요!
A) lldb 명령창에 target stop-hook add --one-liner "frame variable" 를 입력해보세요.
(lldb) target stop-hook add --one-liner "frame variable"
Stop hook #1 added.
(lldb) n
(int) fd = 4
(t_list *) node = 0x00000003040c74e0
(char *) line = 0x0000003000000008 ""
(char *) temp = 0x00000001089f0719 ""
Process 73998 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step over
frame #0: 0x0000000100002539 app.out`get_next_line(fd=4) at get_next_line.c:105:27
102
103 if (fd < 0 || BUFFER_SIZE < 1)
104 return (NULL);
-> 105 node = gnl_lstset(&head, fd);
106 if (node == NULL)
107 return ((char *)gnl_lstclear(&head, fd));
108 temp = node->backup;
Shell
복사
Q) v 명령어를 입력해도 전역변수가 안보여요!
A) ta v (target variable) 명령어를 입력해보세요.
(lldb) ta v
Global variables for <your/program/function> in <your/program/path>:
(t_list *) head = 0x0000603000001a80
Shell
복사
Q) 반복문에 빠져버렸어요!
A) 무한루프 바깥의 행 번호에 브레이크포인트를 걸고 c (continue) 명령어를 입력해보세요.
Process 73998 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step over
frame #0: 0x0000000100002b20 app.out`gnl_strjoin(s1="Ut", s2=" enim ad minim veniam, quis nostrud exerci") at get_next_line_utils.c:52:2
49 while (s1[len1] != '\0')
50 len1++;
51 len2 = 0;
-> 52 while (s2[len2] != '\0') # 빠져나올 수 없는 반복문의 늪...
53 len2++;
54 string = malloc(sizeof(char) * (len1 + len2) + 1);
55 if (string == NULL)
Target 0: (app.out) stopped.
# 아무리 n을 눌러도 while문을 빠져나올 수 없어...!!
Shell
복사
# 그 순간, 당신의 손가락을 구해줄 브레이크포인트가 나타났다...
(lldb) b 54
Breakpoint 2: where = app.out`gnl_strjoin + 245 at get_next_line_utils.c:54:34, address = 0x0000000100002b25`
(lldb) c
Process 73998 resuming
Process 73998 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
frame #0: 0x0000000100002b25 app.out`gnl_strjoin(s1="Ut", s2=" enim ad minim veniam, quis nostrud exerci") at get_next_line_utils.c:54:34
51 len2 = 0;
52 while (s2[len2] != '\0')
53 len2++;
-> 54 string = malloc(sizeof(char) * (len1 + len2) + 1);
55 if (string == NULL)
56 return (NULL);
57 i = 0;
Target 0: (app.out) stopped.
Shell
복사
Q) 브레이크포인트 목록을 보고싶어요!
A) br l 을 입력해보세요.
(lldb) br l
1: name = 'get_next_line', locations = 1, resolved = 1, hit count = 1
1.1: where = app.out`get_next_line + 11 at get_next_line.c:103:9, address = 0x000000010000251b, resolved, hit count = 1
Shell
복사
만약 브레이크포인트를 지우고 싶다면, br del <num> 을 입력해주세요.
(lldb) br del 1
1 breakpoints deleted; 0 breakpoint locations disabled.
(lldb) br l
No breakpoints currently set
Shell
복사
Q) LLDB가 보여주는 코드가 너무 적어요!
A) ~/.lldbinit 파일에(만약 파일이 없다면 홈디렉토리에 파일을 만들어주세요) 아래의 설정을 입력해주세요.
# ~/.lldbinit
# 행 옆에 표시된 화살표 기준으로 코드의 숫자를 원하는만큼 늘릴 수 있습니다. (기본은 3인듯)
settings set stop-line-count-before 10
settings set stop-line-count-after 10
Shell
복사
(lldb) r
Process 74313 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step over
frame #0: 0x0000000100002539 app.out`get_next_line(fd=4) at get_next_line.c:105:27
95
96 char *get_next_line(int fd)
97 {
98 static t_list *head;
99 t_list *node;
100 char *line;
101 char *temp;
102
103 if (fd < 0 || BUFFER_SIZE < 1)
104 return (NULL);
-> 105 node = gnl_lstset(&head, fd);
106 if (node == NULL)
107 과제 코드가 너무 많이 보여져버려서 임의로 지우겠습니다...
108 ////////////////////////////////////
109 ////////////////////////////////////
110 ////////////////////////////////////
111 ////////////////////////////////////
112 ////////////////////////////////////
113 ////////////////////////////////////
114 ////////////////////////////////////
115 ////////////////////////////////////
Target 0: (app.out) stopped.
# 와! 눈이 상쾌하다!
Shell
복사
앞으로 좋은 LLDB 꿀팁을 발견하거나 사용하기 어려운 지점이 생긴다면 업데이트 하겠습니다!
참고자료: