乐趣区

uftrace在arm平台的交叉编译使用介绍

uftrace

概述

uftrace 工具可用来跟踪和剖析用 C/C++ 编写的程序。它深受 Linux 内核的 ftrace 框架(尤其是函数图跟踪器)的启发,并反对用户空间程序。它反对各种命令和过滤器来帮忙分析程序的执行和性能。它的个性如下:

  • 它能跟踪可执行文件中的每个函数并显示持续时间,它也能够跟踪内部库调用(入口和进口),通常也反对内部库嵌套的内部库或者外部函数调用。
  • 它能够在性能级别显示具体的执行流程,并报告哪个函数的开销最高,它还显示了与执行环境相干的各种信息。
  • 能够设置过滤器,以便在跟踪时排除或蕴含特定函数。此外,它还能够保留和显示函数参数和返回值。
  • 它反对多过程和多线程应用程序。
  • 如果内核有启用函数图跟踪器(CONFIG_FUNCTION_GRAPH_TRACER=y),那么它还能够跟踪内核函数(应用 -k 选项)。

实际

toolchain:gcc-9.1.0-2019.11-x86_64_arm-linux-gnueabihf

下 code

git clone https://github.com/namhyung/uftrace.git

编译

./configure --prefix=$PWD/output --host=arm-linux-gnueabihf 
make -j5
make install

生成布局为:

运行

环境筹备

  1. 板子挂载共享目录
ifconfig  eth0  up
ifconfig eth0  xxx.xxx.xxx.xxx
mount -t nfs xxx.xxx.xxx.xxx:/xxx /mnt -o nolock
  1. 将生成的 output/* 拷贝到共享目录的对应地位,板子上布局如下:

  1. 编译二进制程序要带上 -pg 或者 -finstrument-functions,本文全程以上面的程序为例子:
//multi_thread.c
#include <pthread.h>
#include <unistd.h>

void *thread_funcA(void *arg)
{printf("%s:%d\n", __FUNCTION__, __LINE__);
    sleep(5);
    printf("%s:%d\n", __FUNCTION__, __LINE__);

    return NULL;
}

void *thread_funcB(void *arg)
{printf("%s:%d\n", __FUNCTION__, __LINE__);
    sleep(10);
    printf("%s:%d\n", __FUNCTION__, __LINE__);

    return NULL;
}

int main(void)
{
    pthread_t thidA;
    pthread_t thidB;

    printf("%s:%d\n", __FUNCTION__, __LINE__);
    pthread_create(&thidA, NULL, thread_funcA, "funcA");
    printf("%s:%d\n", __FUNCTION__, __LINE__);
    pthread_create(&thidB, NULL, thread_funcB, "funcB");
    printf("%s:%d\n", __FUNCTION__, __LINE__);
    pthread_join(thidA, NULL);
    printf("%s:%d\n", __FUNCTION__, __LINE__);
    pthread_join(thidB, NULL);
    printf("%s:%d\n", __FUNCTION__, __LINE__);

    return 0;
}

编译如下:

arm-linux-gnueabihf-gcc -pg multi_thread.c -lpthread -o multi_thread
  1. 将生成的 multi_thread 放到共享目录里
  2. 须要留神的是,uftrace 会在当前目录创立 fifo/utrace.data,如果是在 windows 共享目录下,会提醒如下出错:

​ 倡议切到板子上的 /tmp 目录: cd /tmp

  1. 最初再设置一下环境变量和动静库门路就能够欢快游玩了:
export PATH=/mnt/uftrace/bin:$PATH
export LD_LIBRARY_PATH=/mnt/uftrace/lib:$LD_LIBRARY_PATH

basic

目标程序执行完后,uftrace 就会输入每个函数的执行工夫。

uftrace /mnt/multi_thread

输入如下:

filters

  • -F FUNC, –filter=FUNC

将过滤器设置为仅跟踪所选函数。

 uftrace -F sleep -F printf /mnt/multi_thread 

输入如下:

  • -C FUNC, –caller-filter=FUNC

只显示所选函数的调用门路。

uftrace -C sleep -C printf /mnt/multi_thread 

输入如下:

  • -N FUNC, –notrace=FUNC

设置过滤器不跟踪所选函数

uftrace -N printf /mnt/multi_thread 

输入如下:

  • -t TIME, –time-filter=TIME

不显示设定工夫阈值以下的短小函数。

uftrace  -t 1ms /mnt/multi_thread

Arguments Detection with Debug Info

应用 -a/–auto-args 去侦测带调试信息的二进制程序的函数参数和返回值。

uftrace -a /mnt/multi_thread 

输入如下:

uftrace record

能够记录下 trace data,便于后续剖析。

uftrace record /mnt/multi_thread

生成如下:

uftrace replay

能够回放对应的 trace data,默认是回放当前目录的 uftrace.data。

uftrace replay

uftrace report

打印 trace data 的统计信息和摘要,默认是打印当前目录的 uftrace.data。

  • basic
uftrace report

输入如下:

  • -s

该选项可抉择按 total time/self time/calls 进行降序排序,默认按 total 降序排序。

  1. 按 total time 降序排序
uftrace report -s total

输入如下:

  1. 按 self time 降序排序
uftrace report -s self

  1. 按 calls 降序排序
uftrace report -s call

uftrace graph

显示函数调用图,默认是显示当前目录的 uftrace.data。

uftrace graph

输入如下:

总结

uftrace 还有很多弱小的个性,比方通过 dump 命令生成相应 trace data,可拿到 chrome 浏览器可视化展现或者生成火焰图;如果 configure 蕴含了 python,还能够编写 python 脚本定义函数入口和进口的钩子函数;如果编译加上 -mnop-mcount,还能够实现运行时动静跟踪;如果 configure 蕴含了 capstone,那能够实现齐全动静跟踪,而不必编译器反对。因而 uftrace 还是值得尝试一下。

参考

  1. github 主页
  2. 具体的官网 PPT
  3. 官网教程
退出移动版