调试

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 单步跟踪,如果有函数调用,他会进入该函数。进入函数的前提是,此函数被编译有debug信息。 next 或n 同样单步跟踪,如果有函数调用,他不会进入该函数。 stepi 或 si nexti 或 ni 单步跟踪一条机器指令。一条程序代码有可能由数条机器指令完成,stepi和nexti可以单步执行机器指令.

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

  • 查看运行数据 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窗口可分析异常点的位置。

注意:如果调试完毕请恢复调试脚本,否则正常的调试流程会无法正常运行。

results matching ""

    No results matching ""