kernel学习之ftrace环境搭设及使用(包括buildroot的使用)
来源:互联网 发布:网络电玩 编辑:程序博客网 时间:2024/04/30 02:36
Updated(2012/04/23):
刚看了elc2012的一篇关于使用ftrace调试性能问题的文章,也很不错
https://events.linuxfoundation.org/images/stories/pdf/lf_elc12_kobayashi.pdf
同时, 推荐下面这篇关于在ARM体系结构下使用Ftrace的文章
http://elinux.org/Ftrace_Function_Graph_ARM
以上支持ARM 的Ftrace的patch在commit:376cfa8730c08c0394d0aa1d4a80fd8c9971f323 中引入了kernel的mainline.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Ftrace是用来帮助调试kernel,了解kernel中的运行机制及performance相关问题而设计的基于debugfs的kernel内部的trace机制.
Ftrace的一些前提知识:
- mcount, 当gcc的-gp参数启用时,根据不同的系统及其compiler相关,会使得每次函数调用之前,先执行这个叫做mcount的操作.它由对应的profiling library提供.
参见:http://sourceware.org/binutils/docs/gprof/Implementation.html
搭建Ftrace调试环境
- 使用build root编译内核及相应的rootfs
这里需要注意, build root只支持ext2(目前还不支持ext3,ext4), 所以编译好的output/images/下的rootfs是ext2的.
如果用比较新的内核,编出的bzImage中不支持ext2的rootfs引导, 所以会出错.
这里就需要把rootfs.ext2的rootfs image转换成ext3的, 如下:
sudo dd if=/dev/zero of=disk.image bs=1024k count=4096
mkfs.ext3 -F -b 1024 disk.image 4096
sudo mount -o loop disk.image /mnt/disk_ext3/
sudo mount -o loop rootfs.ext2 /mnt/disk_ext2/
sudo cp -r /mnt/disk_ext2/* /mnt/disk_ext3/
sudo umount /mnt/disk_ext3 - 运行qemu
qemu -kernel ~/opensource/qemu/test_ftrace/bzImage \
-hda ~/opensource/qemu/test_ftrace/disk.ext3 \
-boot c \
-m 256 \
-append "root=/dev/sda rw" \
-localtime \
-no-reboot \
-name ftrace_linux \
-net nic -net user hostfwd=tcp:5555:23 - qemu启动完毕后,在target的shell中mount debugfsmount -t debugfs nodev /sys/kernel/debug则就能在/sys/kernel/debug/tracing找到各种调试接口了
下面是如何使用ftrace
- 查看当前内核支持什么样的ftrace,这依赖于你在编译内核时,打开了哪些ftrace支持.cat available_tracers
function_graph function nop ...
- 打开你想要的trace功能,并查看trace结果
[tracing]# echo [function] > current_tracer -> 这里[]中键入目前支持的ftrace方式[tracing]# cat current_tracer
- ftrace了一个很有用的ftrace_printk机制, 方便内核开发者使用它,来提供更快速轻量的log机制, 它会把log记在ftrace自己的ring buffer中, 并能够支持interrupt等场合下使用.
如,把trace_printk("read foo %d out of bar %p\n", bar->foo, bar);加入一个模块然后就可以通过读取cat /sys/kernel/debug/ftrace/trace 来查看相关log
- 如何打开/关闭trace
通过对/sys/kernel/debug/ftrace/tracing_on写入1/0来打开/关闭,这样可以提高性能, 隔绝不需要的干扰信息.
请注意,这里只是停止网trace ring buffer中写入log, 而不是关闭trace的整个机制, 它仍然不能降低ftrace带来的overhead.[tracing]# echo 0 > tracing_on[tracing]# echo function_graph > current_tracer[tracing]# echo 1 > tracing_on; run_test; echo 0 > tracing_on
- 提供接口给user space来利用ftrace提供的ring buffer, 从使得通过读取trace信息,能够知道user space和kernel space的交互及时间
参照<Debug the kernel using Ftrace - part2>, 给了一个完整的例子, 如何在开发中使用这个接口[tracing]# echo nop > current_tracer
[tracing]# echo test > trace_marker[tracing]# cat trace# tracer: nop## TASK-PID CPU# TIMESTAMP FUNCTION# | | | | | sh-848 [000] 1986.459489: tracing_mark_write:test在一些critical section- int trace_fd = -1;
- int marker_fd = -1;
- int main(int argc, char *argv)
- {
- char *debugfs;
- char path[256];
- [...]
- debugfs = find_debugfs();
- if (debugfs) {
- strcpy(path, debugfs);
- strcat(path,"/tracing/tracing_on");
- trace_fd = open(path, O_WRONLY);
- if (trace_fd >= 0)
- write(trace_fd, "1", 1);
- strcpy(path, debugfs);
- strcat(path,"/tracing/trace_marker");
- marker_fd = open(path, O_WRONLY);
其中find_debugfs()的代码是- if (marker_fd >= 0)
- write(marker_fd, "In critical area\n", 17);
- if (critical_function() < 0) {
- /* we failed! */
- if (trace_fd >= 0)
- write(trace_fd, "0", 1);
- }
- #define MAX_PATH 256
- #define _STR(x) #x
- #define STR(x) _STR(x)
- static const char *find_debugfs(void)
- {
- static char debugfs[MAX_PATH+1];
- static int debugfs_found;
- char type[100];
- FILE *fp;
- if (debugfs_found)
- return debugfs;
- if ((fp = fopen("/proc/mounts","r")) == NULL)
- return NULL;
- while (fscanf(fp, "%*s %"
- STR(MAX_PATH)
- "s %99s %*s %*d %*d\n",
- debugfs, type) == 2) {
- if (strcmp(type, "debugfs") == 0)
- break;
- }
- fclose(fp);
- if (strcmp(type, "debugfs") != 0)
- return NULL;
- debugfs_found = 1;
- return debugfs;
- }
以上是在user space测使用tracing_on接口,kernel端的开发也提供了tracing_on()和tracing_off()的接口达到同样的目地. - ftrace提供了接口更方便的调试kernel crash的问题
ftrace_dump_on_oops, 既可以在kernel boot parameters打开,也可以在通过ehco 1 > /proc/sys/kernel/ftrace_dump_on_oops
同时,可以控制dump信息的大小[tracing]# echo xx > buffer_size_kb
- ftrace提供了调试kernel stack使用情况的接口
需要在编译内核的时候打开CONFIG_STACK_TRACER.
它基于ftrace的function trace结构, 但是没有使用ring buffer. 所以没有引入额外的负担.
echo 1 > /proc/sys/kernel/stack_tracer_enabledcat stack_max_size
关于使用Ftrace的例子及一些ftrace结果的format,参见ftrace.txt
参考资料:
http://bec-systems.com/site/865/linux-tracing-tutorial
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=tree;f=Documentation/trace
http://lwn.net/Articles/322666/
http://lwn.net/Articles/365835/
http://lwn.net/Articles/366796/
http://lwn.net/Articles/370423/
http://elinux.org/Kernel_Trace_Systems- kernel学习之ftrace环境搭设及使用(包括buildroot的使用)
- kernel学习之ftrace环境搭设及使用(包括buildroot的使用)
- SpringMVC学习之环境搭设
- How to use ftrace to trace your kernel module(使用Ftrace跟踪你的内核模块)
- ftrace 的使用
- ftrace的使用
- ftrace的使用
- 使用ftrace的方法
- ftrace 的使用
- ftrace的使用
- ftrace的使用
- buildroot的使用简介
- go语言学习---环境搭设
- ftrace 使用
- ftrace 使用
- ftrace使用
- FTrace使用
- buildroot使用
- Python和C|C++的混编(一):Python调用C、C++---Boost库
- 贝叶斯分类器-基础知识
- oracle decode函数使用方法
- hibnernate 多对多 删除; 不是级联删除
- JAVA对字符型文件的读写操作(FileReader、FileWriter)
- kernel学习之ftrace环境搭设及使用(包括buildroot的使用)
- linux内核-进程调度
- java基础--日期
- C语言字符串格式化显示
- UICollectionView
- ajax 传递参数;省的找了 附带trim 方法; 注意url路径;
- mysql存储过程用游标解决返回的结果级并拼装字符
- 在windows下用cygwin和eclipse搭建cocos2dx的android开发环境
- Linux开发者需要知道的10个技巧--转自IBM developerworks