Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
gdb
rt-smart
RT-Smart 内核 GDB 调试方法
发布于 2021-05-27 10:26:19 浏览:2256
订阅该版
[tocm] 在开发的过程中,有时没有现成的图形化开发环境,想要进行调试时,需要使用 GDB 直接进行代码调试。本文档记录了以 RT-Thread `qemu-vexpress-a9` BSP 为例,使用 GDB 对 RT-Smart 进行代码调试的方法。 ## 准备 ### 开发配置 1. 在 `~/.bachrc` 配置好工具链地址,避免重复配置。 ``` export RTT_CC=gcc export RTT_EXEC_PATH=your_musleabi_toolchain_path/bin export RTT_CC_PREFIX=arm-linux-musleabi- export PATH=$PATH:$RTT_EXEC_PATH:$RTT_EXEC_PATH/../arm-linux-musleabi/bin ``` 2. 编译项目 - scons 编译工程(编译选项需要加 -g 参数,在 elf 中加入调试信息) - 生成 elf 格式的可执行文件 - 运行 `qemu-dbg.bat` 以调试模式启动 QEMU 模拟 ### 使用调试器 可以选择 arm-none-eabi-gdb 或者 gdb-multiarch 作为 gdb 服务端进行调试。 #### 使用 `gdb-multiarch` - 安装 `gdb-multiarch` 作为 gdb 服务端 - `gdb-multiarch rtthread.elf -ex "tar ext localhost:1234"` 连接到 QEMU 进行代码调试 #### 使用 `arm-none-eabi-gdb` - `arm-none-eabi-gdb rtthread.elf -ex "tar ext localhost:1234"` 连接到 QEMU 进行代码调试 #### 图形化界面 如果想要以 GUI 模式启动 gdb,可以在命令行中添加参数 `-tui`,如下面的命令: - `gdb-multiarch rtthread.elf -ex "tar ext localhost:1234" -tui` ## GDB 调试操作 ### 打开和关闭 | 命令 | 说明 | | ------------------------ | -------------- | | ctrl + d | 退出 GDB | | ctrl + a,松开后再按下 x | 退出 QEMU 调试 | ### 常用调试命令 | 命令 | 说明 | | ------- | ------------------------------------------------------------ | | r | Start debugged program | | c | Continue program being debugged | | n | Step program | | ni | 运行到下一条汇编指令,但是不进行 bl 跳转 | | s | Step program until it reaches a different source line | | si | 运行到下一条汇编指令,会跳转到下一条汇编执行,跟进 bl 命令 | | b | Set breakpoint at specified line or function | | display | Print value of expression EXP each time the program stops | | p | Print value of expression EXP,p /x exp :以 16 进制格式打印目标值 | | u | until 可以当做单次断点,使用 u *0x60000000 跳转到指定地址,u 指令后面跟想要跳转的位置 | | x | x 0x60000000 显示指定地址中的数值,相当于 dump 功能 | | q | 退出 gdb | 如果打 s、n 指令的话,必须要有源代码支持,如果没有源代码支持,只能打出 si、ni,这里 si ni 是针对反汇编指令来说的,如果有源代码的话就可以使用 s、n 指令。 ### 断点操作命令 | 命令 | 说明 | | -------------- | ------------------------------------ | | info b | 查询当前系统中断点命令,简写为 `i b` | | dis + 断点编号 | 使指定编号的断点 disable | | ena + 断点编号 | 使指定编号的断点 enable | | del + 断点编号 | 删除指定编号的断点 | ### 查看反汇编 1. 按下 ctrl + x 然后再按下 2 将会切换视图,例如汇编视图和寄存器视图 2. 按下 ctrl + x 然后再按下 1 将会聚焦选择其中一个视图 ### 调试示例 因为 RT-Smart 内核的加载地址与链接地址不一致,所以开始调试时,只能将调试断点打在 MMU 使能之后。 ![image-20210511101849251.png](https://oss-club.rt-thread.org/uploads/20210527/8c523537ac6d25aca592be650be4bea8.png) 打开图形化界面后,使用 si 指令进行单步调试: ![image-20210511102025773.png](https://oss-club.rt-thread.org/uploads/20210527/afd5e4a5991df33b88657113d76b7ae6.png) 如果想观察寄存器中数值的变化,可以切换到通用寄存器视角: ![image-20210511102234530.png](https://oss-club.rt-thread.org/uploads/20210527/ace36c2a12fe5fa92228d0786290cfaf.png) ## 常见问题 ### 加载地址与链接地址不一致 在 RT-Smart 调试的过程中,发现如果把断点打在 `_reset` 符号时,执行调试时无法停在指定的断点,这个问题的原因是程序的链接地址与加载地址不一致导致的。 RT-Smart 系统被链接在 `0xC0000000` 起始的地址上,但是加载地址为 `0x60000000`,这就导致了在 MMU 没有开启之前,GDB 尝试到 `0xC0000000` 的地址去找符号相应的代码,但是却无法找到。 解决的办法是在指定符号的链接地址上减去 PV_OFFSET,打断点的时候可以使用如下指令: ```shell b *((char *)_reset + 0xa0000000) ``` 以上命令即可将断点打在相应的物理地址上,此时打开 GDB 的代码调试窗口,还不能看到对应汇编源码,但是在浏览窗口可以看到反汇编代码,使用 si ni 指令查看汇编代码调试。 ![image-20210508172544752.png](https://oss-club.rt-thread.org/uploads/20210527/081bd8d83397f5db8ea8c651618831ff.png) 这里 `0xa0000000` 就是 PV_OFFSET。如果是想从物理地址获得虚拟地址,需要 P - (P-V) = V,如果是先要从虚拟地址获得物理地址,则需要 V + (P - V) = P。 这里的 PV_OFFSET 是 0xa0000000 而不是 0x60000000,是因为要用物理地址减去虚拟地址,而不是用虚拟地址减去物理地址. ### 栈溢出 栈内存被写穿的情况,由于线程栈太小,导致在函数较深调用时,导致栈溢出,破坏了系统中其他的数据结构。如果在调试的时候发现,某个变量在没有主动修改的时候突然发生改变,可以怀疑是否出现了栈溢出。 ### 反汇编 在代码调试以及查找错误时,有时会需要对 elf 进行反汇编做代码查看和对比的情况,此时需要使用工具链进行反汇编,命令如下: ```shell arm-linux-musleabi-objdump -S rtthread.elf > rtthread.S ```
3
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
我夏了夏天
Life isn't about finding yourself, life is about creating yourself.
文章
24
回答
1319
被采纳
20
关注TA
发私信
相关文章
1
VScode调试qemu-vexpress-a9工程,GDB出错,求助~
2
为什么 RT Smart 的工具链里 没有 gdb
3
RT-Thread Studio 调试gdb异常
4
在Start GDB Process Job期间发生了内部错误
5
vscode编译rtt工程报错
6
RT -SMART支持GDB调试吗?
7
GDB调试QEMU卡死
8
STUDIO版本是2.2.6,在这个环境下调试HPM6750,出现以下现象。
9
windows环境下在vscode中调试rt thread QEMU例程出错
10
rt-smart发布时间
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
rt_mq_消息队列_msg_queue
SFUD
keil_MDK
msh
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
812
个答案
177
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
2
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
2
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部