gdb远程调试gdbserver挂起的程序

文章介绍了在何种情况下需要使用gdbserver进行远程调试,如生产环境无调试环境。详细讲解了gdbserver的工作模式,C/S架构以及连接方式,包括不同类型的连接指令和目标地址格式。还提供了一个实际案例,展示了如何通过gdb和gdbserver在不同主机间建立连接并进行调试操作。

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

  1. 前言
  2. 连接
  3. 连接
  4. 案例

前言

什么时候需要有gdbserver?

远程调试生产环境; 生产环境没有调试环境, 本地才有;
大佬远程调试有编译环境的环境; 不过这种很少;
被调试程序执行环境不支持gdb的特性; 或者环境不允许, 比如生产环境不好复现环境;

gdbserver能执行的一般也可以执行gdb, 一般都是操作系统, 只是不方便搭建环境而已, 或者不支持全部gdb特性;

C/S模式; 环境复现;

gdb需要复现gdbserver所在的执行环境; 也就是说需要一模一样; exe和其依赖的共享库都需要本地存在, 一模一样, 即ldd查看并打包下载;
为什么需要一模一样? 共享库地址空间等都需要一样? 不然地址空间有差异;

传输协议

有线串口和网络tcp/ip; 明文协议, 不建议上公网;

连接

简介

怎么连: 连接类型和类型之间的差异;
调试环境搭建: 符号信息,源代码,可执行文件,共享库, 连接和断开的指令;

连接类型

target remote ; target extended-remote两种; 一种是普通版; 一种是加强版; 加强版略, 仅介绍普通版本;

指令; extended-remote类型可自行查看;

  • 指定调试程序: gdb /path/to/file | gdb -ex 'file /path/to/file', 需要和gdbserver一致,且一般是带符号的;gdbserver connect_addr file | gdbserver connect_addr --attach pid;
  • 程序和正在执行的差异: gdb不支持attach, gdbserver支持选中; gdbserver CA file第一条指令暂停; gdbserver CA --attach pid可中止并加断点;
  • 连接: gdb执行target remote connect_addr; connect_addr对应gdbserver connect_addr ...中的connect_addr监听端口;
  • 执行: run普通模式不支持;
  • 退出: gdb exit之后gdbserver一起死亡;while 1会被杀死; 具体什么信号杀死的, 可自行测试;

连接

  • 串口: target remote /dev/ttyb

  • Unix域: target remote /tmp/gdb-socket0

  • TCP

target remote host:port
target remote [host]:port
target remote tcp:host:port
target remote tcp:[host]:port
target remote tcp4:host:port
target remote tcp6:host:port
target remote tcp6:[host]:port
  • udp

target remote udp:host:port
target remote udp:[host]:port
target remote udp4:host:port
target remote udp6:[host]:port
  • IO: target remote | command, command的输出作为gdb输入, gdb的输出作为command的输入;

案例

  • GDB

ch@vm:~/code/cfile/gdbserver$ ls
test.cpp
ch@vm:~/code/cfile/gdbserver$ cat test.cpp 
int main() {
   while(1);
}ch@vm:~/code/cfile/gdbserver$ 
ch@vm:~/code/cfile/gdbserver$ g++ test.cpp -g
ch@vm:~/code/cfile/gdbserver$ scp a.out 192.168.1.20:/home/ch/ch/cfile/test
a.out                                                                  100% 9032     3.5MB/s   00:00    
ch@vm:~/code/cfile/gdbserver$ gdb -q a.out
Reading symbols from a.out...done.
(gdb) target remote 192.168.1.20:8080
Remote debugging using 192.168.1.20:8080
warning: while parsing target description (at line 68): Vector "v8bf16" references undefined type "bfloat16"
warning: Could not load XML target description; ignoring
Reading /lib64/ld-linux-x86-64.so.2 from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
Reading /lib64/ld-linux-x86-64.so.2 from remote target...
Reading symbols from target:/lib64/ld-linux-x86-64.so.2...Reading /lib64/ef896a699bb1c2e4e231642b2e1688b2f1a61e.debug from remote target...
Reading /lib64/.debug/ef896a699bb1c2e4e231642b2e1688b2f1a61e.debug from remote target...
(no debugging symbols found)...done.
0x00007ffff7fe32b0 in ?? () from target:/lib64/ld-linux-x86-64.so.2
(gdb) b main
Breakpoint 1 at 0x5555554005fe: file test.cpp, line 2.
(gdb) c
Continuing.
Reading /lib/x86_64-linux-gnu/libc.so.6 from remote target...
BFD: warning: target:/lib/x86_64-linux-gnu/libc.so.6: unsupported GNU_PROPERTY_TYPE (5) type: 0xc0008002
Reading /lib/x86_64-linux-gnu/389d485a9793dbe873f0ea2c93e02efaa9aa3d.debug from remote target...
Reading /lib/x86_64-linux-gnu/.debug/389d485a9793dbe873f0ea2c93e02efaa9aa3d.debug from remote target...

