用gdbserver调试共享库(改进版)

本文介绍了一种在嵌入式Linux环境下使用gdbserver调试共享库的方法。通过手动计算偏移量并加载符号文件,可以有效地进行调试。文章详细记录了在PC机上的调试步骤,并提供了用于计算偏移量的脚本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我在<嵌入式linux调试:用gdbserver调试共享库> 一文中介绍了用gdbserver调试共享库的方法,虽然可行,但是由于计算偏移量很麻烦,除了在非常必要的情况下,我们都很少使用它。昨天我们讨论了一 下,看能不能修改gdbserver/gdb来实现自动计算。理论上这是可行的,不过修改gdbserver和gdb之间的通信协议,我们不想搞得那么复 杂,最后决定用半自动的方式实现:用脚本计算偏移量,但要手工去增加符号文件。

本文以PC机为例演了整个过程,在ARM板上的调试方法类似:

在服务器端(或者目标板)上:运行gdbserver,并记住打印出来的PID,后面用它来获得进程的maps文件。

gdbserver localhost:2222 networkmanager &
Process networkmanager created; pid = 24753
Listening on port 2222

在客户端(或者主机端)上:运行gdb,加载可执行文件的符号文件,在主函数处设置断点,并执行到这里。gdbserver刚运行起来时,共享库还没有加载,所以要执行到main函数才能进行后面的操作。

lixianjing@localhost server>gdb
GNU gdb Red Hat Linux (6.3.0.0-1.122rh)
Copyright 2004 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 "i386-redhat-linux-gnu".
(gdb) target remote localhost:2222
Remote debugging using localhost:2222
0x00293840 in ?? ()
(gdb) symbol-file networkmanager
Reading symbols from /home/lixianjing/work/groupware/network-
anager/server/networkmanager...done.
(gdb) b main
Breakpoint 1 at 0x804a565: file main.c, line 16.
(gdb) c
Continuing.

