uftrace工具介绍

uftrace是一个追踪和分析C/C++程序的工具,其灵感来自于Linux kernelftrace框架(项目主页:https://github.com/namhyung/uftrace)。

(1)安装。
uftrace依赖于elfutils项目中的libelf,所以要首先安装libelf,而uftrace的安装则很简单:

# git clone https://github.com/namhyung/uftrace.git
# cd uftrace
# make
# make install

(2)使用。
以这个简单程序(test.cpp)为例:

#include <cstdio>

class A {
public:
        A() {printf("A is created\n");}
        ~A() {printf("A is destroyed\n");}
};

int main() {
        A a;
        return 0;
}

uftrace要求编译时指定-pg-finstrument-functions选项:

# g++ -pg test.cpp

编译成功后,通过uftrace工具可以对程序进行分析:

# uftrace a.out
A is created
A is destroyed
# DURATION    TID     FUNCTION
   4.051 us [ 8083] | __cxa_atexit();
            [ 8083] | main() {
            [ 8083] |   A::A() {
  13.340 us [ 8083] |     puts();
  17.321 us [ 8083] |   } /* A::A */
            [ 8083] |   A::~A() {
   1.815 us [ 8083] |     puts();
   4.679 us [ 8083] |   } /* A::~A */
  26.051 us [ 8083] | } /* main */

可以看到输出结果包含了程序的运行流程以及各个函数的执行时间。另外也可以使用-k选项追踪内核的相关函数:

# uftrace -k a.out
A is created
A is destroyed
# DURATION    TID     FUNCTION
   1.048 us [ 8091] | __cxa_atexit();
   0.978 us [ 8091] | sys_clock_gettime();
   0.768 us [ 8091] | main();
            [ 8091] | sys_clock_gettime() {
            [ 8091] |   A::A() {
   0.699 us [ 8091] |   } /* sys_clock_gettime */
            [ 8091] |   sys_clock_gettime() {
            [ 8091] |     puts() {
   0.768 us [ 8091] |     } /* sys_clock_gettime */
            [ 8091] |     sys_newfstat() {
   1.466 us [ 8091] |       smp_irq_work_interrupt();
   4.819 us [ 8091] |     } /* sys_newfstat */
   3.422 us [ 8091] |     __do_page_fault();
            [ 8091] |     sys_clock_gettime() {
   1.327 us [ 8091] |       smp_irq_work_interrupt();
   3.701 us [ 8091] |     } /* puts */
......  

通常我们需要把运行结果保存下来,便于以后分析,这时可以使用uftracerecord功能:

# uftrace record a.out
A is created
A is destroyed
# ls
a.out  test.cpp  uftrace.data

可以看到在当前目录下多了一个uftrace.data的文件夹,里面记录了关于这次程序运行的信息,随后就可以对程序进行分析了。举个例子,可以使用uftracereplay功能对程序的运行进行一遍“回看”:

# uftrace replay
# DURATION    TID     FUNCTION
   3.980 us [ 8104] | __cxa_atexit();
            [ 8104] | main() {
            [ 8104] |   A::A() {
  30.660 us [ 8104] |     puts();
  34.781 us [ 8104] |   } /* A::A */
            [ 8104] |   A::~A() {
  27.378 us [ 8104] |     puts();
  30.591 us [ 8104] |   } /* A::~A */
  69.632 us [ 8104] | } /* main */

综上所述,uftrace在下面这两个方面可以给我们很大帮助:
(1)了解程序的执行流程;
(2)度量函数的运行时间,确定热点。
感兴趣的朋友不妨亲自一试!