调试
Linux下调试
准备工作
安装并运行
C-sky DebugServer
, 下载链接url点击并连接设备,成功后如图所示
GDB介绍
GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具,由平头哥半导体完成对CSKY体系结构的移植。CK调试器的基本特性都与GNU GDB十分相似,一般来说,使用过GNU GDB的用户,在阅读完本文档,了解一些CSKY体系相关的调试特性之后,就能够很快熟练地使用CK调试器。
一般来说,CK调试器主要帮你完成下面四个方面的功能:
启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
可让被调试的程序在你所指定的调置的断点处停住。
当程序被停住时,可以检查此时你的程序中所发生的事。
动态的改变你程序的执行环境。
基本命令列表
| 指令名称 | 指令简介 | | ---------- | --------------------------------- | | Target | 连接目标调试系统 | | BreakPoint | 设置断点 | | WatchPoint | 设置观察点 | | clear / delete / disable / enable | 维护停止点(断点或观察点) | | continue / step /next | 恢复程序运行和单步调试 | | backtrace | 查看栈信息 | | list / disassemble | 查看源代码 | | examine | 查看内存 | | print | 查看变量值 | | info registers | 查看寄存器值 | | set | 修改寄存器值或内存值 | | dump / append | 将内存中的信息抽取出来,并以文件的形式保存下来 | | source | 脚本执行 命令 |
命令详解
target
target jtag jtag://127.0.0.1:1025
- 连接调试代理服务程序(和实际目标板连接调试),其中127.0.0.1是调试代理服务程序的所在计算机的ip地址,1025则是调试代理服务程序启动时的socket端口号,缺省值为1025
target remote 192.168.0.102:1025
- 连接CSKY实现的CKCORE体系结构的软件仿真器csky-qemu,其中192.168.0.102是qemu所在host机上的ip地址,1025则是socket端口号。请参考仿真器的用户手册。
BreakPoint
设置断点 用break(b) 或 hbreak(hb)命令来设置断点,其中hb为设置硬件断点,断点个数受硬件限制,用法如下:
b 程序代码断地址
b 函数名
b 文件名:行号
b 当前程序pc指针所在文件行号
b +offset
b –offset //在当前行号的前面或后面的offset行停住。offiset为自然数。
- 查看断点 可使用info命令,如下所示:(注:n表示断点号)
info breakpoints [n]
info break [n]
i b
WatchPoint
- 设置观察点。
观察点一般来观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,马上停住程序。
watch 表达式
- 查看观察点
info watchpoints //列出当前所设置了的所有观察点。
维护停止点
clear
如果没有参数,删除当前行所有的断点。
如果后面加行数,则删除该行所有的断点。
如果后面加函数名,则删除在函数首定义的所有断点。
delete [breakpoints] [range...]
删除指定的断点,breakpoints为断点号。如果不指定断点号,则表示删除所有的断点。range 表示断点号的范围(如:3-7 或者 3 4 5 6 7 用空格分隔)。其简写命令为d。
disable [breakpoints] [range...]
disable所指定的停止点,用法同delete,简写命令是dis.
enable [breakpoints] [range...]
enable所指定的停止点,用法同delete, 简写为en。
continue / step /next
当程序被停住了,可以使用continue继续运行,step,next等命令单步跟踪
continue或c
命令恢复程序的运行直到程序结束,或下一个断点到来。
step
backtrace
查看栈信息 backtrace(简写为bt)
(cskygdb) bt #0 func (n=250) at tst.c:6 #1 0x08048524 in main (argc=1, argv=0xbffff674) at tst.c:30 #2 0x400409ed in __libc_start_main () from /lib/libc.so.6
根据以上输出可以看出函数的调用栈信息:__libc_start_main --> main() --> func()
跳转到相应的堆栈位置
frame Id (简写为f ld)
(cskygdb) frame 2 ――跳到frame 2,即__libc_start_main的frame
查看当前栈的一些局部变量等信息
list / disassemble
- 显示c代码 list (简写为l) 显示当前行后面的源程序。一般是打印当前行的上5行和下5行。
- 显示汇编代码 disassemble
disassemble //显示当钱pc指针后的汇编代码 disassemble start_addr , end_addr //显示start_addr , end_addr之间的汇编代码 disassemble $pc , $pc+offset //显示pc后,共offset条汇编代码 disassemble func //显示该函数的汇编代码
examine
- 查看内存地址中的值
examine(简写是x),语法如下:
x/
< addr >
n 显示内存的长度。 f 显示格式。 u 表示从当前地址往后请求的字节数,默认是4个bytes,u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字节,g表示八字节。
addr 表示一个内存地址。
例如:
x/3uh 0x54320 表示,从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示三个单位,u表示按十六进制显示。
- 查看运行数据
print /
表达式 输出格式 CK调试器会根据变量的类型输出变量的值,也可以强制转换类型,参数如下 x 按十六进制格式显示变量。 d 按十进制格式显示变量。 u 按十六进制格式显示无符号整型。 o 按八进制格式显示变量。 t 按二进制格式显示变量。
a 按十六进制格式显示变量。 c 按字符格式显示变量。 f 按浮点数格式显示变量。
info registers
info registers
查看CPU通用寄存器和psr,epsr,pc,epc。
info registers <regname…>
查看具体的某个寄存器,regname表示具体寄存器名字,可以是多个。
set
- 设置变量或寄存器 (cskygdb) set x=4 (cskygdb) set $r0=4
dump / append
dump/append binary
将目标板上的指令和数据以二进制流保存到文件。
dump ihex
将目标板上的指令和数据以十六进制数据流保存到文件。
dump/append memory
将目标板上的内存的数据以二进制流保存到文件。
dump/append value
将目标板上的表达式的值以二进制流保存到文件。
source
- 执行脚本
source
其中 是脚本名称。
CDK下调试
开始调试
以CB2201开发板为例
准备工作
安装CDK
连接设备
创建工程
运行CDK,菜单Project->New IoT Project,选择方案。
编译烧写
调试前必须编译并烧写镜像到开发板。一次烧写后若没有代码修改,可反复调试。
调试脚本
路径:boards/cb2201/script/gdbinit
命令 | 说明 |
---|---|
reset | 进入调试前复位开发板 |
set $psr=0xc0000000 | 调试前硬件相关寄存器准备 |
#set $pc=0x10006000 | 设置启动点,reset已经重启设备,可不设置 |
set debug-in-rom on | 设置为XIP调试模式 |
hb main | 应用入口默认设置一个断点 |
进入调试模式
编译、烧写完成后,点击进入调试模式。默认会停在复位后的一个随机位置。
再点击,继续执行。若中间有暂停,可再点执行,最后会停止再app_main函数
断点、单步执行、查看变量等基本调试功能可参考CDK自带的帮助文档。
绑定调试
开发板烧写好镜像后如果没有连接调试离线运行,如发现设备运行逻辑错误,可继续进行绑定调试。但需要确保CDK工程代码和开发板镜像是一致的。
修改调试脚本
使用“#”注释掉boards/cb2201/script/gdbinit脚本中除了set debug-in-rom on的所有命令
进入调试模式
进入调试模式前,请确保调试脚本以正确修改,否则可能破坏现场。
崩溃现场定位
崩溃现场示例
CPU Exception: NO.2
r0: 00000000 r1: 00000000 r2: 00000061 r3: 00123457
r4: 60001ae4 r5: 00000000 r6: 06060606 r7: 07070707
r8: 00000000 r9: 09090909 r10: 10101010 r11: 11111111
r12: 6000b3a9 r13: 6000bbdd r14: 60008a64 r15: 1000f7d4
epsr: 80000140
epc : 1000f7da
常用异常号说明
异常号 | 说明 |
---|---|
1 | 未对齐访问异常 |
2 | 访问错误异常 |
3 | 保留 |
4 | 非法指令异常 |
5 | 特权违反异常 |
6 | 保留 |
7 | 断点异常,地址观测异常 |
8 | 不可恢复错误异常 |
恢复现场
根据上述异常信息转化为如下命令,注意epsr和epc需要改名使用
复制到gdbinit调试脚本中
set debug-in-rom on
set $r0=0x00000000
set $r1=0x00000000
set $r2=0x00000061
set $r3=0x00123457
set $r4=0x60001ae4
set $r5=0x00000000
set $r6=0x06060606
set $r7=0x07070707
set $r8=0x00000000
set $r9=0x09090909
set $r10=0x10101010
set $r11=0x11111111
set $r12=0x6000b3a9
set $r13=0x6000bbdd
set $r14=0x60008a64
set $r15=0x1000f7d4
set $psr=80000140
set $pc=0x1000f7da
进入调试模式
进入调试模式,执行脚本进行现场还原,使用CDK的Call Stack窗口可分析异常点的位置。
注意:如果调试完毕请恢复调试脚本,否则正常的调试流程会无法正常运行。