谈uftrace之前,先谈谈ftrace。

ftrace是一个用于调试linux内核的工具,它可以用于调试内核的调用栈,performance等。

ftrace的核心是在编译内核代码时,通过制定-pg标志,在函数的调用入口插入桩mcount函数,这样,就可以在桩函数里收集函数调用的信息。至于mcount函数怎么来的,我们可以后续再谈。

uftrace应用了类似的机制,只不过它是针对user space的应用程序。使用uftrace的前提是要通过 “-pg”或者“-finstrument-functions”这个编译标志对应用程序代码进行编译。

"-pg"指定编译器在函数入口插入对mcount()桩函数的调用,而“-finstrument-functions”会指定编译器在函数入口插入对__cyg_profile_func_enter()函数的调用,在函数返回时插入对__cyg_profile_func_exit()函数的调用。 uftrace对这2种情况都能支持。正常情况下,c库提供了对这些桩函数的定义,所以我们链接程序时,是可以链接到c库里面的桩函数定义。

同时呢,我们可以重新定义这些函数,让编译器链接到自定义的函数了。那么这里来了个问题,既然c库里面已经有同名的函数定义,链接器怎么知道该链接c库里面的定义还是自定义的函数?这里就用到了__attribute__((weak))这样一种属性,c库里面在定义桩函数时,在函数前面加了这个weak属性。链接器在链接这个函数符号时,如果只在c库里面找到了,那就链接到c库里面去。但是如果找到另外一个自定义的同名函数,且不是weak的,那么链接器就会优先链接到这个自定义的同名函数。

我们可以验证一把:

$ ldd test
linux-vdso.so.1 => (0x00007ffc379b7000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbd6d5fb000)
/lib64/ld-linux-x86-64.so.2 (0x00007fbd6d9c5000)
$ readelf -s /lib/x86_64-linux-gnu/libc.so.6 |grep mcount
113: 000000000010a350 91 FUNC GLOBAL DEFAULT 13 _mcount@@GLIBC_2.2.5
419: 0000000000143530 50 FUNC GLOBAL DEFAULT 13 _dl_mcount_wrapper_check@@GLIBC_2.2.5
1616: 0000000000143510 23 FUNC GLOBAL DEFAULT 13 _dl_mcount_wrapper@@GLIBC_2.2.5
2012: 000000000010a350 91 FUNC WEAK DEFAULT 13 mcount@@GLIBC_2.2.5

可以看到mcount()在libc.so.6里被定义为WEAK类型,这个验证了我们的猜想。

利用这个机制,我们可以玩很多花样,我们可以自己定义桩函数,然后链接到应用程序中,至于在桩函数里面干什么,那就海阔任鱼游了。

uftrace也利用了这点。

我们看看uftrace使用效果如何。

我们有下面这个小程序

void func_a(){

}

void func_b(){
func_a();
} int main(){
func_a();
func_b();
}

然后我们这样编译

$ gcc -pg -g test.c
$ ls
a.out test.c

运行

$ uftrace a.out
# DURATION TID FUNCTION
0.602 us [ 3211] | __monstartup();
0.604 us [ 3211] | __cxa_atexit();
[ 3211] | main() {
0.131 us [ 3211] | func_a();
[ 3211] | func_b() {
0.101 us [ 3211] | func_a();
0.406 us [ 3211] | } /* func_b */
1.113 us [ 3211] | } /* main */ $

这里面打印了函数调用栈和每个函数运行时间,这些信息对于我们的运行时分析是非常有用的,特别是有回调函数之类的代码。

当然uftrace还有更多有用的功能。这个后续再谈。

