📉
GDBTutorial
  • Introduction
  • Why GDB
  • Preparation
  • Creating Coredump
  • Reading Coredump
  • Dynamic Running GDB
  • More Breaks
  • More Info
  • Changing Program Flow
  • Automating Debug
  • Example 1: Test the Patch
  • More configuration
Powered by GitBook
On this page
  • Break with condition
  • Break when Variables change
  • Break on Catch Event

Was this helpful?

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 เติมได้

PreviousDynamic Running GDBNextMore Info

Last updated 5 years ago

Was this helpful?