版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/feilengcui008/article/details/51306894
(此文主要用来记录一些调试,性能测试与分析等工具的用法,备忘)
Linux下的追踪和性能统计
Linux内核提供的基础设施
- tarcepoints => 静态探测点
- kprobe => 内核态动态探测点(kernel/kprobe.c, example:sample/kprobe)
- uprobe => 用户态动态探测点(kernel/events/uprobe.c)
其最基本的用法我们可以写内核模块注入某个探测点的探针,做一些追踪与统计分析,
但通常会有更方便的框架以及其前端工具,比如下面将提到的ftrace与trace-cmd,
perf_events与perf, systemtap, 还有基于这些前端工具的工具perf-tools…
ftrace framework
1. 介绍
ftrace框架主要以debugfs中/sys/kernel/debug/trace文件系统的形式提供了静态和动态
追踪的接口,ftrace框架有命令行和图像化的前端工具trace-cmd 和 kernelshark。而且
提供了不同种类的tracer, 可以使用下面命令查看:
cat /sys/kernel/debug/trace/available_tracers
ftrace的核心代码位于kernel/trace目录下,ftrace.c注册了debugfs下的trace目录,
trace_kprobe.c和trace_uprobe.c提供了kprobe和uprobe的接口。除了kprobe和uprobe,
ftrace还提供了events支持,主要位于/kernel/sys/debug/trace/events, 主要包括
硬件事件,内核软件事件,以及静态tracepoints的事件。可以通过下面命令查看支持的事件:
cat /sys/kernel/debug/trace/available_events
2. 例子
(例子来源于内核源码Documentation/trace)
- 基于ftrace使用kprobe动态trace:
// 添加探针
echo 'p:myprobe do_sys_open dfd=%ax filename=%dx flags=%cx mode=+4($stack)' > /sys/kernel/debug/tracing/kprobe_events
echo 'r:myretprobe do_sys_open $retval' >> /sys/kernel/debug/tracing/kprobe_events
// 激活
echo 1 > /sys/kernel/debug/tracing/events/kprobes/myprobe/enable
echo 1 > /sys/kernel/debug/tracing/events/kprobes/myretprobe/enable
// 查看输出
cat /sys/kernel/debug/tracing/trace
// 关闭
echo 0 > /sys/kernel/debug/tracing/events/kprobes/myprobe/enable
echo 0 > /sys/kernel/debug/tracing/events/kprobes/myretprobe/enable
// 移除探针
echo -:myprobe >> kprobe_events
echo > /sys/kernel/debug/tracing/kprobe_events
- 基于ftrace使用uprobe动态trace(kernel/trace/trace_uprobe.c)
// 添加探针
echo 'p: /bin/bash:0x4245c0' > /sys/kernel/debug/tracing/uprobe_events
echo 'r: /bin/bash:0x4245c0' > /sys/kernel/debug/tracing/uprobe_events
// 激活
echo 1 > events/uprobes/enable
// 查看输出
cat /sys/kernel/debug/tracing/trace
// 关闭
echo 0 > events/uprobes/enable
// 移除
echo '-:bash_0x4245c0' >> /sys/kernel/debug/tracing/uprobe_events
echo > /sys/kernel/debug/tracing/uprobe_events
- 基于ftrace使用tracepoints静态events(kernel/trace/trace_events.c)
- 通常我们可以写内核模块给某个静态tracepoint添加探针
- 基于ftrace events
// 添加event
echo sched_wakeup >> /sys/kernel/debug/tracing/set_event
echo *:* > /sys/kernel/debug/tracing/set_event
echo 'irq:*' > /sys/kernel/debug/tracing/set_event
// 激活event
echo 1 > /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable
// 查看输出
cat /sys/kernel/debug/tracing/trace
// 移除event
echo '!sched_wakeup' >> /sys/kernel/debug/tracing/set_event
echo > /sys/kernel/debug/tracing/set_event
perf_events
1. 介绍
perf_events和对应的前端工具perf提供了硬件和软件层面的计数等性能分析。其源码位于
内核源码树tools/perf目录下。
2. 例子
systemtap
1. 介绍
2. 例子
perf-tools and flamegraph
1. 介绍
2. 例子
GDB常用调试命令和调试技巧
命令
- status
- info => 查看程序本身相关信息
- args => 打印参数
- breakpoints => 断点信息
- files => 进程的地址空间详细内容
- sharedlibrary => 加载的共享库
- frame => 栈帧
- line => 当前所在行
- locals => 当前栈帧中的变量
- registers => 寄存器信息
- stack => 栈信息
- source => 当前源码文件信息
- auxv => 进程属性
- address/symbol => symbol的地址/地址的symbol
- threads => 线程信息
- tracepoints => tracepoint信息
- vtbl => 某个类指针的虚函数表
- watchpoints => 显示watchpoints信息
- …
- show => 查看系统配置环境等信息
- environment => 环境变量
- endian => 大小端
- print => 打印格式的相关配置
- …
- info => 查看程序本身相关信息
- breakpoints
- awatch/watch => 为某个表达式设置watchpoint
- break => 设置断点
- clear => 清除断点
- catch => 当发生下列某个时间时stop
- assert
- catch
- fork
- exec
- signal
- syscall
- throw
- vfork
- delete => 删除
- breakpoints
- checkpoint
- tracepoints
-
data
- disassemble => 反汇编某段代码
- dump binary
- memory => 二进制形式dump内存
- value => 二进制形式dump值
- set => 修改gdb配置
-
stack
- backtrace/bt => 所有栈帧
- down/up => 下一帧/上一帧
- frame => 打印某一帧
技巧
- 设置watch points调试内存非法写等错误
- …
valgrind常用命令和技巧
命令
- –tool
- memcheck =>
- cachegrind =>
- callgrind =>
- helgrind =>
- –trace-children => 多进程
- –leak-check=no|summay|yes|full => 打印内存泄露信息
技巧
- 生成调用图
- 先用valgrind生成call.grind.out.xxx文件
- 生成dot文件: gprof2dot -f callgrind -n10 -s callgrind.out.xxx > out.dot
- 生成png: dot -Tpng out.dot -o out.png