OpenWRT开发之——远程debug

来源:互联网 发布:充电器检测软件 编辑:程序博客网 时间:2024/06/07 05:43
摘要
在目标机上安装gdbserver,并进行远程调试。

想要用gdb对OpenWrt进行远程调试。首先得在OpenWrt目标机上安装gdbserver。

其实在trunk路径下也有gdb的ipk安装包的,不信find一下。

[trunk]$ find bin/ -name "gdb*.ipk"bin/ar71xx/packages/base/gdb_7.8-1_ar71xx.ipkbin/ar71xx/packages/base/gdbserver_7.8-1_ar71xx.ipk

查看一下它们的大小:

[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的路由器,实在有点吃紧!

还好,gdbserver只有96K。我们可以将gdbserver安装在目标机上,将其用网络或串口与开发机上的gdb进行协同使用。



1. 安装gdbserver

gdbserver 可以用 ipk 包进行安装。

在OpenWrt的trunk目录下,运行 make menuconfig,进行系统进行裁剪。

gdbserver在 Development 目录下。

将gdbserver选为M,保存退出。

可以打开 .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.

好了!安装好了,那就用用看吧。


2. 试用gdbserver

远程调试需要目标机启动 gdbserver并执行调试目标程序。在调试的过程中,gdbserver开启一个TCP服务,由开发机上的gdb连接。之后 gdbserver接收gdb的指令并将指令操作结果反馈给gdb,从而达到了远程调试的目的。


开发机(CentOS)IP:192.168.1.10

目标机(OpenWrt)IP:192.168.1.2


2.1 首次尝试

在目标机上启动gdbserver

root@OpenWrt:~# gdbserver 127.0.0.1:3000 debug-demoProcess cpp11-demo created; pid = 3335Listening 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(12);    printf("n = %d\n", n);    return 0;}

src/Makefile:

target:=debug-demoCFLAGS+=-gobjects:=$(subst .c,.o,$(wildcard *.c))$(target) : $(objects)    $(CC$(CFLAGS) -o $@ $^.PHONY:cleanclean:    $(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:3000Remote debugging using 192.168.1.2:3000warningwhile parsing target description (at line 10): Target description specified unknown architecture "mips"warning: Could not load XML target description; ignoringReply contains invalid hex digit 59

出现问题:(1)首先gdb不认识mips平台。(2)没有XML目标描述文件。


2.2 解决问题

应该说,什么样的平台就应该用什么样的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-gdbGNU gdb (Linaro GDB) 7.6-2013.05Copyright (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有三种:

  1. 安装到目标机上,在目标机上运行的gdb。(通过SSH在目标机上运行gdb调试)

  2. 运行在开发机上,用于调试目标机上程序的。(通过SSH在目标机上运行gdbserver开启调试服务,在开发机上启动平台对应的gdb连接gdbserver进行调试)

  3. 运行在开发机上,用于调试开发机程序的。

这3种gdb不能搞混淆了。


好,再连接目标机:

(gdb) target remote 192.168.1.2:3000Remote debugging using 192.168.1.2:3000warning: Can not parse XML target description; XML support was disabled at compile time0x77fe0f40 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 目录下的才是。


<未完待续>

0 0
原创粉丝点击