Edit online

GDB 调试

使用 JTAG 调试器连接 SOC,通过 DebugServer 提供的 gdb 调试接口来调试 dm-app。

调试动态模块需要两方面的信息:

  • 动态模块的符号表。

  • 动态模块的动态加载地址。

test_dm_lib 命令动态加载 hello.so 为例,描述整个调试过程。

保留 elf 调试信息

hello.mohello.so 原始 elf 文件中是有 debug 信息的,为了减少动态加载时的内存大小,把这些信息 strip 掉了。

所以在调试的时候,我们需要临时把 rtconfig.py 文件中这个 strip 动作 M_POST_ACTION 注释掉:
# M_POST_ACTION = M_STRIP + ' -R .hash $TARGET\n' + M_SIZE + ' $TARGET \n'

rtconfig.py 文件的路径:如果 aic-dm-apps 还在 luban-lite 目录当中,修改 luban-lite\bsp\artinchip\sys\dxxx\rtconfig.py ;如果 aic-dm-apps 已经从 luban-lite 拷贝出来, 修改 aic-dm-apps\tools\sdk\rtconfig.py

重新运行 scons --app=hello 或者 scons --lib=hello ,编译出来的 hello.mo 或者 hello.so elf 文件就是带有 debug 调试信息了。

计算动态加载地址

  1. 模块动态加载基地址
    动态模块的基地址会在加载函数 dlmodule_load() 加载完动态模块后,打印出当前模块的基地址。
    aic /> test_dm_lib              // '0x404f8c80' 即模块动态加载的基地址
    01-01 10:05:30 I/NO_TAG: Module: load /sdcard/hello.so to 0x404f8c80 succeed.
    [AIC-DM-APP] init!
    
  2. text 偏移
    通过 readelf 命令读取 elf 文件 .text 段的偏移:
    $ readelf -S hello/hello.so     // .text 的 Address 字段为 '0x550'
    Section Headers:
    [Nr] Name              Type             Address           Offset
        Size              EntSize          Flags  Link  Info  Align
        ...
    [7] .text             PROGBITS         000000000000055000000550
        000000000000008e  0000000000000000  AX       002
        ...
    
  3. gdb 加载符号表
    通过上两节的地址可以计算出 add-symbol-file hello.so xxx 的基地址:
    0x404f8c80+0x550=0x404F91D0

    可以通过 gdb 命令 add-symbol-file aic-dm-apps/hello/hello.so 0x404F91D0 来加载动态模块的符号表了。

  4. 完整 gdb 调试过程
    1. 在 gdb 中给系统函数 dlmodule_load() 打上断点:
      (gdb) b dlmodule_load
      
    2. 在串口 shell 中启动 test_dm_lib 测试:
      aic /> test_dm_lib
    3. gdb 中断在 dlmodule_load() 入口以后,输入 finish 命令让 dlmodule_load() 执行完成:
      (gdb) finish
    4. 记录串口 shell 上打印出来的模块动态加载基地址:
      aic /> test_dm_lib
      01-01 10:05:30 I/NO_TAG: Module: load /sdcard/hello.so to 0x404f8c80 succeed.
      [AIC-DM-APP] init!
    5. 通过 readelf 命令读取 elf 文件 .text 段的偏移:
      $ readelf -S hello/hello.so     // .text 的 Address 字段为 '0x550'
      Section Headers:
      [Nr] Name              Type             Address           Offset
          Size              EntSize          Flags  Link  Info  Align
          ...
      [ 7] .text             PROGBITS         0000000000000550  00000550
          000000000000008e  0000000000000000  AX       0     0     2
          ...
    6. 计算出 .text 的动态基地址
      0x404f8c80 + 0x550 = 0x404F91D0
    7. gdb 中加载 hello.so 符号表
      (gdb) add-symbol-file aic-dm-apps/hello/hello.so 0x404F91D0
    8. 操作 gdb 跳转到 hello.so 中的 my_thread_init() 函数后,可以像普通程序一样调试了
      (gdb) n
      30      func();
      (gdb) s
      my_thread_init () at hello/rtt_api_test.c:18
      18      tid = rt_thread_create("tMyTask", my_thread_entry, RT_NULL