Bài 35.330 phút đọc
Xem dữ liệu: print, x và ptype
Sau bài này bạn sẽ làm được
- Dùng print với các định dạng /x /d /t /c /s
- In n phần tử liên tiếp bằng cú pháp @
- Đọc bộ nhớ thô bằng x với đủ ba phần của đặc tả
- Dùng ptype và display cho vòng lặp gỡ lỗi nhanh
Ba lệnh làm nên chín mươi phần trăm công việc trong GDB: print để xem giá trị, x để xem byte, ptype để xem kiểu. Bài này chạy hết chúng trên một chương trình thật.
#print và các định dạng
terminal
# Dừng ở dòng 41 của dslk.c, sau khi mọi thứ đã khởi tạo
gdb -q -batch -x g2.gdb ./dslk.exe
Breakpoint 1 at 0x40168f: file dslk.c, line 41.
Thread 1 hit Breakpoint 1, main () at dslk.c:41
41 printf("tong = %d\n", t);
$1 = {5, 3, 9, 1, 7}
$2 = {5, 3, 9, 1, 7}
$3 = {0x5, 0x3, 0x9, 0x1, 0x7}
$4 = 0x9
$5 = 1001
$6 = 65 'A'
$7 = 32
$8 = 60
$9 = 0x3c| Lệnh | Kết quả | Ghi chú |
|---|---|---|
| print a | $1 = {5, 3, 9, 1, 7} | Mảng in đầy đủ |
| print a[0]@5 | $2 = {5, 3, 9, 1, 7} | n phần tử từ một địa chỉ |
| print/x a | $3 = {0x5, 0x3, 0x9, 0x1, 0x7} | Hệ mười sáu |
| print/x a[2] | $4 = 0x9 | Một phần tử, hệ mười sáu |
| print/t a[2] | $5 = 1001 | Hệ hai |
| print/c 65 | $6 = 65 'A' | Vừa số vừa ký tự |
| print sizeof(Nut) | $7 = 32 | Tính được cả sizeof |
| print t | $8 = 60 | Biến thường |
| print/x t | $9 = 0x3c | Cùng biến, khác định dạng |
#In mảng
(gdb) print a
$1 = {5, 3, 9, 1, 7} /* mang co kich thuoc biet truoc: in het */
(gdb) print a[0]@5
$2 = {5, 3, 9, 1, 7} /* cu phap @: in n phan tu tu mot dia chi */
(gdb) print *p@10 /* voi con tro: day la cach DUY NHAT */
(gdb) print *ds@so_phan_tu /* so luong lay tu mot bien */
/* Cu phap @ la thu quan trong nhat trong muc nay:
voi "int *p = malloc(n * sizeof *p)", GDB khong biet n,
nen "print p" chi cho ra dia chi va "print *p" chi cho phan tu dau. */# Mang lon: gioi han so phan tu in ra
(gdb) show print elements
Limit on string chars or array elements to print is 200.
(gdb) set print elements 0 # khong gioi han
(gdb) set print elements 20 # chi 20 phan tu dau
# In dep hon
(gdb) set print array on # moi phan tu mot dong
(gdb) set print array-indexes on # kem chi so
(gdb) print a
$1 = {[0] = 5,
[1] = 3,
[2] = 9,
[3] = 1,
[4] = 7}
# Gom cac gia tri giong nhau
(gdb) show print repeats
Threshold for repeated print elements is 10.
(gdb) print bo_dem
$2 = '\000' <repeats 1023 times> # thay vi in 1024 so khong#ptype và whatis
terminal
gdb -q -batch -x g2.gdb ./dslk.exe
type = struct Nut {
int ma;
char ten[16];
struct Nut *sau;
}
type = struct Nut {
int ma;
char ten[16];
struct Nut *sau;
} *(gdb) ptype Nut /* dinh nghia DAY DU cua kieu */
(gdb) ptype dau /* kieu cua bien, dau * o cuoi cho biet la con tro */
(gdb) whatis dau /* chi TEN kieu, khong khai trien */
$1 = type = Nut *
(gdb) ptype tong /* ca chu ky ham */
type = int (const Nut *)
(gdb) ptype/o Nut /* GDB 8.1 tro len: kem OFFSET va kich thuoc */# Ba lenh info tra cuu ky hieu
(gdb) info functions tong # moi ham co ten chua "tong"
All functions matching regular expression "tong":
File dslk.c:
static int tong(const Nut *);
(gdb) info variables # moi bien toan cuc va tinh
(gdb) info types Nut # moi kieu khop
(gdb) info line dslk.c:23 # dia chi cua mot dong
(gdb) info symbol 0x4015be # ky hieu tai mot dia chi
(gdb) info scope tong # bien nao song trong ham tong#Lệnh x: đọc bộ nhớ thô
terminal
gdb -q -batch -x g2.gdb ./dslk.exe
0x61fe30: 5 3 9 1 0x61fe40: 7 0x61fe30: 0x05 0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x61fe38: 0x09 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x61fe40: 0x07 0x00 0x00 0x00 0xb82834: "ba"
| Lệnh | Dùng khi |
|---|---|
| x/16xb &sv | Xem từng byte của một struct, kể cả phần đệm |
| x/8xg $sp | Xem tám ô tám byte trên đỉnh ngăn xếp |
| x/s ten | Xem một chuỗi, dừng ở ký tự kết thúc |
| x/3s ten | Xem ba chuỗi liên tiếp trong bộ đệm |
| x/10i $pc | Xem mười lệnh máy sắp chạy |
| x/4f d | Xem bốn số thực |
| x/20xw p | Xem hai mươi word từ một con trỏ nghi ngờ |
| x/1000xb bo_dem | Đổ toàn bộ một bộ đệm ra |
#display và info
display x # in x sau MOI lan dung
display/x co # kem dinh dang
display *p # theo doi thu con tro tro toi
info display # liet ke
undisplay 1 # bo mot cai
delete display # bo het
/* display la thu bien viec buoc tung dong thanh de chiu:
thay vi go "print x" sau moi lenh next, ban dang ky mot lan
va GDB in tu dong. */terminal
# display u, rồi next: GDB tự in u sau khi bước
gdb -q -batch -x g7.gdb ./buoc.exe
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
| Lệnh info | Cho biết |
|---|---|
| info locals | Mọi biến cục bộ của khung hiện tại |
| info args | Tham số của hàm hiện tại |
| info frame | Chi tiết khung: địa chỉ trả về, con trỏ khung |
| info registers | Thanh ghi số nguyên |
| info all-registers | Cả thanh ghi SSE và thanh ghi thực |
| info breakpoints | Danh sách điểm dừng và watchpoint |
| info threads | Các luồng đang chạy |
| info sharedlibrary | Thư viện động đã nạp |
| info proc mappings | Bản đồ bộ nhớ, xem trang nào đọc ghi được |
| info source | Tệp nguồn hiện tại và cờ dịch |
#Sửa giá trị khi đang chạy
set var x = 100 # sua bien
set var p->ma = 5 # sua truong qua con tro
set var a[2] = 42 # sua phan tu mang
set var s[0] = 'A' # sua ky tu
set var $rax = 0 # sua thanh ghi
call ham(1, 2) # goi mot ham
print ham(1, 2) # giong call nhung in ket qua
return # ep ham hien tai tra ve NGAY
return 0 # tra ve voi gia tri 0
jump 42 # nhay toi dong 42, KHONG chay cac dong giuaTự làm thử
- In một mảng bằng cả
print avàprint a[0]@5, so hai cách. - In cùng một biến ở năm định dạng khác nhau.
- Chạy
ptype/otrên một struct có đệm và đối chiếu vớisizeof. - Dùng
x/20xbtrên một số nguyên và xác định thứ tự byte của máy bạn. - Dùng biến tiện dụng
$pđể đi qua ba nút của một danh sách liên kết. - Đặt điểm dừng sau
malloc, dùngset var p = 0để đi vào nhánh xử lý hết bộ 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
- Cú pháp
@là cách duy nhất in được n phần tử từ một con trỏ, vì GDB không biết kích thước vùng cấp phát. ptype/ohiện cả độ dời, kích thước và phần đệm, trả lời ngay câu hỏi vì sao struct to hơn tổng các trường.- Đặc tả của
xcó ba phần: số lượng, định dạng, kích thước đơn vị. Gõxtrống thì lặp lại đặc tả cũ. printđánh giá biểu thức C đầy đủ, gọi được cả hàm trong chương trình, nhưng lời gọi đó chạy thật và có tác dụng phụ thật.- Luôn viết
set var x = ...chứ không phảiset x = ..., vì nhiều tên biến trùng với tên lệnh của GDB.