gcc -g <any other flags e.g. -Wall> -o <file> <file.c>
開啟GDB session
在終端機輸入gdb和執行檔名稱即可開啟gdb session
1 2 3 4 5 6 7 8 9
gdb <program_name> GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1 Copyright (C) 2022 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> ... For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from factorial... (gdb)
//This program calculates and prints out the factorials of 5 and 17
#include<stdio.h> #include<stdlib.h>
intfactorial(int n);
intmain(void) { int n = 5; int f = factorial(n); printf("The factorial of %d is %d.\n", n, f); n = 17; f = factorial(n); printf("The factorial of %d is %d.\n", n, f);
return0; } //A factorial is calculated by n! = n * (n - 1) * (n - 2) * ... * 1 //E.g. 5! = 5 * 4 * 3 * 2 * 1 = 120 intfactorial(int n) { int f = 1; int i = 1; while (i <= n) { f = f * i; i++; } return f; }
$ gdb corrupted_linked_list (gdb) run 0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0 **ctrl + c** Program received signal SIGINT, Interrupt. 0x00007fffff1272c0 in __write_nocancel () at ../sysdeps/unix/syscall-template.S:84 84 ../sysdeps/unix/syscall-template.S: No such file or directory.
中斷後我們可以用where指令看一下目前所在的位置,輸出會類似如下
1 2 3 4 5 6 7 8 9 10 11 12
(gdb) where #0 0x00007fffff1272c0 in __write_nocancel () at ../sysdeps/unix/syscall-template.S:84 #1 0x00007fffff0a8bff in _IO_new_file_write (f=0x7fffff3f5620 <_IO_2_1_stdout_>, data=0x6020f0, n=512) at fileops.c:1263 #2 0x00007fffff0aa409 in new_do_write (to_do=512, data=0x6020f0 "0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0-"..., fp=0x7fffff3f5620 <_IO_2_1_stdout_>) at fileops.c:518 #3 _IO_new_do_write (fp=0x7fffff3f5620 <_IO_2_1_stdout_>, data=0x6020f0 "0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0->0-"..., to_do=512) at fileops.c:494 #4 0x00007fffff0a947d in _IO_new_file_xsputn (f=0x7fffff3f5620 <_IO_2_1_stdout_>, data=<optimised out>, n=2) at fileops.c:1331 #5 0x00007fffff07d92d in _IO_vfprintf_internal (s=0x7fffff3f5620 <_IO_2_1_stdout_>, format=<optimised out>, ap=ap@entry=0x7ffffffedf08) at vfprintf.c:1663 #6 0x00007fffff085899 in __printf (format=<optimised out>) at printf.c:33 #7 0x000000000040071b in print_list (list=0x602010) at corrupted_linked_list.c:50 #8 0x0000000000400628 in main () at corrupted_linked_list.c:17
Program terminated with signal SIGSEGV, Segmentation fault. #0 0x000055be9593e283 in print_list (list=0x55be96c20260, length=7) at broken_linked_list.c:51 51 printf("%d->", curr->data);
define p_generic_list set var $n = $arg0 while $n print *($n) set var $n = $n->next end end
document p_generic_list p_generic_list LIST_HEAD_POINTER Print all the fields of the nodes in the linked list pointed to by LIST_HEAD_POINTER. Assumes there is a next field in the struct. end
define indentby printf "\n" set $i_$arg0 = $arg0 while $i_$arg0 > 10 set $i_$arg0 = $i_$arg0 - 1 printf "%c", ' ' end end
//This program calculates and prints out the factorials of 5 and 17
#include <stdio.h> #include <stdlib.h>
int factorial(int n);
int main(void) { int n = 5; int f = factorial(n); printf("The factorial of %d is %d.\n", n, f); n = 17; f = factorial(n); printf("The factorial of %d is %d.\n", n, f);
return 0; } //A factorial is calculated by n! = n * (n - 1) * (n - 2) * ... * 1 //E.g. 5! = 5 * 4 * 3 * 2 * 1 = 120 int factorial(int n) { int f = 1; int i = 1; while (i <= n) { f = f * i; i++; } return f; }
(gdb) br factorial Breakpoint 1 at 0x11a5: file factorial.c, line 24. (gdb) r Starting program: ~/factorial Breakpoint 1, factorial (n=5) at factorial.c:24 24 int f = 1; (gdb) c Continuing. The factorial of 5 is 120. Breakpoint 1, factorial (n=17) at factorial.c:24 24 int f = 1;
接下來設定watch和display,我們希望i初始化之後再設定watch和display,
1 2 3 4
(gdb) n 25 int i = 1; (gdb) n 26 while (i <= n) {
然後設定watch和display
1 2 3 4
(gdb) watch f Hardware watchpoint 2: f (gdb) display i 1: i = 1
//This program calculates and prints out the factorials of 5 and 17
#include<stdio.h> #include<stdlib.h>
intfactorial(int n);
intmain(void) { int n = 5; int f = factorial(n); printf("The factorial of %d is %d.\n", n, f); n = 17; f = factorial(n); printf("The factorial of %d is %d.\n", n, f);
return0; } //A factorial is calculated by n! = n * (n - 1) * (n - 2) * ... * 1 //E.g. 5! = 5 * 4 * 3 * 2 * 1 = 120 intfactorial(int n) { int f = 1; int i = 1; while (i <= n) { f = f * i; i++; } return f; }
你可以先嘗試看看在還沒設定LD_LIBRARY_PATH之前或是利用unset LD_LIBRARY_PATH指令清空LD_LIBRARY_PATH變數,所編譯出來的執行檔會出現什麼問題。 你應該會發現編譯的過程沒有任何錯誤訊息,但是一旦你執行編譯出來的執行檔a.out就會跳出錯誤訊息./a.out: error while loading shared libraries: libpal.so: cannot open shared object file: No such file or directory,這表示執行檔loader找不到libpal.so檔 {: .prompt-tip }