1. gdb 调试ld

  • 先准备代码, 我放在/root/musl/1.2.4下面
  • 启动gdb
    • 指定源码位置-d /root/musl/1.2.4
    • 这里我想调试/lib/ld-musl-x86_64.so.1, 而它的参数是/rl/sbin/apk -h
/lib/ld-musl-x86_64.so.1 --library-path /rebornlinux/lib:/rebornlinux/usr/lib /rl/usr/bin/gdb -d /root/musl/1.2.4 --args /lib/ld-musl-x86_64.so.1 /rl/sbin/apk -h
b load_library
r
n
p env_path
$6 = 0x7ffe10651e5a "/lib:/usr/lib:/isam/slot_default/lib"

musl libc的load是/lib/ld-musl-x86_64.so.1, 它同时也是c库.

~ # ls -lh /rl/lib
...
-rwxr-xr-x    1 root     root      602.6K Oct  6  2023 ld-musl-x86_64.so.1
lrwxrwxrwx    1 root     root          19 Aug 13 01:05 libc.musl-x86_64.so.1 -> ld-musl-x86_64.so.1
...

/lib/ld-musl-x86_64.so.1是一个动态链接的bin的interpreter:

~ # rl /rl/usr/bin/patchelf --print-interpreter /rl/sbin/apk
/lib/ld-musl-x86_64.so.1

直接启动/rl/sbin/apk的效果和用interpreter启动是一样的:

rl /rl/sbin/apk -h
rl /lib/ld-musl-x86_64.so.1 /rl/sbin/apk -h

1.1. /lib/ld-musl-x86_64.so.1 load .so的过程

  • 优先搜索环境变量LD_LIBRARY_PATH指定的路径
  • 如果有rpath, 搜索rpath路径
  • 如果没找到, 搜索/etc/ld-musl-x86_64.path指定的路径
  • 如果没有/etc/ld-musl-x86_64.path, 则默认从/lib:/usr/lib下面找

1.2. loader支持的选项

--list: ldd就是调用它
--library-path: 覆盖LD_LIBRARY_PATH
--preload: 覆盖LD_PRELOAD
--argv0: 设置arg0

1.3. 一些命令记录

LD_LIBRARY_PATH=/rebornlinux/lib:/rebornlinux/usr/lib /rebornlinux/usr/bin/patchelf --set-rpath /rebornlinux/lib:/rebornlinux/usr/lib /rebornlinux/sbin/apk
/rebornlinux/lib/ld-musl-x86_64.so.1 --library-path /rebornlinux/lib:/rebornlinux/usr/lib /rebornlinux/sbin/apk -h

2. gdb tui模式

tui模式下更像个ide调试界面, 信息更丰富.

#可以先gdb program core来启动, 在gdb里面用layout命令来显示源码 asm和reg窗口
#Ctrl + x,再按a:回到传统模式,即退出layout,回到执行layout之前的调试窗口
#Ctrl + x, o: 切换激活窗口, 切换到命令窗口可以上下翻历史命令


layout split
layout src
layout reg


#刷新窗口
refresh 或Ctrl + L

#上一条命令快捷键: Ctrl+p

3. gdb看所有线程的调用栈

(gdb) info threads
(gdb) thread apply all bt full

4. 远程调试app, 用gdbserver和gdb远程调试板子

板子上配好ip: 192.168.2.12

#直接带好参数
~ # gdbserver :9123 /isam/user/eoe_filter -n eth0 -t tap-fwd -E

我在mint上, 用sshfs mount了服务器的buildroot目录; 所以我在mint上就能操作:

export PATH=$PATH:~/work/share/buildroot73/output/host/opt/ext-toolchain/bin
#cd到被调试的app目录下
yingjieb@yingjieb-VirtualBox ~/work/share/buildroot73/output/build/isam-linux-target-apps-22ef847b216e5d579c016ed9dd9795d393b56001
#这个eoe_filter是带符号表的
#能自动找到sysroot:/home/yingjieb/work/share/buildroot73/output/host/opt/ext-toolchain/mips64-octeon-linux-gnu/sys-root/
Linux Mint 19.1 Tessa $ mips64-octeon-linux-gnu-gdb eoe_filter
#板子上的程序会停在__start, __start是lib32/ld.so.1的符号
(gdb) target remote 192.168.2.12:9123
(gdb) handle SIG42 nostop noprint
(gdb) set print pretty on
#先断点到这个函数:
(gdb) b openTapItf
#继续执行直到断点
(gdb) c
#结合代码, 我要看tap设备是否创建成功:
(gdb) b eoe_filter.c:116
#在另外一个窗口ip a能看到tap-fwd
(gdb) info locals
#再往下跟, 发现是子线程调用了exit(), 导致tap设备被注销了.
(gdb) next

5. 远程调试uboot, 用jtag做gdb server

cd /repo2/yingjieb/cavium/sdk31_508/usr/local/Cavium_Networks/OCTEON-SDK/tools/bin
//gdb调试elf文件
mipsisa64-octeon-elf-gdb /repo2/yingjieb/u-boot-octeon-sdk3.1/u-boot-octeon_fpxtb
//启动空的gdb后, 再加载elf文件
file /repo2/yingjieb/u-boot-octeon-sdk3.1/u-boot-octeon_fpxtb
//可以设置architecture, 如果直接加载elf文件则不用设置
set architecture mips:octeon3
//启动远程调试
target remote 135.251.9.60:30000
//使用monitor指令
monitor help
monitor B::break.set 0xc00a2ff8 /program
//查看程序地址?
info line eth_send
//设置程序参数
gdb --args prog args
set args --ddr0spd=fpxtbspd --ddr_clock_hz=667000000
b init_octeon3_ddr3_interface

