理论知识
调试过程都是 这样子的 : 让核心停下来,查询信息,让核心继续运行
我们看一下 kgdb 是怎么做的
kgdb:
让核心停下来:
1. linux启动前期会自动进入kgdb
或
2. linux启动完成,挂载了procfs,用echo g > /proc/sysrq-trigger 来进入 kgdb
查询信息
1. bash#gdb vmlinx
2. gdb>target remote /dev/ttyS0
3. gdb>set remotebaud 115200
4. gdb>bt
6. gdb>b free_initmem
7. gdb>c
继续运行
参考 查询信息 中的 "7. gdb>c"
kgdb需要配置才能编入 vmlinux,kgdb是芯片相关的,因为需要操作串口,(也可以通过网口?)
1.linux配置
内核在3.x中已经默认自带KDB,CONFIG_KGDB
2.内核参数
kgdboc=ttyS0,115200
kgdbwait
3.gdb配置
set remotebaud 115200
target remote /dev/ttyS0
4.开启gdb
4.1启动过程中开启
4.2手动开启echo g > /proc/sysrq-trigger
kgdb/gdb 是 服务器/客户端架构,kgdb是一个gdb server
kgdb 的主体 是一段 循环代码, 在 linux 发生 某种异常(TODO)的时候进入,然后就开始死循环等待客户端接入
KGDB与linux(不包括KGDB的部分)的互斥
对核心的争抢
当内核正常运行的时候,kgdb(server) 其实是不存在的
因为可以说server能响应的时候就是跑到kgdb异常的时候,当正常运行的时候server不能响应
因为server和kgdb要争抢同一个cpu,是互斥的,不可能同时存在
但是状态信息是可以在的,因为都在内存里,内存不断电
只需要将内核要反馈给gdb的信息提前放在内存里,然后交由kgdb给gdb(用户)
对串口的争抢
KGDB和linux使用同一个串口是可以的
因为kdgb和linux是互斥的,不可能同时访问串口寄存器
如果既想做控制台使用又想同时作为 gdb 通信的载体,两者之间会存在干扰
可以从以下 site 下载一个串口多路复用的软件 agent-proxy,编译,执行。
该软件单独使用也可替代 Minicom 的功能。解压之后可按如下方式运行该软件:
[root@Kylin ~]# ./agent-proxy 5550^5551 0 /dev/ttyUSB0,115200 -s003
关于该软件的原理和各个参数的意义可查看里面的 README 文件。开启一个终端执行以下命令:
[root@Kylin ~]# telnet localhost 5550
连上之后即可当作串口控制台使用
之前的串口 可以用做 kgdb 的输出
互斥方法
互斥不是天然的,在进入KGDB所在的异常后要进行同步?
KGDB现场与断点现场的矛盾
矛盾
kgdb进入断点之后,pc在哪里?在断点处还是kgdb的异常循环中?
如果在断点处,怎么与gdb通信?
如果在kgdb异常循环中,怎么查询到正确的pc寄存器和堆栈信息
解决方案?
也就是应该有两个现场:断点现场及kgdb现场
现实所在的现场是kgdb现场,但是我们要的是断点现场
所以我们在进kgdb的时候必须把断点现场保存,以供gdb查询
软件调试离不开cpu、操作系统、编译器和gdb等调试软件的帮助。
cpu
决定了什么指令本身会产生中断。
操作系统
帮助我们收集被调试程序的所有信息。
编译器
产生调试信息。
gdb
完成调试者和系统的交互工作。
kgdb调试架构中
kgdb完成的工作是收集信息
gdb完成工作是调试者和系统的交互
KGDB调试实战
Console: switching to colour frame buffer device 60x34
fb0: s3cfb frame buffer device
s3c6400-uart.0: ttySAC0 at MMIO 0x7f005000 (irq = 69, base_baud = 0) is a S3C6400/10
printk: console [ttySAC0] enabled
s3c6400-uart.1: ttySAC1 at MMIO 0x7f005400 (irq = 70, base_baud = 0) is a S3C6400/10
s3c6400-uart.2: ttySAC2 at MMIO 0x7f005800 (irq = 71, base_baud = 0) is a S3C6400/10
s3c6400-uart.3: ttySAC3 at MMIO 0x7f005c00 (irq = 72, base_baud = 0) is a S3C6400/10
KGDB: Registered I/O driver kgdboc
KGDB: Waiting for connection from remote gdb...
# cat /sys/module/kgdboc/parameters/kgdboc
# echo ttySAC0 > /sys/module/kgdboc/parameters/kgdboc
KGDB: Registered I/O driver kgdboc
# cat /sys/module/kgdboc/parameters/kgdboc
ttySAC0
# echo g > /proc/sysrq-trigger
sysrq: DEBUG
KGDB: Entering KGDB
连接不上去
(gdb) target remote /dev/ttySAC0
/dev/ttySAC0: No such file or directory.