想要用gdb對OpenWrt進行遠程調試。首先得在OpenWrt目標機上安裝gdbserver。html
其實在trunk路徑下也有gdb的ipk安裝包的,不信find一下。linux
[trunk]$ find bin/ -name "gdb*.ipk" bin/ar71xx/packages/base/gdb_7.8-1_ar71xx.ipk bin/ar71xx/packages/base/gdbserver_7.8-1_ar71xx.ipk
查看一下它們的大小:git
[trunk]$ ls -lh bin/ar71xx/packages/base/gdb*.ipk -rw-r--r--. 1 hevake_lcj hevake_lcj 1.5M May 3 02:31 bin/ar71xx/packages/base/gdb_7.8-1_ar71xx.ipk -rw-r--r--. 1 hevake_lcj hevake_lcj 96K May 3 02:31 bin/ar71xx/packages/base/gdbserver_7.8-1_ar71xx.ipk
OMG,gdb這個包有1.5M!對於FLASH總共才只有8M的路由器,實在有點吃緊!redis
還好,gdbserver只有96K。咱們能夠將gdbserver安裝在目標機上,將其用網絡或串口與開發機上的gdb進行協同使用。shell
gdbserver 能夠用 ipk 包進行安裝。網絡
在OpenWrt的trunk目錄下,運行 make menuconfig,進行系統進行裁剪。spa
gdbserver在 Development 目錄下。.net
將gdbserver選爲M,保存退出。debug
能夠打開 .config 進行查看:調試
能夠看到 CONFIG_PACKAGE_gdbserver=m。
好了,再 make V=s 。
編譯完成以後,生成 bin/ar71xx/packages/base/gdbserver_7.8-1_ar71xx.ipk 包文件。
將這個文件用 scp 傳送到目標機上,進行安裝。
root@OpenWrt:~# opkg install gdbserver_7.8-1_ar71xx.ipk Installing gdbserver (7.8-1) to root... Collected errors: * satisfy_dependencies_for: Cannot satisfy the following dependencies for gdbserver: * libthread-db * * opkg_install_cmd: Cannot install package gdbserver.
依賴 libthread-db 庫。那就先安裝 libthread 。安裝包是:
trunk/bin/ar71xx/packages/base/libthread-db_0.9.33.2-1_ar71xx.ipk
將其傳到目標機上並安裝。
而後再安裝 gdb-server:
root@OpenWrt:~# opkg install gdbserver_7.8-1_ar71xx.ipk Installing gdbserver (7.8-1) to root... Configuring gdbserver.
好了!安裝好了,那就用用看吧。
遠程調試須要目標機啓動 gdbserver並執行調試目標程序。在調試的過程當中,gdbserver開啓一個TCP服務,由開發機上的gdb鏈接。以後 gdbserver接收gdb的指令並將指令操做結果反饋給gdb,從而達到了遠程調試的目的。
開發機(CentOS)IP:192.168.1.10
目標機(OpenWrt)IP:192.168.1.2
在目標機上啓動gdbserver
root@OpenWrt:~# gdbserver 127.0.0.1:3000 debug-demo Process cpp11-demo created; pid = 3335 Listening on port 3000
如上,命令格式爲:gdbserver <local IP>:<port> <program> [args list]
<local IP>就寫成127.0.0.1,<port>指定爲3000,要調試的是debug-demo程序。
以下爲程序源碼:
src/main.c
#include <stdio.h> int nGlobalVar = 0; int tempFunction(int a, int b) { printf("tempFunction is called, a = %d, b = %d \n", a, b); return (a + b); } int main() { int n; n = 1; n++; n--; nGlobalVar += 100; nGlobalVar -= 12; printf("n = %d, nGlobalVar = %d \n", n, nGlobalVar); n = tempFunction(1, 2); printf("n = %d\n", n); return 0; }
src/Makefile:
target:=debug-demo CFLAGS+=-g objects:=$(subst .c,.o,$(wildcard *.c)) $(target) : $(objects) $(CC) $(CFLAGS) -o $@ $^ .PHONY:clean clean: $(RM) $(objects)
值得注意的是:在 src/Makefile中,添加一行:
CFLAGS+=-g
使之在make的時候可以將調試信息加進去。
將這個程序打包安裝到OpenWrt上去。至於怎麼打包與安裝,博主已上前面兩三個博文裏詳細討論過了,這裏再也不重複囉嗦。若想了解詳細步驟,請參考:【OpenWrt對C++11的支持】
而後,在開發機上啓動gdb,並執行 target remote 192.168.1.2:3000 進行鏈接:
$ gdb (gdb) target remote 192.168.1.2:3000 Remote debugging using 192.168.1.2:3000 warning: while parsing target description (at line 10): Target description specified unknown architecture "mips" warning: Could not load XML target description; ignoring Reply contains invalid hex digit 59
出現問題:(1)首先gdb不認識mips平臺。(2)沒有XML目標描述文件。
應該說,什麼樣的平臺就應該用什麼樣的gdb進行調試。若是像上面那樣,用開發機的 gdb 與目標機上的 gdbserver 鏈接進行調試,應該是不對的。
那麼應該使用 mips 平臺的gdb。而這個gdb就在 staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/ 路徑下,有一個:mips-openwrt-linux-gdb 文件。
運行它來進行調試:
[trunk]$ cd ./staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/ [bin]$ ./mips-openwrt-linux-gdb GNU gdb (Linaro GDB) 7.6-2013.05 Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=i686-redhat-linux --target=mips-openwrt-linux-uclibc". For bug reporting instructions, please see: <http://bugs.launchpad.net/gdb-linaro/>. (gdb)
能夠看到,gdb在啓動時提示:"This GDB was configured as "--host=i686-redhat-linux --target=mips-openwrt-linux-uclibc",說明該gdb是針對mips平臺的。
這裏,博主要總結一下。gdb有三種:
安裝到目標機上,在目標機上運行的gdb。(經過SSH在目標機上運行gdb調試)
運行在開發機上,用於調試目標機上程序的。(經過SSH在目標機上運行gdbserver開啓調試服務,在開發機上啓動平臺對應的gdb鏈接gdbserver進行調試)
運行在開發機上,用於調試開發機程序的。
這3種gdb不能搞混淆了。
好,再鏈接目標機:
(gdb) target remote 192.168.1.2:3000 Remote debugging using 192.168.1.2:3000 warning: Can not parse XML target description; XML support was disabled at compile time 0x77fe0f40 in ?? () (gdb)
結果仍是報沒有XML目標描述文件。
從網上找到資料:http://blog.csdn.net/yangzhongxuan/article/details/13002789
具這位大牛說,是在編譯gdb的時候,沒有XML的解析庫expat。
那我就在開發機上看一下有沒有這個庫。用locate查一下:
$ locate libexpat ... /lib/libexpat.so.1 /lib/libexpat.so.1.5.2 ...
說明開發機系統是有expat庫的。
那爲何沒有編譯進去呢?有多是在編譯 gdb 的 ./configure 時候,將expat去除了。
查看trunk路徑下,關於gdb包的Makefile。打開文件:package/devel/gdb/Makefile,發現:
嘿!第56行,看到了嗎?禁了expat。爲何要禁它???
博主也就嘗試一下,把第56行刪除。改爲:
從新make gdb。
[trunk]$ make package/devel/gdb/install V=s
思考一下:你說,這是編譯目標機上在gdb呢,仍是開發機上的gdb?
實踐證實,我想錯了。在package目錄下都是要打包成ipk的。
由於上面的make命令並無影響到:staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-gdb
而是:bin/ar71xx/packages/base/gdb_7.8-1_ar71xx.ipk
應該是在 toolchain 目錄下的纔是。
<未完待續>