6. 远程调试, over串口

在板子上:

board:
stty -F /dev/ttyS0 115200
stty -F /dev/ttyS0 460800
stty -F /dev/ttyS0 -a
( taskset 1 gdbserver /dev/ttyS0 ./isam_app useSTDIO) &

在服务器上:

ASBLX28:/repo/yingjieb/fdt063/sw/vobs/esam/build/reborn/buildroot-isam-reborn-cavium-fgltb/output/host/usr/bin
$ mips64-octeon-linux-gnu-gdb /repo/yingjieb/fdt063/sw/vobs/esam/build/fglt-b/OS/application/isam_app.nostrip
#这个135.251.199.198:2009是串口服务器地址
(gdb) target remote 135.251.199.198:2009
(gdb) set sysroot /repo/yingjieb/fdt063/sw/vobs/esam/build/reborn/buildroot-isam-reborn-cavium-fgltb/output/staging
(gdb) set remotetimeout 60
(gdb) handle SIG42 nostop noprint
(gdb) set print pretty on
(gdb) detach

7. gdb调试nand

target:

devmem 0x1070000000500 64 0
devmem 0x1070000000508 64 0
devmem 0x1070000000510 64 0
devmem 0x1070000000518 64 0
echo ttyS1 > /sys/module/kgdboc/parameters/kgdboc
echo g > /proc/sysrq-trigger
从kgdb切换到kdb, 盲敲$3#33

host:

mips64-octeon-linux-gnu-gdb vmlinux
target remote 135.251.199.198:2114
set print pretty on
set sysroot /repo/yingjieb/fdt063/sw/vobs/esam/build/reborn/buildroot-isam-reborn-cavium-fgltb/output/staging
set remotetimeout 20
detach
bt
c

8. gdb基本

8.1. 查看当前要执行的行

frame, 简写f

8.2. 临时变量

set $i="hello"

8.3. 自动显示变量, 每次c后或n后, 自动显示其值

display 变量名

8.4. 按结构体方式查看内存地址

p *(struct mtd_info *)0x80000000885dc018
(gdb) p ((struct txq *)0xffff8119f800)->elts_n

8.5. 显示内存内容

#从priv->data这个地址开始, 显示2048个单位(2048), 每个单位一个字节(b), 按16进制显示(x)
x/2048xb priv->data

8.6. 计算数值, 16进制显示

(gdb) p /x 0xffff90c8c430+1914*8
$7 = 0xffff90c90000

8.7. 指定显示格式

#有时候, gdb不能准确显示一个uint16_t类型的变量的值, 比如
(gdb) p nb_pkt_per_burst
$19 = 65568
#此时需要用x加FMT来看, 8xh是说显示8个, 安装16进制halfword显示
(gdb) x/8xh &nb_pkt_per_burst
0x9f0c36 <nb_pkt_per_burst>: 0x0020 0x0001 0x0000 0x0000 0x0000 0x0040 0x0000 0x0000
#如果知道这个变量是uint16_t, 下面的也可以; 相当于x/1dh
(gdb) x/dh &nb_pkt_per_burst
0x9f0c36 <nb_pkt_per_burst>: 32

8.8. 执行任意函数

(gdb) p system("nandtest -k -o0x0 -l0x20000 /dev/mtd6")
$1 = 1

8.9. 查看结构体定义

(gdb) ptype trx_sys_t

8.10. 汇编和C混合显示

(gdb) disassemble /m function
(gdb) disassemble /m lj_meta_lookup
(gdb) disassemble /m dp_netdev_input__

8.11. info命令族

#源码信息
info source
#当前局部变量
info locals
info files
info threads
info sharedlibrary
info signals
info line
info tasks
info variables
info symbol
info stack
info registers
#还有不少
help info

8.12. 加入libc符号表

#必须使/repo/yingjieb/glibc-2.16.0能够被板子访问到
gdb oflt.nostrip
set args useSTDIO
set print pretty on
set sysroot /repo/yingjieb/fdt063/sw/vobs/esam/build/reborn/buildroot-isam-reborn-cavium-fgltb/output/staging
#dir的意思是增加源文件的search path到gdb
dir /repo/yingjieb/glibc-2.16.0
dir /repo/yingjieb/glibc-2.16.0/nptl
dir /repo/yingjieb/glibc-ports-2.16.0
handle SIG42 nostop noprint
b cs_dpll_resetTest
b oak_spi_datatransfer
b board_commands.c:153
b fork.c:133
b do_system

8.13. 调试模块, 加载符号表

#加载ko符号表
/sys/module/spi_oak_island/sections # cat .text
0xffffffffc0002000
/sys/module/spi_oak_island/sections # cat .data
0xffffffffc0000000

(gdb) add-symbol-file /repo/yingjieb/fdt063/sw/vobs/esam/build/reborn/buildroot-isam-reborn-cavium-fgltb/output/build/isam-linux-drivers-custom/misc/spi-oak-island.ko 0xffffffffc0002000 -s .data 0xffffffffc000000

8.14. 查看地址处的代码

# source file and line number for an instruction address
info line *0x<target_addr>
# source lines around an instruction address
list *0x<target_addr>
# assembly instructions at an address
disas 0x<target_addr>, or
x/20i 0x<target_addr>

8.15. 显示内存布局

#显示所有内存section
info files
#比上面命令显示更全
maintenance info sections

results matching ""

    No results matching ""