Breakpoint 1, main () at test.cpp:2
2           while(1);
(gdb) q
A debugging session is active.

       Inferior 1 [process 211830] will be killed.

Quit anyway? (y or n) y
ch@vm:~/code/cfile/gdbserver$
  • gdbserver

ch@ch:~/ch/cfile/test$ ls
ch@ch:~/ch/cfile/test$ pwd
/home/ch/ch/cfile/test
ch@ch:~/ch/cfile/test$ gdbserver 0:8080 a.out 
Process /home/ch/ch/cfile/test/a.out created; pid = 211830
Listening on port 8080
Remote debugging from host 192.168.1.74, port 53562
ch@ch:~/ch/cfile/test$ 

可以看到是一次性连接;

### 如何使用 QEMU 调试汇编代码 #### 安装 QEMU 模拟器 为了能够运行和调试 ARM 架构下的汇编代码,首先需要安装 QEMU 模拟器。QEMU 是一种开源的机器模拟器和虚拟机程序,支持多种架构的仿真环境[^1]。 #### 编写与编译 ARM 汇编代码 在完成 QEMU 的安装之后,下一步是编写目标平台(如 ARM)上的汇编代码,并通过交叉工具链将其编译成可执行文件。例如,可以通过 `arm-linux-gnueabi` 工具链来构建适用于 ARM 平台的目标文件: ```makefile ARMGNU ?= arm-linux-gnueabi test.elf: test.o $(ARMGNU)-ld -Ttext 0x0 -o test.elf $^ %.o : %.S $(ARMGNU)-gcc -o $@ $< -g -c clean: rm *.o *.elf -f ``` 上述 Makefile 提供了一个简单的框架,用于将 `.S` 文件编译为目标对象文件以及最终链接为 ELF 可执行文件[^4]。 #### 启动 QEMU 并加载 GDB Stub 一旦生成了目标文件,就可以利用 QEMU 来启动该文件并进入调试模式。对于 ARM 环境而言,通常会采用如下命令行参数调用 QEMU: ```bash qemu-system-arm -M versatilepb -m 128M -kernel test.elf -s -S ``` 其中 `-s` 参数表示启用 gdbserver,默认监听于 TCP 端口 1234 上;而 `-S` 则暂停 CPU 执行直到 GDB 建立连接为止。 #### 使用 GDB 进行远程调试 当 QEMU 成功挂起等待调试时,可以打开另一个终端窗口并通过 GDB 接管控制权。具体步骤如下所示: 1. **启动 GDB**: 加载相应的符号表。 ```bash arm-linux-gnueabi-gdb test.elf ``` 2. **连接至 QEMU 实例**: 输入以下指令让本地实例化的 GDB 应用尝试接入由前面提到选项指定的服务端口中去。 ```gdb target remote localhost:1234 ``` 此时应该可以看到来自被调试进程内部状态反馈信息显示出来,从而允许进一步分析其行为表现情况[^2]。 另外值得注意的是如果想要从最初始阶段即 Linux Kernel 的第一条汇编码处就开始跟踪,则需额外注意一些细节处理方式[^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值