Breakpoint 1, main (argc=Cannot access memory at address 0xa396940a
) at main.c:16
16      {

在客户端(或者主机端)上:用脚本计算共享库的偏移量,这里由于gdbserver和gdb在同一台机器上,所以直接取了maps文件的内容,如果是调试ARM版,要把maps文件从ARM板拷贝到主机上再运行。

./gen_add_symbol_file.sh /proc/24753/maps

...
add-symbol-file /home/lixianjing/work/pcemu/broncho/usr/local/lib/libgobject-2.0.so.0.1200.10 0x8fc140
Y
add-symbol-file /home/lixianjing/work/pcemu/broncho/usr/local/lib/libgmodule-2.0.so.0.1200.10 0x938d30
Y
add-symbol-file /home/lixianjing/work/pcemu/broncho/usr/local/lib/libbasecommon.so.0.0.0 0xad9680
Y
add-symbol-file /home/lixianjing/work/pcemu/broncho/usr/local/lib/libglib-2.0.so.0.1200.10 0xb652c0
Y
add-symbol-file /home/lixianjing/work/pcemu/broncho/usr/local/lib/libdbus-1.so.3.2.0 0xc34b20
Y
add-symbol-file /home/lixianjing/work/pcemu/broncho/usr/local/lib/libdbus-glib-1.so.2.0.0 0xdeaab0

在客户端(或者主机端)上: 用前面生成的add-symbol-file加载共享库符号文件到指定的偏移量,然后设置断点,并进入正常调试。

add-symbol-file /home/lixianjing/work/pcemu/broncho/usr/local/lib/libgobject-2.0.so.0.1200.10 0x8fc140
Y
add-symbol-file /home/lixianjing/work/pcemu/broncho/usr/local/lib/libgmodule-2.0.so.0.1200.10 0x938d30
Y
add-symbol-file /home/lixianjing/work/pcemu/broncho/usr/local/lib/libbasecommon.so.0.0.0 0xad9680
Y
add-symbol-file /home/lixianjing/work/pcemu/broncho/usr/local/lib/libglib-2.0.so.0.1200.10 0xb652c0
Y
add-symbol-file /home/lixianjing/work/pcemu/broncho/usr/local/lib/libdbus-1.so.3.2.0 0xc34b20
Y
add-symbol-file /home/lixianjing/work/pcemu/broncho/usr/local/lib/libdbus-glib-1.so.2.0.0 0xdeaab0

(gdb) b g_main_loop_new
Breakpoint 2 at 0xb84ae4: file ../.././glib/gmain.c, line 2756.
(gdb) c
Continuing.

Breakpoint 2, 0x00b84ae4 in IA__g_main_loop_new (context=0x0, is_running=0) at ../.././glib/gmain.c:2756
2756    {


脚本文件gen_add_symbol_file.sh的内容为(对于ARM,objdump要换成对应的ARM版工具arm-linux-objdump):

#!/bin/bash
#Copyright (c) 2007 Li XianJing <xianjimli@hotmail.com>

if [ "$1" = "" ]
Then
    echo 
"usage: " $0 " [maps file]"
    
exit 1
Fi

grep r-xp $1 |grep /.so >all_so.tmp.log

awk 
'BEGIN{i=0} {print i " " strtonum("0x"substr($1, 0, 8)) " " $6; i++}' 
all_so
.tmp.log >baseaddr_so.tmp.log
awk 
'{system("objdump -h " $3 "| grep text");}' baseaddr_so.tmp.log |
awk 
'BEGIN{i=0}{print i " " strtonum("0x" $4); i++}' >offset.tmp.log

join offset.tmp.log baseaddr_so.tmp.log >offset_baseaddr_so.tmp.log

awk 
'{printf("add-symbol-file %s 0x%x y ", $4, $2 + $3)}' offset_baseaddr_so.tmp.log

rm 
-*.tmp.log



一直没有找到比较完美的方法,若哪位高手知道,请不吝赐教。


from http://blog.chinaunix.net/u1/43721/showart_386371.html

<think>好的,我现在需要帮助用户了解如何配置GDBServer进行调试。根据用户提供的引用资料,我需要整理出一个清晰的步骤指南。首先,我得回顾用户提供的四个引用内容,确保覆盖所有关键点。 引用1提到在服务器上运行gdb并检查架构,这可能涉及到确保目标平台和宿主机架构兼容。引用2和3讨论了远程调试的两种方式,其中使用gdbserver是重点,并指出需要针对ARM平台重新编译gdb。引用4详细描述了网络配置、权限设置和调试启动的具体命令。这些步骤需要整合成一个连贯的流程。 首先,用户需要安装gdbserver在目标板上,同时宿主机安装交叉编译的gdb。然后配置网络,确保两者可以通信。接着,编译应用程序时加入调试信息,复制到目标板并赋予执行权限。启动gdbserver监听端口,宿主机连接并进行调试。可能还需要处理不同架构的情况,比如ARM平台需要特定版本的gdb,如引用3所述。 需要注意用户可能的误区,比如直接使用系统自带的gdb而非交叉编译版本,或者网络配置不正确导致连接失败。此外,权限问题也是常见错误,比如没有给程序添加可执行权限。 最后,生成相关问题时要围绕配置步骤、常见问题、优化方法和应用场景展开,帮助用户深入理解。</think>### GDBServer调试配置方法详解 #### **一、环境准备** 1. **目标板(开发板/嵌入式设备)** - 安装gdbserver:若系统未预装,需交叉编译gdbserver并上传至设备 示例命令:`gdbserver --version` 验证是否安装成功[^3] - 网络连通性:确保设备与宿主机IP互通(可通过`ping`命令测试)[^4] 2. **宿主机(调试用电脑)** - 安装交叉编译工具链:生成与目标平台匹配的gdb(如ARM平台需`arm-linux-gnueabihf-gdb`) 编译参数示例:`./configure --target=arm-linux --prefix=/opt/arm-gdb`[^3] - 验证工具链:`arm-linux-gnueabihf-gdb -v` 查看版本信息 #### **二、调试流程** 1. **编译带调试信息的程序** ```bash arm-linux-gnueabihf-gcc -g -o hello_world hello_world.c # -g参数保留符号表 ``` ▸ 关键点:必须使用与目标板匹配的交叉编译器 2. **部署到目标板** ```bash scp hello_world root@192.168.1.100:/root # 假设目标板IP为192.168.1.100 ssh root@192.168.1.100 chmod +x /root/hello_world # 添加可执行权限 ``` 3. **启动gdbserver** ```bash gdbserver :10000 ./hello_world # 监听10000端口 ``` ▸ 输出提示:`Listening on port 10000`表示服务已就绪 4. **宿主机连接调试** ```bash arm-linux-gnueabihf-gdb ./hello_world (gdb) target remote 192.168.1.100:10000 # 建立远程连接 (gdb) b main # 设置断点 (gdb) continue # 开始执行 ``` #### **三、调试技巧** 1. **多架构支持验证** ```bash (gdb) show architecture # 查看当前调试架构[^1] set architecture armv7 # 手动指定架构 ``` 2. **文件传输优化** - 使用`gdbserver --attach`附加到正在运行的进程 - 通过`nfs`共享目录避免重复传输 3. **断点高级用法** ```bash (gdb) watch variable_name # 数据断点 (gdb) catch throw # 捕获异常 ``` #### **四、常见问题处理** | 问题现象 | 解决方案 | |---------|----------| | 连接超时 | 检查防火墙设置:`iptables -L` | | 架构不匹配 | 重新编译gdb时指定`--target=armv5te` | | 符号缺失 | 确认编译时使用`-g`参数且未执行strip操作 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值