說明
gdb一份代碼裏包含兩個程序,一個是gdb,一個是gdbserver,分別運行在PC主機和開發板上,編譯的時候得分開編譯。
準備材料
操作系統:ubuntu-16.04.4-desktop-i386
本地編譯器:gcc v5.4.0(ubuntu原配)
交叉編譯器:arm-linux-gcc v3.4.5
gdb源碼:gdb-7.5.tar.bz2(gdb下載地址)
gdb和gdbserver我已經編譯好了,在這裏:百度網盤,密碼: v36n
編譯gdb
進入gdb的源碼目錄,配置gdb:
gdb-7.5$ ./configure --target=arm-linux
gdb-7.5$ make
出現一個錯誤:
opncls.c: In function ‘bfd_fopen’:
bfd.h:529:65: error: right-hand operand of comma expression has no effect [-Werror=unused-value]
#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE)
重新配置一次,忽略這種函數命名不規範導致的錯誤:
gdb-7.5$ ./configure --target=arm-linux --disable-werror
再次make後又出現錯誤:
checking for library containing waddstr... no
configure: WARNING: no enhanced curses library found; disabling TUI
checking for library containing tgetent... no
configure: error: no termcap library found
Makefile:8370: recipe for target 'configure-gdb' failed
make[1]: *** [configure-gdb] Error 1
make[1]: Leaving directory '/home/sam/Work/gdb/gdb-7.5'
Makefile:844: recipe for target 'all' failed
make: *** [all] Error 2
安裝libncureses5-dev:
gdb-7.5$ sudo apt-get install libncurses5-dev
再次make,通過了。此時gdb位於:gdb-7.5/gdb/gdb。你可以執行make install把gdb安裝到/usr/local/bin/裏去,由於ubuntu自帶了一個gdb,我沒有這樣做,而是後續自己手動加入,並改了個名,以區分ubuntu自帶的那個gdb。
然而,gdbtui並沒有編譯出來,我也不知道爲什麼,但是我編譯gdb-7.4.1是可以的。
編譯gdbserver
進入gdbserver所在目錄:gdb-7.5/gdb/gdbserver,配置gdbserver:
gdb-7.5/gdb/gdbserver$ ./configure --target=arm-linux --host=arm-linux
- --target=arm-linux你不用改,除非你的單板不是ARM;
- --host=arm-linux意思是你的交叉編譯器的前綴是arm-linux,如果你的交叉編譯器叫arm-none-linux-gnueabi-gcc,那麼這裏應該填--host=arm-none-linux-gnueabi;
make後出現錯誤:
linux-arm-low.c: In function `arm_stopped_by_watchpoint':
linux-arm-low.c:643: error: `PTRACE_GETSIGINFO' undeclared (first use in this function)
linux-arm-low.c:643: error: (Each undeclared identifier is reported only once
linux-arm-low.c:643: error: for each function it appears in.)
Makefile:222: recipe for target 'linux-arm-low.o' failed
make: *** [linux-arm-low.o] Error 1
意思是PTRACE_GETSIGINFO這個宏沒有定義,這個宏其實位於交叉編譯器的安裝目錄裏:
gcc-3.4.5-glibc-2.3.6$ grep -nrR PTRACE_GETSIGINFO
arm-linux/sys-include/linux/ptrace.h:27:#define PTRACE_GETSIGINFO 0x4202
arm-linux/include/linux/ptrace.h:27:#define PTRACE_GETSIGINFO 0x4202
distributed/arm-linux/sys-include/linux/ptrace.h:27:#define PTRACE_GETSIGINFO 0x4202
distributed/arm-linux/include/linux/ptrace.h:27:#define PTRACE_GETSIGINFO 0x4202
修改linux-arm-low.c這個文件,添加#include <linux/ptrace.h>
/* Don't include elf.h if linux/elf.h got included by gdb_proc_service.h.
On Bionic elf.h and linux/elf.h have conflicting definitions. */
#ifndef ELFMAG0
#include <elf.h>
#endif
#include <sys/ptrace.h>
#include <signal.h>
#include <linux/ptrace.h>
再次make,通過了。
開始調試
準備
- 單板和主機之間連接好串口線或網線或WIFI;
- 編譯程序,記得gcc加上-g選項;
- 可執行程序主機和單板各存一份;
- 主機編譯出的gdbserver拷貝到單板的/usr/bin/目錄下,單板檢查這個gdbserver有沒有執行權限,沒有的話chmod +x /usr/bin/gdbserver;
注意
在主機上運行arm-linux-gnueabihf-gdb如果報這個錯誤:
arm-linux-gnueabihf-gdb: error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file: No such file or directory
解決方法是:
sudo apt-get install libpython2.7
在單板上運行gdbserver如果報這個錯誤:
gdbserver: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
解決方法是:
把主機的<交叉編譯器安裝目錄>/libstdc++.so.6拷貝到單板的/lib目錄。
如果用網絡連接
“test”是待調試的可執行程序。
單板:
gdbserver 192.168.43.247:6666 test
主機:
arm-linux-gnueabihf-gdb test
(gdb) target remote 192.168.43.141:6666
OK,可以開始調試了。
如果用串口連接
這篇文章講得很詳細了: