Bài 35.228 phút đọc
Điểm dừng và điều khiển luồng chạy
Sau bài này bạn sẽ làm được
- Đặt điểm dừng theo hàm, theo dòng và theo điều kiện
- Phân biệt next với step và biết khi nào dùng cái nào
- Dùng finish để thoát nhanh khỏi hàm đã lỡ bước vào
- Quản lý danh sách điểm dừng bằng info, disable, delete
Điểm dừng có điều kiện là thứ biến GDB từ đồ chơi thành công cụ. Không có nó, bạn bấm continue chín trăm chín mươi bảy lần. Có nó, bạn dừng đúng lần lặp cần xem.
#Đặt điểm dừng
break main # theo ten ham (viet tat: b main)
break 42 # theo dong trong tep hien tai
break dslk.c:23 # theo tep va dong
break *0x4015be # theo dia chi
break # tai dong hien tai
tbreak tong # diem dung TAM: chi dung mot lan roi tu xoa
rbreak ^sv_ # moi ham co ten bat dau bang sv_
start # tuong duong: tbreak main + runterminal
gdb -q -batch -x g1.gdb ./dslk.exe
Breakpoint 1 at 0x4015be: file dslk.c, line 23. Thread 1 hit Breakpoint 1, tong (dau=0x752830) at dslk.c:23 23 int t = 0;
#Điểm dừng có điều kiện
vong.c
#include <stdio.h>
static int xu_ly(int i) { return i * i; }
int main(void) {
int tong = 0;
for (int i = 0; i < 1000; ++i)
tong += xu_ly(i);
printf("tong = %d\n", tong);
return 0;
}terminal
# Tệp lệnh: break xu_ly if i > 996, run, info args, bt
gdb -q -batch -x g5.gdb ./vong.exe
Breakpoint 1 at 0x401557: file vong.c, line 3.
Thread 1 hit Breakpoint 1, xu_ly (i=997) at vong.c:3
3 static int xu_ly(int i) { return i * i; }
i = 997
#0 xu_ly (i=997) at vong.c:3
#1 0x0000000000401587 in main () at vong.c:9# Ba cach khac de bo qua nhung lan dung khong can
ignore 1 500 # bo qua 500 lan dung dau tien cua diem dung 1
# nhanh hon dieu kien, vi khong phai danh gia bieu thuc
break xu_ly
commands
silent
if i < 990
continue
end
printf "i = %d\n", i
end # lenh tu dong, xem muc cuoi bai#Quản lý danh sách
info breakpoints # liet ke tat ca (viet tat: i b)
delete 2 # xoa diem dung so 2
delete # xoa HET, co hoi lai neu confirm on
disable 1 # tat tam thoi, giu lai
enable 1 # bat lai
enable once 1 # bat, dung mot lan roi tu tat
enable delete 1 # bat, dung mot lan roi tu xoa
clear tong # xoa diem dung o ham tong
clear dslk.c:23 # xoa theo vi tri(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000401557 in xu_ly at vong.c:3
stop only if i > 996
breakpoint already hit 1 time
2 breakpoint keep n 0x0000000000401587 in main at vong.c:9
3 hw watchpoint keep y sv.diem
/* Doc cac cot:
Disp keep = giu lai, del = tu xoa sau lan dung dau
Enb y = dang bat, n = dang tat
What vi tri, va dong duoi la dieu kien neu co */#Năm cách bước
| Lệnh | Viết tắt | Làm gì |
|---|---|---|
| run | r | Chạy từ đầu |
| continue | c | Chạy tiếp tới điểm dừng sau |
| next | n | Chạy một dòng, BƯỚC QUA lời gọi hàm |
| step | s | Chạy một dòng, BƯỚC VÀO hàm nếu có mã nguồn |
| finish | fin | Chạy hết hàm hiện tại rồi dừng ở hàm gọi |
| until 50 | u 50 | Chạy tới dòng 50 |
| until | u | Như next, nhưng không quay lại đầu vòng lặp |
| advance tong | Chạy tới khi vào hàm tong hoặc thoát khung hiện tại | |
| nexti / stepi | ni / si | Bước một LỆNH MÁY thay vì một dòng |
| kill | k | Dừng chương trình, giữ phiên GDB |
buoc.c
static int binh_phuong(int x) {
int t = x * x;
return t;
}
static int tinh(int a, int b) {
int u = binh_phuong(a);
int v = binh_phuong(b);
return u + v;
}
int main(void) {
int kq = tinh(3, 4);
printf("kq = %d\n", kq);
return 0;
}terminal
# break tinh, run, display u, next, step, info args
gdb -q -batch -x g7.gdb ./buoc.exe
Breakpoint 1 at 0x40157c: file buoc.c, line 10. Thread 1 hit Breakpoint 1, tinh (a=3, b=4) at buoc.c:10 10 int u = binh_phuong(a); 11 int v = binh_phuong(b); 1: u = 9 binh_phuong (x=4) at buoc.c:4 4 int t = x * x; x = 4
terminal
# finish: chạy hết hàm hiện tại
gdb -q ./buoc.exe
(gdb) tbreak binh_phuong Temporary breakpoint 1 at 0x40155b: file buoc.c, line 4. (gdb) run Thread 1 hit Temporary breakpoint 1, binh_phuong (x=3) at buoc.c:4 4 int t = x * x; (gdb) finish Run till exit from #0 binh_phuong (x=3) at buoc.c:4
#Chạy lệnh tự động khi dừng
Gắn một chuỗi lệnh vào điểm dừng
(gdb) break them
(gdb) commands
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>silent
>printf "them: ma=%d ten=%s\n", ma, ten
>continue
>end
/* Bay gio moi lan them() duoc goi, GDB in mot dong roi chay tiep,
khong dung lai.
"silent" bo dong "Breakpoint 1, them (...)" ma GDB in mac dinh,
nen ket xuat gon.
Day thuc chat la printf debugging ma KHONG PHAI dich lai chuong trinh.
Do la uu the lon nhat cua no. */terminal
gdb -q -batch -x g_them.gdb ./dslk.exe
Breakpoint 1 at 0x401563: file dslk.c, line 12. them: ma=10 ten=mot them: ma=20 ten=hai them: ma=30 ten=ba tong = 60 a[2] = 9
Tự làm thử
- Đặt điểm dừng theo tên hàm, theo dòng và theo tệp, rồi so ba cách.
- Đặt
break xu_ly if i > 996trên vòng lặp nghìn lần và xác nhận nó dừng đúng lần. - So thời gian giữa
break f if x == 999999vàignore 1 999998. - Dùng
nextvàsteptrên cùng một dòng có gọi hàm và đối chiếu. - Dùng
untilđể thoát khỏi một vòng lặp nghìn vòng bằng một lệnh. - Viết một khối
commandsghi nhật ký mọi lời gọi một hàm mà không dịch lại chương trình.
Trình chấm điểm tự động sẽ được bổ sung ở giai đoạn sau. Hiện tại bạn tự chạy thử trên máy.
Tóm tắt
break tongdừng sau phần mở đầu hàm, nên tham số đã sẵn sàng khi bạn gọiinfo args.- Điều kiện của điểm dừng là biểu thức C đầy đủ, gọi được cả
strcmpvà đi theo được con trỏ. nextbước qua lời gọi hàm,stepbước vào,finishchạy hết hàm và in giá trị trả về.untilở cuối thân vòng lặp thoát thẳng ra khỏi vòng, thay cho hàng nghìn lầnnext.- Khối
commandsvớisilentvàcontinuecho bạn gỡ lỗi bằngprintfmà không phải dịch lại.