想到公司买了台仿真器,虽然还没到手但是可以找资料学习一下,特别是想查查有没linux下搭配的软件,因为我知道很多都只有mswin下的。
哈,结果没查到,倒找到了怎么使用gdb远程调试的东西。这个对于我们来说是好方法,至少比我们现在使用的只靠简单地加入调试进行调试的方法效率高很多。而且,我很久就想认真学习一下gdb的使用,可是没有工作压力就是学不上来。呵,这不,又给我找来学了大半天。
以下是总结的一些东西,后面有机会还会继续加入新东西,不管是玩linux的还是openbsd的,只要是我想到的好东西都要加上来。
以此作为今年的第一篇有点技术性质的**开始今年新的学习吧。(虽然大部分是抄袭别人的想法,但,我会尽可能地加入一些属于我自己的东西:)
一,下载比较新的gdb版本源码(下载地址见注1)
二,编译gdb和gdbserver
# tar zxvf gdb-x.x.tar.gz
# cd gdb-x.x
# ./configure --target=powerpc-linux --prefix=/usr/local/gdb
# make // 生成主机对应目标板的gdb
# make install // 安装主机对应目标板的gdb
# cd gdb/gdbserver
# ./configure --target=powerpc-linux --host=powerpc-linux
# make // 生成目标板的gdbserver
三,编译要调试的程序
# powerpc-linux-gcc -g gdbtest.c -o gdbtest // 编译例子程序,注意:有个-g的参数
# cat gdbtest.c // 显示例子的文件内容
#include <stdio.h>
int func(int n)
{
int sum=0, i;
for (i=0; i<n; i++)
{
sum += i;
}
return sum;
}
int main(void)
{
int i;
long result = 0;
for (i=0; i<=100; i++)
{
result += i;
}
printf(&quot;result[1-100] = %d \n&quot;, result);
printf(&quot;resutl[1-225] = %d \n&quot;, func(255));
return 0;
}
四,调试
假设,目标板IP:192.168.0.200,主机IP:192.168.0.20
1, 目标板的操作
# tftp -g 192.168.0.20 -r gdbtest // 下载要调试的程序
# tftp -g 192.168.0.20 -r gdbserver // 下载gdbserver
# chmod +x gdbserver
# ./gdbserver 192.168.0.20:1234 gdbtest // 打开远程调试
Process gdbtest created; pid = 79
Listening on port 1234
出现类似以上信息说明目标板运行成功
2, 主机的操作
# powerpc-linux-gdb gdbtest
(gdb)target remote 192.168.0.20:1234 // 连接到开发板 成功后就可以进行调试
(gdb)list or l
(gdb)break func
(gdb)break 22
(gdb)info br
(gdb)continue or c // 这里不能用 run
(gdb)next or n
(gdb)print or p result
(gdb) finish // 跳出func函数
(gdb) next
(gdb) quit
建立连接后进行gdb远程调试和gdb本地调试方法相同
五,除可以调试编译时带-g参数的程序外,一般的程序也可以调试,只是列不出c的源码,但还是可以看汇编代码。具体更多的gdb命令、功能和使用,请看gdb的手册和文档。
六,值得注意的是,如果列不出c源码或汇编代码等,并报No symbol table等错,那应该是主机没加载要调试的文件,这样就找不到符号表。应该目标板和主机都应该加载同样的文件就不会出现这样的问题了。(呵,这个问题google了好久才得以解决:)
七,除了可以通过tcp进行链接远程调试外,还可以直接通过串口。
1,目标板:
# ./gdbserver /dev/ttyS0 gdbtest
2,主机:
# powerpc-linux-gdb gdbtest
(gdb)target remote /dev/ttyS0
3,如果当前目标板正通过串口连接当终端使用着,像minicom和超级终端等,那可以改用telnet当终端使用。或者使用如下技巧(这个只是想出来,还没完全试过):
# sleep 10; ./gdbserver /dev/ttyS0 gdbtest;
也就是延时10秒后再通过gdbserver打开终端进行调试。在这10秒里也足够结束minicom等终端占用串口。
八,远程调试linux内核和内核模块可以参考:http://www.xfocus.net/articles/200509/820.html
九,列列常用的gdb命令吧:
1, list [<expr | address | [filename:]funcname | [filename:] linenum>] (or l) 查看源码
2, disassemble [address] (or disas) 反汇编
3, printf[/{x|d|u|o|t|a|c|f}] [value] (or p) 查看变量的值
4, break <expr | address | [filename:]funcname | [filename:] linenum> (or br) 添加中断
5, delete breakpoints <number | range> (or del br) 删除中断
6, enable breakpoints <number | range> (or en br) 开启中断
7, disable breakpoints <number | range> (or dis br) 关闭中断
8, info break [number] (or info br) 查看中断列表
9, contione [ignore-count] (or c) 继续运行,直到结束或遇断点
10, nexti [count] (or ni) 机器指令级单步跟踪
11, next [count] (or n) 单步跟踪(不进子函数)
12, stepi [count] (or si) 机器指令级单步跟踪
13, step [count] 单步跟踪(进入子函数)
14, finish 继续运行,直到函数返回
15, until (or u) 继续运行,直到退出循环体
16, run (or r) 运行
17, bt 查看函数堆栈
18, shell <command> 运行shell命令
19, cd <dir> 等价于shell cd <dir>
20, pwd 等价于shell pwd
21, make [args] 等价于shell make [args]
22, watch <expr> 添加变化观察点
23, rwatch <expr> 添加读观察点
24, awatch <expr> 添加读写观察点
25, info watchpoints 查看所有观察点列表
26, search <regexp> 向前搜索源码
27, reverse-search <regexp> 全面搜索源码
28, x[/{n|f|u}] <address> 查看内存
29, display[/{i|s}] <expr | addr> 自动显示
30, quit (or q)
...
注:
1, 下载gdb源码的地址:http://ftp.gnu.org/gnu/gdb/
2, gdb的文档:
(英文版)http://sourceware.org/gdb/documentation/
(中文简单实用版)http://yongzou.com/gdb%E4%B8%AD%E6%96%87%E6%89%8B%E5%86%8C/
3, 我们公司现在用到的三个平台的分别为(虽然还有mips平台的,可是我工作上没接触着):
marvell arm-none-linux-gnueabi
storlink armv4tl-hardhat-linux
powerpc powerpc-linux
4, 可以通过ftp,tftp,nfs,ssh等方法进行传输文件
5, 参考:http://blog.csdn.net/zxg623/archive/2007/09/02/1769200.aspx |