More Breaks
นอกจาก break โง่ๆที่แสดงให้ดูก่อนหน้าแล้ว ยังมี break อีกหลายแบบที่ช่วยให้เราสามารถ debug ด้วย GDB อย่างมีความสุขมากขึ้นได้ (สำหรับคนที่ชื่นชอบการ break โง่ๆก็ข้ามได้ครับ)
Break with condition
เราสามารถเพิ่ม condition ขณะ break ได้ โดยใช้คำสั่ง cond
ด้วย cond <breakpoint_no> <condition>
เช่น
(gdb) b 11
Breakpoint 1 at 0x890: file example.c, line 11.
(gdb) cond 1 (i==5)
(gdb) r
Starting program: /home/bankde/Desktop/tmp/example.o
Put string to split: hello world
Breakpoint 1, split (input=0x7fffffffdf40 "hello world\n") at example.c:11
11 if (input[i] == ' ') {
(gdb) p i
$1 = 5
เราก็จะสามารถหยุดเฉพาะกรณี i==5 ได้ ไม่เสียเวลามานั่งเลือกครับ
Break when Variables change
ให้หยุดเมื่อตัวแปรที่เราระบุไว้มีการเปลี่ยนแปลง ใช้คำสั่ง watch
ครับ ข้อเสียคือ ตัวแปรนั้นต้องถูกประกาศ หรือ memory ที่จะ watch ต้องถูก allocate ก่อน
นอกจากนี้ยังมี rwatch
สำหรับหยุดเมื่อพบการ read และ awatch
สำหรับทั้งการ read/write ด้วย
(gdb)
10 for (int i=0; i<strlen(input); i++) {
(gdb)
11 if (input[i] == ' ') {
(gdb) watch i
Hardware watchpoint 2: i
(gdb) c
Continuing.
Hardware watchpoint 2: i
Old value = 0
New value = 1
0x00005555555548e3 in split (input=0x7fffffffdf40 "hello world\n") at example.c:10
10 for (int i=0; i<strlen(input); i++) {
(gdb) c
Continuing.
Hardware watchpoint 2: i
Old value = 1
New value = 2
0x00005555555548e3 in split (input=0x7fffffffdf40 "hello world\n") at example.c:10
10 for (int i=0; i<strlen(input); i++) {
(gdb) c
Continuing.
Hardware watchpoint 2: i
Old value = 2
New value = 3
0x00005555555548e3 in split (input=0x7fffffffdf40 "hello world\n") at example.c:10
10 for (int i=0; i<strlen(input); i++) {
watch ที่ memory location ก็ได้ครับ อันนี้เครื่องผมไม่ support masking ของ watch เลยต้อง manual watch เอง เนื่องจากมันไม่เข้าใจว่าที่ watch อยู่เป็น string old/new value เลยดูประหลาดๆ ก็เลยต้อง print bytes ออกมาให้ดูครับ
(gdb) b getInputAndRun
Breakpoint 1 at 0x90d: file example.c, line 20.
(gdb) r
Starting program: /home/bankde/Desktop/tmp/example.o
Breakpoint 1, getInputAndRun () at example.c:20
20 int getInputAndRun() {
(gdb) n
22 printf("Put string to split: ");
(gdb)
23 fgets(input, 100, stdin);
(gdb)
Put string to split: hello world
24 if (strcmp(input, "exit") == 0) return -1;
(gdb) x/s input
0x7fffffffdf40: "hello world\n"
(gdb) watch *0x7fffffffdf40 mask 0xffffffffff00
This target does not support masked watchpoints.
(gdb) watch *0x7fffffffdf40
Hardware watchpoint 2: *0x7fffffffdf40
(gdb) watch *0x7fffffffdf44
Hardware watchpoint 3: *0x7fffffffdf44
(gdb) watch *0x7fffffffdf48
Hardware watchpoint 4: *0x7fffffffdf48
(gdb) c
Continuing.
Hardware watchpoint 3: *0x7fffffffdf44
Old value = 1870078063
New value = 1870069871
split (input=0x7fffffffdf40 "hello") at example.c:13
13 result[j] = input+i+1;
(gdb) x/4xb 0x7fffffffdf44
0x7fffffffdf44: 0x6f 0x00 0x77 0x6f
(gdb) c
Continuing.
Hardware watchpoint 2: *0x7fffffffdf40
Old value = 1819043176
New value = 1819043144
getInputAndRun () at example.c:28
28 *result[1] = toupper(result[1][0]);
(gdb) c
Continuing.
Hardware watchpoint 3: *0x7fffffffdf44
Old value = 1870069871
New value = 1867972719
getInputAndRun () at example.c:29
29 printf("First str: %s\n", result[0]);
(gdb) c
Continuing.
First str: Hello
Second str: World
Break on Catch Event
ใช้ catch
สำหรับดักพวก Exception และ loading shared library ต่างๆ ผมไม่ได้เขียน c++ เลยใช้ส่วนนี้ไม่เป็นครับ ตอนนี้ใส่ไว้ให้ผู้อ่านรู้ว่ามันก็มีนะ ส่วนใครทำเป็น มาเปิด PR เติมได้
Last updated
Was this helpful?