使用uftrace来debug应用程序的更多相关文章

  1. Python 【Debug排除程序故障】

    debug #排除程序故障 print()函数常和#号注释结合在一起用来debug 多行注释有两种快捷操作:1.在需要注释的多行代码块前后加一组三引号''' 2.选中代码后使用快捷键操作:Window ...

  2. eclipse远程debug Java程序

    使用Eclipse JPDA远程调试Java程序 本文将介绍使用Eclipse JPDA,在Eclipse的开发环境下对远程运行的Java程序进行调试操作. 请按以下步骤进行(本人已经在Eclipse ...

  3. debug PHP程序(xdebug、IntelliJ IDEA)

    之前写PHP程序的都是echo调试,今天感觉太麻烦了就想起研究一下IntelliJ IDEA如何调试PHP程序. 从网上查找了很多资料,大部分都提到在IDE里开启服务,一下就懵了,怎么启这么多服务呢. ...

  4. [VS2008] Debug版本程序发布后 由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题

    转自VC错误:http://www.vcerror.com/?p=59 问题描述: [VS2008] 版本程序发布后,运行程序弹出错误框: 由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序 ...

  5. debug : 应用程序无法正常启动(0xc000007b)

  6. 使用Dev C++调试(debug)程序

    在 "Tools" -> "Compiler Options" -> "Add following commands when calli ...

  7. 如何在其他电脑上运行VS2005编译的DEBUG版应用程序

    做项目的过程中,遇到这样的问题:在自己的电脑上用VS2005编译好的DEBUG版程序在其它的没有安装VS2005的电脑上没有办法运行,郁闷至极啊. 直 接拷贝文件后,错误信息如下:"This ...

  8. Debug程序无法运行解决

    说明:文章内容部分参考网络上的解决思路. 在没有安装Microsoft Visual Studio的系统上,Debug版本无法正常运行.这是由于缺少vs运行时库引起的. 以vs2005为例.开发机用v ...

  9. Python程序高效地调试

    现在我在debug python程序就只是简单在有可能错误的地方print出来看一下,不知道python有没像c++的一些IDE一样有单步调试这类的工具?或者说各位python大神一般是怎么debug ...

随机推荐

  1. 通过识别页面内容获得返回值判断后续执行(exists指令的用法)

    本案例主要用到airtest 的exists指令 从指令解释可以知道,当判断某图片不存在的时候,会返回false值 脚本思路即为如果返回值==false则执行A,!=fales则执行B 下图脚本思路, ...

  2. kivy file import

    from kivy.app import Appfrom kivy.uix.boxlayout import BoxLayoutfrom kivy.properties import ObjectPr ...

  3. Datagrip 快捷键和常用插件持续更新一集一些使用技巧

    快捷键 Ctrl+Enter:执行选中的SQL语句 Ctrl+Shift+左右箭头:调整列宽度(选中行,可以调整所有列的宽度) Ctrl+N / 双击Shift :全局搜索,点击可直接进入表 Ctrl ...

  4. sharding-JDBC学习笔记

    sharding-JDBC学习笔记 ShardingSphere ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC.Sharding-Pr ...

  5. Flink 1.10 正式发布!——与Blink集成完成,集成Hive,K8S

    Apache Flink社区宣布Flink 1.10.0正式发布! 本次Release版本修复1.2K个问题,对Flink作业的整体性能和稳定性做了重大改进,同时增加了对K8S,Python的支持. ...

  6. JavaScript所有函数和内置方法

    Number isFiniter() 检测传入的的数值是否在无穷大和无穷小之间(有限数字或者是可转换成有限数字)返回true,否则返回false.NaN返回false. isFinite(Number ...

  7. 视觉slam十四讲第七章课后习题7

    版权声明:本文为博主原创文章,转载请注明出处:http://www.cnblogs.com/newneul/p/8544369.html  7.题目要求:在ICP程序中,将空间点也作为优化变量考虑进来 ...

  8. throw throws区别

    1.throws是在方法上对一个方法进行声明,而不进行处理,向上传,谁调用谁处理: 格式: 权限修饰符 返回值类型 方法名(参数列表) throws Exception1,Exception2...{ ...

  9. 05-Spring02-AOP

    今日知识 1. AOP 2. AspectJ 3. JdbcTemplate AOP 1. AOP :Aspect Oriented Programming,意为面向切面编程,通过预编译方式和运行期动 ...

  10. SpringProfile轻松切换多环境配置文件

    在项目开发的过程中,我们难免会遇到开发.测试.生产等环境的切换,而各个环境的配置肯定是不同的.传统的办法是在项目打包的时候修改配置文件.但人为做的事情难免产生意外.Spring 为我们提供了一种多环境 ...