当前位置:嗨网首页>书籍在线阅读

19-应用程序调试

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

22.10 应用程序调试

在嵌入式系统中,为调试Linux应用程序,可在目标板上先运行GDBServer,再让主机上的GDB与目标板上的GDBServer通过网口或串口通信。

1.目标板

需要运行如下命令启动GDBSerber:

gdbserver :

:为主机的IP地址和端口,app是可执行的应用程序名。

当然,也可以用系统中空闲的串口作为GDB调试器和GDBServer的底层通信手段,如:

gdbserver/dev/ttyS0./tdemo

2.主机

需要先运行如下命令启动GDB:

arm-linux-gdb

app与GDBServer的app参数对应,arm-linux-gdb是专门为ARM处理器编译出的GDB调试器。

之后,运行如下命令就可以连接目标板:

target remote :

:为目标机的IP地址和端口。

如果目标板上的GDBServer使用串口,则在宿主机上GDB也应该使用串口,如:

(gdb)target remote/dev/ttyS1

之后,便可以使用GDB像调试本机上的程序一样调试目标机上的程序。

3.通过gdbserver和arm-linux-gdb调试LDD6410应用程序

我们为LDD6410开发板提供了gdbserver,下面演示通过以太网口调试LDD6410上的应用程序。要调试的应用程序的源代码如下:

/*

  • gdb_example.c: program to show how to use arm-linux-gdb

*/

void increase_one(int *data)

{ data = data + 1;

}

int main(int argc, char *argv[])

{ int dat = 0;

int *p = 0;

increase_one(&dat);

/ program will crash here /

increase_one(p);

return 0;

}

通过 debug 方式编译它:

arm-linux-gcc -g -o gdb_example gdb_example.c

将程序下载到目标板后,在目标板上运行:

gdbserver 192.168.1.20:1234 gdb_example

Process gdb_example created; pid = 1096

Listening on port 1234

其中 192.168.1.20为目标板的IP,1234为gdbserver的侦听端口。

在主机上运行:

lihacker@lihacker-laptop:~/ldd6410/tests/gdb-example$ arm-linux-gdb gdb_example

GNU gdb 6.6

Copyright (C) 2006 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are welcome

to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB. Type "show warranty" for details.

This GDB was configured as "--host=/usr/local/arm/4.2.2-eabi/usr/bin/ --target= arm

linux" ... (gdb)

主机的 arm-linux-gdb中运行如下命令连接目标板:

(gdb) target remote 192.168.1.20:1234

Remote debugging using 192.168.1.20:1234

...

0x400007b0 in ?? ()

运行如下命令将断点设置在increase_one(&dat);这一行:

(gdb) b gdb_example.c:16

Breakpoint 1 at 0x8390: file gdb_example.c, line 16.

通过“c”命令继续运行目标板上的程序,发生断点:

(gdb) c

Continuing.

...

Breakpoint 1, main (argc=1, argv=0xbead4eb4) at gdb_example.c:16

16 increase_one(&dat);

运行“n”命令执行完increase_one(&dat);

再查看dat的值:

(gdb) n

19 increase_one(p); (gdb) p dat

$1 = 1

发现 dat 变成 1。继续运行“c”命令,由于即将访问空指针,gdb_example将崩溃:

(gdb) c

Continuing.

Program received signal SIGSEGV, Segmentation fault.

0x0000834c in increase_one (data=0x0) at gdb_example.c:8

8 data = data + 1;

我们通过“bt”命令可以拿到 backtrace:

(gdb) bt

0 0x0000834c in increase_one (data=0x0) at gdb_example.c:8

1 0x000083a4 in main (argc=1, argv=0xbead4eb4) at gdb_example.c:19

通过“info reg”命令可以查看当时的寄存器值:

(gdb) info reg

r0 0x0 0

r1 0xbead4eb4 3199028916

r2 0x1 1

r3 0x0 0

r4 0x4001e5e0 1073866208

r5 0x0 0

r6 0x826c 33388

r7 0x0 0

r8 0x0 0

r9 0x0 0

r10 0x40025000 1073893376

r11 0xbead4d44 3199028548

r12 0xbead4d48 3199028552

sp 0xbead4d30 0xbead4d30

lr 0x83a4 33700

pc 0x834c 0x834c <increase_one+24>

fps 0x0 0

cpsr 0x60000010 1610612752