如何调试系统启动过程中systemd的代码

简介: 之前写过很多kernel的gdb debug, 其实用户态也是可以调试的, 只是在共享库的动态地址上不是很好处理, 最近同事有调试系统启动过程中systemd的需求, 简单研究了一下 其实qemu kvm打断点并不区别kernel还是用户态, 都是rip的值等于某个地址或者遇到断点指令了, 所以开机的时候把断点打到systemd的main上就可以了 但是其实另外一个问题是, 用户态的地

之前写过很多kernel的gdb debug, 其实用户态也是可以调试的, 只是在共享库的动态地址上不是很好处理, 最近同事有调试系统启动过程中systemd的需求, 简单研究了一下

其实qemu kvm打断点并不区别kernel还是用户态, 都是rip的值等于某个地址或者遇到断点指令了, 所以开机的时候把断点打到systemd的main上就可以了

但是其实另外一个问题是, 用户态的地址是很多进程共享的, 这时候有可能会另一个进程也跑到了这个地址, 所以断点就需要条件断点, 用进程的pid是一个好方法,

下面是简单得步骤
第一步, 开机暂停

sudo qemu-system-x86_64 -drive file=centos7.vhd,if=virtio -vnc :11 -enable-kvm  -serial mon:stdio -smp 8 -m 1024 -redir tcp:1011::22 -append "root=/dev/vda1 console=ttyS0 slub_debug=PFZ ro norandmaps" -kernel /home/shidao.ytt/alikernel/7u/arch/x86/boot/bzImage -s -S

kernel 参数 norandmaps很重要, 不然的话, 共享库的地址每次都不一样, 加了这个参数, 每次共享库的地址都是一样的, 就不用考虑共享库动态地址的问题了

第二步, 连接qemu, 打断点到systemd的main

/usr/bin/gdb vmlinux -ex 'target remote :1234' -ex 'thb start_kernel' -ex c

(gdb) add-symbol-file /usr/lib/debug/usr/lib/systemd/systemd.debug 0x0000555555573b60

这里说明一下, 因为要调试guest的systemd代码, 所以要在物理机上安装guest的systemd的debuginfo, 这个很好处理, 去centos下载debuginfo rpm安装就可以了

后面的地址0x0000555555573b60是systemd映射到进程代码段的加载地址, 这个地址如何获得, 开机一次, 去查看pid 1进程的vm映射空间就可以了, 简单一点就是gdb -p 1, info files就可以了

(gdb) thbreak *0x5555555752c0 if $lx_current().pid == 1
Hardware assisted breakpoint 2 at 0x5555555752c0: file src/core/main.c, line 1244.

简单说明, 因为systemd进程都还没起来, 所以是没有这个地址的, 所以一定需要用hardware breakpoint, 后面是条件判断, 只有pid为1的时候生效, 这个就是断点打到具体进程的利器了

c
接着跑
![image.png](http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/f0b46477c660776e64219e06c60084f9.png)

只要打断点的时候加入pid的条件限制, 就可以打到任意的进程了

目录
相关文章
|
监控 Shell Linux
systemd调试
systemd调试,参考https://freedesktop.org/wiki/Software/systemd/Debugging/
1889 0
|
监控 Unix Linux
|
监控 Unix Linux
cpu相关指标(top、uptime、vmstat、mpstat、sar、pidstat、ps、dstat、perf、tcpdump、lscpu)等常见使用方法(二)
cpu相关指标(top、uptime、vmstat、mpstat、sar、pidstat、ps、dstat、perf、tcpdump、lscpu)等常见使用方法
385 0
|
存储 算法 Java
QT中的线程池的介绍和使用
QT中的线程池的介绍和使用
370 0
|
缓存 JavaScript 前端开发
《Webpack5 核心原理与应用实践》学习笔记-> 构建npm包
《Webpack5 核心原理与应用实践》学习笔记-> 构建npm包
183 0
|
网络协议 Docker 容器
Docker的4种网络模式
我们在使用docker run创建Docker容器时,可以用--net选项指定容器的网络模式,Docker有以下4种网络模式: · host模式,使用--net=host指定。
8401 0
|
存储 机器学习/深度学习 人工智能
DeepSpeed + Kubernetes 如何轻松落地大规模分布式训练
DeepSpeed + Kubernetes 如何轻松落地大规模分布式训练
|
SQL 数据库连接 数据库
Gorm学习(四)基础:关联
要定义一个 belongs to 关系,数据库的表中必须存在外键。默认gorm使用(关联属性类型 + 主键)组成外键名,如上面的例子User + ID 组成UserID,UserID就作为Profile的外键。
1109 0
Gorm学习(四)基础:关联
|
缓存 算法 网络性能优化
Block Throttle
block throttle 是 block QoS 的重要组成部分,也是最早的一个 QoS,其功能是限制每个 cgroup 的 IOPS/BPS 上限。 ### Group Hiererchy 每个 blkdev 会为每个 block group 创建一个对应的 throttle group ![](https://ata2-img.oss-cn-zhangjiakou.aliyuncs.
2147 2
Block Throttle
|
JSON 测试技术 数据格式
自动化测试--如何使用YAML存放测试用例
YAML 是一种可读性非常高,与程序语言数据结构非常接近。同时具备丰富的表达能力和可扩展性,并且易于使用的数据标记语言。 YAML是 "YAML Ain't a Markup Language"(YAML不是一种标记语言)的递归缩写。
616 0