Lệnh gdb trong linux là một công cụ dòng lệnh mạnh mẽ, giúp bạn gỡ lỗi các chương trình C/C++ một cách hiệu quả. Nó cho phép bạn theo dõi quá trình thực thi, kiểm tra giá trị biến và tìm ra nguyên nhân gây lỗi dễ dàng. Với gdb, việc sửa lỗi trở nên nhanh chóng và chính xác hơn, tiết kiệm thời gian phát triển.
Lệnh gdb trong linux là gì?
GDB (GNU Debugger) là một công cụ dòng lệnh mạnh mẽ, cho phép bạn gỡ lỗi các chương trình viết bằng C, C++, và nhiều ngôn ngữ khác trên Linux. Command gdb in linux giúp bạn kiểm tra trạng thái chương trình, đặt điểm dừng, và theo dõi giá trị biến để tìm ra lỗi. Nó cho phép bạn chạy chương trình từng bước một, giúp bạn hiểu rõ hơn luồng thực thi và xác định nguyên nhân gây ra sự cố. Với GDB, việc tìm và sửa lỗi trong code trở nên dễ dàng và hiệu quả hơn rất nhiều, tiết kiệm thời gian và công sức. GDB là một công cụ không thể thiếu cho bất kỳ lập trình viên nào làm việc trên hệ thống Linux.
Giới thiệu về gdb và Cách Sử Dụng
Trong bước này, chúng ta sẽ làm quen với GNU Debugger (gdb) và cách dùng nó để debug chương trình C. gdb là công cụ mạnh mẽ giúp bạn kiểm tra trạng thái chương trình đang chạy, đặt breakpoint và dò từng bước code để tìm và sửa lỗi.
Đầu tiên, hãy đảm bảo rằng gdb đã được cài đặt trong container Ubuntu 22.04 Docker của chúng ta:
sudo apt-get update
sudo apt-get install -y gdb
Ví dụ về kết quả:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
libasan6 libubsan1 python3-gdb
Suggested packages:
gdb-multiarch
The following NEW packages will be installed:
gdb libasan6 libubsan1 python3-gdb
0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
Need to get 3,470 kB of archives.
After this operation, 13.5 MB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Bây giờ, hãy tạo một chương trình C đơn giản để debug. Tạo file example.c trong thư mục ~/project với nội dung sau:
#include <stdio.h>
int main() {
int a = 5;
int b = 0;
int c = a / b;
printf("The result is: %d\n", c);
return 0;
}
Chương trình này sẽ cố tình chia cho 0, gây ra lỗi runtime.
Để debug chương trình này bằng gdb, hãy làm theo các bước sau:
- Biên dịch chương trình với flag
-gđể bao gồm các debugging symbol:
gcc -g -o example example.c
- Khởi động gdb debugger và tải chương trình đã biên dịch:
gdb ./example
- Trong gdb prompt, đặt breakpoint tại hàm
main:
(gdb) break main
Breakpoint 1 at 0x11a6: file example.c, line 4.
- Chạy chương trình:
(gdb) run
Starting program: /home/labex/project/example
- Khi chương trình dừng tại breakpoint, bạn có thể kiểm tra biến, dò từng bước code và debug vấn đề:
Breakpoint 1, main () at example.c:4
4 int a = 5;
(gdb) print a
$1 = 5
(gdb) next
5 int b = 0;
(gdb) print b
$2 = 0
(gdb) next
6 int c = a / b;
Như bạn thấy, khi chương trình cố gắng chia cho 0, nó sẽ gây ra lỗi runtime mà có thể được bắt và debug bằng gdb.
Gỡ Lỗi Chương Trình C Đơn Giản với gdb
Trong bước này, chúng ta sẽ dùng gdb để gỡ lỗi một chương trình C đơn giản có lỗi runtime.
Đầu tiên, hãy tạo một file C mới tên là simple.c trong thư mục ~/project với nội dung sau:
#include <stdio.h>
int main() {
int x = 10;
int y = 0;
int z = x / y;
printf("The result is: %d\n", z);
return 0;
}
Chương trình này sẽ cố tình chia cho zero, gây ra lỗi runtime (thời gian chạy).
Bây giờ, hãy biên dịch chương trình với flag -g để bao gồm các debugging symbols:
gcc -g -o simple simple.c
Tiếp theo, khởi động gdb debugger và tải chương trình đã biên dịch vào:
gdb ./simple
Trong gdb prompt, đặt một breakpoint tại hàm main:
(gdb) break main
Breakpoint 1 at 0x11a6: file simple.c, line 4.
Bây giờ, hãy chạy chương trình:
(gdb) run
Starting program: /home/labex/project/simple
Khi chương trình dừng tại breakpoint, bạn có thể kiểm tra biến, đi từng bước code và gỡ lỗi:
Breakpoint 1, main () at simple.c:4
4 int x = 10;
(gdb) print x
$1 = 10
(gdb) next
5 int y = 0;
(gdb) print y
$2 = 0
(gdb) next
6 int z = x / y;
Như bạn thấy, khi chương trình cố gắng chia cho zero, nó sẽ gây ra lỗi runtime và có thể được bắt và gỡ lỗi bằng gdb.
Gỡ lỗi chương trình C đa luồng với gdb
Trong bước này, chúng ta sẽ dùng gdb để gỡ lỗi một chương trình C đa luồng có race condition.
Đầu tiên, hãy tạo một file C mới tên là multithreaded.c trong thư mục ~/project với nội dung sau:
#include <stdio.h>
#include <pthread.h>
int shared_variable = 0;
void* thread_function(void* arg) {
for (int i = 0; i < 1000000; i++) {
shared_variable++;
}
return NULL;
}
int main() {
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, thread_function, NULL);
pthread_create(&thread2, NULL, thread_function, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("Final value of shared_variable: %d\n", shared_variable);
return 0;
}
Chương trình này tạo ra hai luồng, cả hai đều tăng một biến chia sẻ 1.000.000 lần.
Do race condition, giá trị cuối cùng của biến chia sẻ có thể không phải là 2.000.000 như mong đợi.
Bây giờ, hãy biên dịch chương trình với flag -g để bao gồm các debugging symbol:
gcc -g -o multithreaded multithreaded.c -lpthread
Tiếp theo, khởi động gdb debugger và tải chương trình đã biên dịch:
gdb ./multithreaded
Trong dấu nhắc gdb, đặt một breakpoint ở đầu hàm thread_function:
(gdb) break thread_function
Breakpoint 1 at 0x11b6: file multithreaded.c, line 7.
Bây giờ, hãy chạy chương trình:
(gdb) run
Starting program: /home/labex/project/multithreaded
Khi chương trình chạm breakpoint, bạn có thể kiểm tra biến, bước qua code và gỡ lỗi race condition:
Breakpoint 1, thread_function (arg=0x0) at multithreaded.c:7
7 for (int i = 0; i < 1000000; i++) {
(gdb) print shared_variable
$1 = 0
(gdb) step
8 shared_variable++;
(gdb) print shared_variable
$2 = 1
Bằng cách bước qua code và kiểm tra biến chia sẻ, bạn có thể quan sát race condition.
Từ đó, bạn có thể xác định vấn đề trong chương trình đa luồng này một cách dễ dàng.
Kết luận cho linux gdb command
Vậy là chúng ta đã cùng nhau khám phá những điều cơ bản về gdb, một công cụ gỡ lỗi mạnh mẽ trên Linux. Hy vọng rằng, với những kiến thức này, bạn sẽ tự tin hơn khi đối mặt với những lỗi khó chịu trong chương trình của mình. Đừng ngại thử nghiệm các linux gdb command khác nhau để hiểu rõ hơn cách chúng hoạt động nhé. Gỡ lỗi có thể hơi khó khăn lúc đầu, nhưng càng thực hành nhiều, bạn sẽ càng trở nên thành thạo hơn. Hãy nhớ rằng, gdb là một người bạn đồng hành đáng tin cậy trên con đường trở thành một lập trình viên giỏi. Chúc bạn thành công và luôn tìm thấy niềm vui trong việc lập trình! Hãy tiếp tục khám phá và chinh phục những thử thách mới!