嵌入式中自己编译gdb和gdbserver工具
- 格式:doc
- 大小:36.50 KB
- 文档页数:4
gdbserver 工作原理gdbserver是一种用于调试目标程序的工具,它与gdb(GNU调试器)配合使用,可以实现远程调试功能。
本文将介绍gdbserver 的工作原理及其在调试过程中的应用。
一、gdbserver的工作原理gdbserver是一个在目标系统上运行的程序,它与gdb通过网络连接进行通信。
在目标系统上,gdbserver会替代目标程序的执行,从而使得gdb可以对目标程序进行远程调试。
具体来说,gdbserver的工作原理如下:1. 在目标系统上启动gdbserver,并指定目标程序的可执行文件及其参数。
2. gdbserver会监听一个指定的端口,等待gdb的连接。
3. 在主机上,通过gdb命令连接到目标系统的gdbserver。
4. gdb与gdbserver建立通信后,可以发送各种命令给gdbserver,如设置断点、查看变量值等。
5. gdbserver接收到命令后,在目标系统上执行相应的操作,并将结果返回给gdb。
6. gdb根据返回的结果进行调试操作,如显示变量值、执行下一条指令等。
7. 调试过程中,gdbserver会不断接收来自gdb的命令,并在目标系统上执行相应的操作。
二、gdbserver的应用gdbserver主要用于以下场景:1. 嵌入式系统调试:对于嵌入式系统,通常无法直接在开发主机上运行目标程序,而是需要将目标程序部署到目标系统上进行调试。
gdbserver提供了一种远程调试的方式,可以通过网络连接到目标系统进行调试。
2. 跨平台调试:gdbserver可以在不同的操作系统上运行,例如在Linux上运行gdbserver进行Windows程序的调试。
这种方式可以避免在不同操作系统之间部署gdb的复杂性。
3. 防止干扰:在某些情况下,调试器的运行会对目标程序的执行产生干扰,导致调试结果不准确。
使用gdbserver可以避免这种问题,因为gdbserver运行在目标系统上,与目标程序相互独立。
交叉编译gdb使用交叉编译GDB(GNU Debugger)通常用于在一个平台上生成适用于另一个平台的GDB 可执行文件。
这可能在嵌入式系统或不同体系结构的开发环境中很常见。
以下是一个基本的交叉编译GDB 的步骤:1. 准备交叉编译工具链:-获取并安装适用于目标平台的交叉编译工具链。
这包括交叉编译器、交叉链接器等。
这通常由目标平台的供应商提供。
2. 获取GDB 源码:-下载GDB 的源代码3. 配置GDB 交叉编译:-执行`configure` 脚本时,使用`--target` 选项指定目标平台,并通过`--host` 选项指定主机平台。
例如:```bash./configure --target=your_target_arch --host=your_host_arch --prefix=your_installation_path```其中,`your_target_arch` 是目标平台的体系结构(例如arm-linux-gnueabihf),`your_host_arch` 是主机平台的体系结构(例如x86_64-linux-gnu),`your_installation_path` 是GDB 的安装路径。
4. 编译和安装:-运行`make` 编译GDB,并使用`make install` 安装生成的GDB 可执行文件。
```bashmakemake install```5. 使用交叉编译GDB:-使用交叉编译生成的GDB 进行远程调试或与目标平台交互。
在使用GDB 时,确保使用正确的目标体系结构和调试符号文件。
```bashyour_installation_path/bin/your_target_arch-gdb your_program```请注意,这只是一个简单的步骤示例,实际的交叉编译过程可能会更复杂,具体取决于目标平台和你的开发环境。
确保查阅GDB 文档和目标平台的文档以获取详细的说明。
arm-linux-gdbgdbserver双串口目标机调试心得1.下载gdb源码:/gnu/gdb/2.编译arm-linux-gbd解压后进入gdb-XX目录下:./configure --target=arm-linuxmake(生成gdb)make install(生成arm-linux-gdb,并存入/usr/local/bin/)3.编译gdbserver进入gdb-XX/gdb/gdbserver/目录下:./configure --target=arm-linux --host=arm-linux修改config.h:注释掉//#define HAVA_SYS_REG_H这行修改Makefile:找到“CC = gcc”这行,改为“CC =/usr/local/arm/2.95.3/bin/arm-linux-gcc”(交叉编译器所在路径)make(生成gdbserver在当前目录下)检查编译完的gdbserver是否是for arm平台:执行file gdbserver是否看到“ELF 32-bit LSB executable, ARM, version 1, dynamically linked (uses shared libs), for GNU/Linux 2.0.0, not stripped”4.把gdbserver烧到arm板上运行minicom在shell下执行:./gdbserver /dev/ttyS1 app -display :0 &PC机shell下执行:./arm-linux-gdb -b 38400 app握手:target remote /dev/ttyS0握手成功后c,开始调试。
注:ttyS1为目标机上的gdbserver和pc机上的arm-linux-gdb 通讯端口;ttyS0为控制台端口。
问题收集:1.出现“No symbol table is e the "file" command.”表示编译app应用程序时没加-g调试信息选项导致无法load符号表。
Eclipse-cdt配合gdbserver进⾏arm程序远程调试下中,介绍了如何编译、运⾏arm-linux-gdb 和 gdbserver,这⼀篇中介绍怎样结合Eclipse-cdt进⾏图形化编译调试⾸先当然是使⽤CDT创建项⽬并添加源⽂件。
1. 在左侧 Project Explorer 的项⽬名上点右键->Properties 进⼊项⽬属性设置2. 选择 C/C++ Build->Settings 在Tool Settings中,将Toolchain修改为arm版本GCC C Compiler :arm-linux-gccGCC C Linker : arm-linux-gccGCC C Assembler :arm-linux-ar其他选项默认就好,有需要⾃⼰修改3. [可选]Build Steps 这⾥可以填些编译步骤,我这⾥希望编译后⾃动将程序拷贝到tftpd的⽬录以⽅便arm端直接下载那么就在Post-build steps -> Command: 中填写cp ipcam /tftpboot编译部分修改完,接下来是调试部分1. 选中项⽬->菜单栏 ”Run“->Debug Configurations…2. 双击C/C++ Applecation 新建⼀个配置,Eclipse会根据当前选择的项⽬初始化⼤部分配置,这⾥只需修改Debugger配置页3. 选择进⼊Debugger配置页Debugger:选择gdbserver DebuggerDebugger Options:GDB Debugger 这项,如果上⼀篇中编译出的的arm-linux-gdb拷贝到PATH的⽬录,或者将arm-linux-gdb的⽬录加⼊到PATH,那么这⾥直接填arm-linux-gdb就可以了,否则浏览⽬录选择带路径的命令Shared Libraries这项,可以添加库路径,⽐如调试过程中要步⼊外部函数,就必须在这⾥给出带调试信息的库⽂件路径,否则会找不到该函数的定义Connection这项是关键:Type选 TCP,Host name or IP address填arm端的ip,端⼝号默认即可,这个端⼝号将在arm端运⾏gdbserver时填写4. 所有配置完成,点Apple 再关掉配置页开始调试1. 在arm端运⾏程序# tftp -g -r ipcam 192.168.1.100# gdbserver 192.168.1.100:10000 ipcam192.168.1.100是主机ip 10000是之前设定的端⼝2. 在Eclipse开始调试。
Linux应⽤调试使⽤gdb和gdbserver命令详解1.gdb和gdbserver调试原理通过linux虚拟机⾥的gdb,来向开发板⾥的gdbserver发送命令,⽐如设置断点,运⾏setp等,然后开发板上的gdbserver收到命令后,便会执⾏应⽤程序做相应的动作,来实现调试的功能和之前学的裸板GDB调试⼀样,只不过之前学的是在win下的,本次是在linux⾥的gdb1.1同样,它们都会需要⼀个带调试信息的编译⽂件.通过Makefile⾥的arm-linux-gcc -g 来的, -g:表⽰编译⽂件⾥包含gdb调试信息1.2为什么需要调试信息的编译⽂件?⽐如读开发板的应⽤程序⾥的变量a:⾸先gdb通过应⽤程序的带调试信息的编译⽂件,来找出变量a存的地址位置然后将地址发送给开发板⾥的gdbserver,来读出a地址的值2.安装gdb和gdbserver2.1在虚拟机上安装GDB: # tar xjf gdb-7.4.tar.bz2 //解压# cd gdb-7.4/ //进⼊gdb-7.4⽬录#./configure --target=arm-linux//GDB需要在pc本机⾥运⾏,并调试开发板⾥的应⽤程序,所以--target设为arm-linux#make //编译#mkdir tmp#make install prefix=$PWD/tmp //安装到./tmp⽬录下sudo cp tmp/bin/arm-linux-gdb /bin/ //复制到/bin⽬录下/bin/arm-linux-gdb -v //-v: 确定⼀下gdb的版本VID,是否是7.42.2 在开发板上安装GDBServer:cd gdb/gdbserver/ //在gdb-7.4⽬录下输⼊./configure --target=arm-linux --host=arm-linux //设GDBServer的⼯作环境make //编译出现以下错误:指在linux-arm-low.c⾥,没有找到PTRACE_GETSIGINFO 定义2.3 解决:1)#echo $PATH //来查看PATH环境变量找到编译器gcc位于/work/tools/gcc-3.4.5-glibc-2.3.6/bin2)#cd /work/tools/gcc-3.4.5-glibc-2.3.6/ # grep "PTRACE_GETSIGINFO" * -nR在gcc根⽬录下,搜索到在linux/ptrace.h中定义:3)#vi linux-arm-low.c添加: #define PTRACE_GETSIGINFO 0x42024)最后重新make,⽣成gdbserver命令⽂件然后将gdbserver命令⽂件,放⼊我们开发板的根⽬录/bin中,便能使⽤了cp gdbserver /nfs_root/bin/ //nfs_root:开发板的nfs系统根⽬录3.测试程序如下(test_debug.c)#include <stdio.h>void C(int *p){ *p = 0x12;}void B(int *p){ C(p);}void A(int *p){ B(p);}void A2(int *p){ C(p);}int main(int argc, char **argv){ int a; int *p = NULL; A2(&a); // A2 > C printf("a = 0x%x\n", a); A(p); // A > B > C return 0;}其中A2(&a)会调⽤A2()->C(),然后将a赋值为0x12.A(p)会调⽤A()->B()->C(),由于p是个空指针,这⾥将会出错.接下来,我们便以这个应⽤程序为例.4.编译#arm-linux-gcc -g -o test_debug test_debug.c //-g:附带调试信息5.调试test_debug.c在开发板上:⾸先,需要让gdbserver建⽴本地服务器,以及要测试的哪个⽂件:#gdbserver 192.168.2.107:2345 ./test_debug//192.168.2.107:本地IP地址//2345:端⼝号,⽤来让gdb来连接⽤的//./test_debug:要测试的哪个⽂件在虚拟机上:#/bin/arm-linux-gdb ./test_debug // 启动gdb,指定调试⽂件为test_debug#target remote 192.168.2.107:2345 //与gdbserver建⽴连接5.1连接成功,便使⽤gdb命令来调试列出所有源代码break [file]:[row]打断点,⽐如:break test_debug.c:21 //在test_debug.c⽂件的第21⾏处打断点info br查看断点info file列出当前的⽂件,共享库。
qtcreator单步调试嵌入式arm程序的方法前言该方法配置步骤为:(1)安装gdb-multiarch。
(2)在qtcreator中配置gdb-multiarch。
(3)启动板子上的gdbserver。
(4)将qtcreator连接到板子上的gdbserver,启动单步调试。
1.安装gdb-multiarch使用“sudo apt-get install gdb-multiarch”命令安装gdb-multiarch。
安装完如图1所示。
图12.在qtcreator中配置gdb-multiarch在qtcreator中添加gdb-multiarch步骤如下。
在[工具]-[选项]中,在[Debuggers]页面中,添加gdb-multiarch,如图2和图3所示。
图2图3在[构建套件(kit)]页面中,添加gdb-multiarch对应的调试器,如图4所示。
图43.在板子上启动gdbserver将要调试的程序拷贝到板子上,如图5所示。
图5用如下指令,启动gdbserver。
gdbserver 172.24.119.123:8888 /tmp/only_only_test172.24.119.123是虚拟机的IP地址。
8888是选取的一个通信端口。
/tmp/only_only_test是板子上要调试的程序。
如图6所示。
图64.qtcreator连接gdbserver单步调试首先,确保虚拟机与板子能互相ping通,如图7所示。
图7然后,在虚拟机的qtcreator中,用Debug模式编译程序,如图8所示。
图8在虚拟机中的qtcreator中,点击[调试]-[开始调试]-[Attach to Running Debug Server...]。
参考图9进行设置。
图9设置中:✧本地执行档:虚拟机中待调试程序的存在位置。
✧Override server channel: IP地址为板子IP地址,端口号为gdbserver启动时指定的端口号。
gdb+gdbserver安装及调试(总结)Ubuntu下gdb+gdbserver安装及调试1、 gdb+gdbserver介绍1.1、说明远程调试(即gdb+gdbserver)环境由宿主机GDB和目标机调试stub共同构成,两者通过串口或TCP连接。
使用 GDB标准程串行协议协同工作,实现对目标机上的系统内核和上层应用的监控和调试功能。
调试stub是嵌入式系统中的一段代码,作为宿主机GDB和目标机调试程序间的一个媒介而存在。
就目前而言,嵌入式Linux系统中,主要有三种远程调试方法,分别适用于不同场合的调试工作:用ROM Monitor调试目标机程序、用KGDB调试系统内核和用gdbserver调试用户空间程序。
这三种调试方法的区别主要在于,目标机远程调试stub 的存在形式的不同,而其设计思路和实现方法则是大致相同的。
而我们最常用的是调试应用程序。
就是采用gdb+gdbserver的方式进行调试。
1.2、功能一般来说,GDB可以帮你办以下几件事:1、启动程序,可以按照用户自定义的要求随心所欲的运行程序。
2、可让被调试的程序在用户所指定的调置的断点处停住。
3、当程序被停住时,可以检查此时用户的程序中所发生的事。
1.3、优点在很多情况下,用户需要对一个应用程序进行反复调试,特别是复杂的程序。
采用GDB方法调试,由于嵌入式系统资源有限性,一般不能直接在目标系统上进行调试,所以通常采用gdb+gdbserver的方式进行调试。
2、安装包下载嵌入式Linux的GDB调试环境由宿主机host和目标机(开发板)target两部分组成,arm-linux-gdb安装运行于宿主机,gdbserver安装运行于目标机,但安装包只有一个,其中gdbserver是在宿主机编译成功后,将生成的elf二进制可执行文件拷贝到目标机。
一般Linux发行版中都有一个可以运行的GDB,但开发人员不能直接使用该发行版中的GDB来做远程调试,而要获取GDB的源代码包,针对arm 平台作一个简单配置,重新编译得到相应GDB。
gdbserver用法使用gdbserver进行调试的常见步骤如下:1. 在目标设备上启动gdbserver:通过命令行启动gdbserver,并指定绑定的IP和端口,例如:```$ gdbserver <ip:port> <e某ecutable>```这将在目标设备上开启一个gdbserver进程,并监听来自指定IP和端口的连接请求。
2.在主机上运行GDB:在主机上打开终端,使用GDB命令行工具连接到目标设备,例如:```$ gdb <e某ecutable>```3. 在GDB中设置连接到gdbserver:在GDB命令行中输入以下命令来连接到正在运行的gdbserver进程:```(gdb) target remote <ip:port>```4.设置断点和调试:一旦连接建立,您可以在GDB中设置断点,观察变量和执行程序。
例如:```(gdb) break <function_name>(gdb) run(gdb) print <variable_name>(gdb) step```5.分析和调试:使用GDB的各种命令和调试功能,如单步执行(step)、步入函数(step into)、跳出函数(step out)、打印变量(print)、查看栈帧(backtrace)等,对目标程序进行分析和调试。
此外,GDB还提供了一些附加功能来支持使用gdbserver进行远程调试,例如:- 多目标调试:允许同时调试多个目标设备或进程,只需在GDB中连接到不同的gdbserver实例即可。
- 远程文件传输:可以使用GDB的`file`命令来传输目标设备上的可执行文件和调试信息文件到主机上,方便在本地进行调试。
需要注意的是,使用gdbserver进行远程调试可能需要目标设备和主机之间的网络连接,同时也需要确保主机和目标设备上的可执行文件和调试符号文件的兼容性。
嵌入式中自己编译gdb和gdbserver工具目录一.序论 2二.开发环境说明 2三.编译gdb和gdbserver工具 2四.Gdbserver操作使用 5一.序论就目前而言,嵌入式Linux系统中,主要有三种远程调试方法,分别适用于不同场合的调试工作:用ROMMonitor调试目标机程序、用KGDB调试系统内核用gdbserver调试用户空间程序。
这三种调试方法的区别主要在于,目标机远程调试stub的存在形式的不同,而其设计思路和实现方法则是大致相同的。
而我们最常用的是调试应用程序。
就是采用gdb+gdbserver的方式进行调试。
在很多情况下,用户需要对一个应用程序进行反复调试,特别是复杂的程序。
采用GDB方法调试,由于嵌入式系统资源有限性,一般不能直接在目标系统上进行调试,通常采用gdb+gdbserver的方式进行调试。
Gdbserver在目标系统中运行,gdb则在宿主机上运行。
目标系统必须包括gdbserver程序,宿主机也必须安装gdb程序。
一般linux发行版中都有一个可以运行的gdb,但开发人员不能直接使用该发行版中的gdb来做远程调试,而要获取gdb的源代码包,针对arm平台作一个简单配置二.开发环境说明嵌入式中自己编译gdb和gdbserver工具,由自己亲自编译通过并可以正确运行使用。
所在环境是pc运行在red 9.0.硬件板子:at91rm9200,跑嵌入式linux-2.4.27.gcc为3.3.2,gdb和gdbservr源代码选用gdb- 5.2.1(先后试过gdb6.0, gdb6.4, gdb6.6三个版本,这三个没有成功,具体以后有时间再研究),可以到ftp:///gnu/gdb下载。
.三.编译gdb和gdbserver工具可以在根据下面一步一步做,也可以象我一样,做一个shell脚本文件,这样可以提高效率(可以在windows上先做好这个脚本,制作好后拷贝到pc的linux下,可能不能执行,要用:先执行dos2unix 脚本名将dos格式转化成linux认识的文件,然后再执行chmod 777 脚本名。
这样就可以直接执行这个脚本了)。
操作具体情况请看脚本里的注释,编译中,源代码中好像没有出现语法错误提示,如果有的话,也就是添加或取消包含.H文件。
#!/bin/sh#编译gdb#download from /gdb/old-releases/# tar jxf gdb-5.2.1.tar.bz2#文件的很多目录也许你还没有建立,跟我的电脑上不一致,则要自己建立起目录。
cd /usr/src/arm/gdb/gdb-5.2.1mkdir ../build-gdbcd ../build-gdb../gdb-5.2.1/configure --target=arm-linux --enable-shared --prefix=/usr/src/arm/gdb/build-gdb --without-x --disable-gdbtk --disable-tui --without-included-regex --without-included-gettext#具体说明请看相关附录makemake install#编译gdbserver gdb5.2.1版本mkdir ../build-gdbservercd ../build-gdbserverchmod +x ../gdb-5.2.1/gdb/gdbserver/configureCC=/usr/local/arm/3.3.2/bin/arm-linux-gcc ../gdb-5.2.1/gdb/gdbserver/configure arm-linux--without-included-regex --without-included-gettext#具体说明请看相关附录makecp -vf gdbreplay gdbserver /nfsshare/gdb具体说明附录:对应脚本里的两行编译配置:../gdb-5.2.1/configure --target=arm-linux--enable-shared --prefix=/usr/src/arm/gdb/build-gdb --without-x --disable-gdbtk --disable-tui--without-included-regex --without-included-gettext还有:CC=/usr/local/arm/3.3.2/bin/arm-linux-gcc ../gdb-5.2.1/gdb/gdbserver/configure arm-linux--without-included-regex --without-included-gettext上面两个配置,在我电脑如果书写成用\隔开的几行,这样不能运行,不知道为什么。
我一直还没有搞明白,不过这是小问题。
上面的配置一定要加对,否则编译有问题,或者编译好后,使用时有问题,如运行不起来,或者运行时不能设置断点,只能全速跑。
整个编译过程如果碰到这些问题:1.编译后,在板子上运行gdbserver后出现[root@AT91RM9200DK /usr]$gdbserver: error in loading shared libraries: libthread_db.so.1: cannot open shared object file: No such file or directory出现这个问题,是跟上面的两个配置有关,如只是简单的配置了如网上流行的说法target host prefix,没有其他选项了。
这样生成的gdbserver是要共享库的,目标文件在使用时要求有libthread_db.so.1共享库文件,可以尝试将gcc3.3.2(我自己使用的版本)交叉编译器下的这个文件拷贝到你的板子linux 下的/lib 或/tm/lib,或/usr/lib(具体不是很明白,我试过拷贝在/lib),但是有这个文件后,会导致这个文件要调用libc.so.6这个文件,这个文件又需要libc-2.3.2.so ,这些文件更换后,最后更多文件依赖。
原因是:我的根文件下面ramdisk解开后库文件的版本低,好像全是1.3.2版本的(在家没带板子),就是说libc-2.3.2.so,ld-2.3.2.so,还很多别的库文件都是1.0版本的。
其实这些库只是版本低,在原来的ramdisk里都有,但是提示找不到。
你上一步我也是跟综过的。
然而我用新的如gcc 3.3.2或3.4.1里面的库换掉后换掉后,如换成libc-2.3.2.so,ld-2.3.2.so,连根文件ramdisk启动不来,也就是说要改动init部分,也就意外重新做busybox部分,那工作量更大,然而我也做了busybox,发现新做的busybox做成ramdisk后,内核起不来,处在init过不去。
所以如果文件版本不一致的话,busybox和ramdisk不是自己作的话,上面这种动态编译gdbserver然后再在板子上加共享库,那是很难成功的。
上面这个原因,我没有搞定,如果有人知道原因,请提示我。
谢谢!2.为了解决问题,看了一篇老外的文章,说可以在编译gdbserver时,改动gdbserver下面的Makefie.in或configure后的Makefile,里面的LDFLAGS改成LDFLAGS= -static。
原始老外文章:[bgat@mars build-gdb] cd gdb/gdbserver[bgat@mars build-gdb] make CC=arm-linux-gcc[bgat@mars build-gdb] file gdbserver./gdbserver: ELF 32-bit LSB executable, ARM, version 1 (ARM), dynamically linked (uses shared libs), not strippedYou probably don't want your gdbserver to use shared libraries, unless your target environment supports them (and you want to prove that they actually work!). To save some hair, you'll probably want to build a statically-linked gdbserver instead, so that you can debug even if shared libraries are broken. To do that, edit the Makefile in gdb/gdbserver, and modify LDFLAGS:LDFLAGS = -staticThere may be other LDFLAGS flags already there, which you'll want to leave alone--- just add -static to the end of the list. In other cases, LDFLAGS may not exist at all; just add the above line somewhere near CFLAGS.Then, rebuild gdbserver:[bgat@mars build-gdb] make clean[bgat@mars build-gdb] make CC=arm-linux-gcc[bgat@mars build-gdb] file gdbservergdbserver: ELF 32-bit LSB executable, ARM, version 1 (ARM), statically linked, not stripped Run arm-linux-strip on the executable, if you want to shrink it down:[bgat@mars build-gdb] arm-linux-strip gdbserver[bgat@mars build-gdb] ls -l gdbserver-rwxrwxr-x 1 bgat bgat 249164 Aug 2 11:16 gdbserver我这样编译gdbserver后,gdbserver终于可以运行了,但是让我失望的是,gdbserver调试时程序不能设置断点,跑一次就完了。