SPROF - Linux手册页

时间:2019-08-20 17:58:33  来源:igfitidea点击:

Linux用户手册 第1部分
更新日期: 2020-06-09

名称

sprof-读取和显示共享对象分析数据

语法

sprof [option]... shared-object-path [profile-data-path]

说明

sprof命令显示指定为第一个命令行参数的共享库(共享库)的概要分析。使用(可选的)第二个命令行参数中先前生成的概要分析数据来创建概要分析摘要。如果省略概要分析数据路径名,则sprof将尝试使用共享库的soname推断出它,在当前目录中查找名称为.profile的文件。

选项

以下命令行选项指定要生成的概要文件输出:

-c, --call-pairs
打印共享对象导出的接口的呼叫路径对列表,以及每个路径的使用次数。
-p, --flat-profile
生成带有计数和刻度的受监视对象中所有功能的平面轮廓。
-q, --graph
生成调用图。

如果未指定上述任何一个选项,则默认行为是显示平面轮廓和调用图。

以下其他命令行选项可用:

-?, --help
显示命令行选项和参数的摘要,然后退出。
--usage
显示简短用法消息并退出。
-V, --version
显示程序版本并退出。

遵循规范

sprof命令是GNU扩展,在POSIX.1中不存在。

示例

下面的示例演示sprof的用法。该示例包含一个主程序,该程序在共享对象中调用两个函数。一,主程序代码:

$ cat prog.c
#include <stdlib.h>

void x1(void);
void x2(void);

int
main(int argc, char *argv[])
{
    x1();
    x2();
    exit(EXIT_SUCCESS);
}

函数x1()和x2()在以下用于构造共享库的源文件中定义:

$ cat libdemo.c
#include <unistd.h>

void
consumeCpu1(int lim)
{
    int j;

    for (j = 0; j < lim; j++)
        getppid();
}

void
x1(void) {
    int j;

    for (j = 0; j < 100; j++)
        consumeCpu1(200000);
}

void
consumeCpu2(int lim)
{
    int j;

    for (j = 0; j < lim; j++)
        getppid();
}

void
x2(void)
{
    int j;

    for (j = 0; j < 1000; j++)
        consumeCpu2(10000);
}

现在,我们以真实名称libdemo.so.1.0.1和sod libdemo.so.1构造共享对象:

$ cc -g -fPIC -shared -Wl,-soname,libdemo.so.1 \
        -o libdemo.so.1.0.1 libdemo.c

然后,我们为库soname和库链接器名称构造符号链接:

$ ln -sf libdemo.so.1.0.1 libdemo.so.1
$ ln -sf libdemo.so.1 libdemo.so

接下来,我们编译主程序,将其链接到共享对象,然后列出程序的动态依赖项:

$ cc -g -o prog prog.c -L. -ldemo
$ ldd prog
        linux-vdso.so.1 =>  (0x00007fff86d66000)
        libdemo.so.1 => not found
        libc.so.6 => /lib64/libc.so.6 (0x00007fd4dc138000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fd4dc51f000)

为了获得共享库的概要分析信息,我们用库的soname定义环境变量LD_PROFILE

$ export LD_PROFILE=libdemo.so.1

然后,我们用应该在其中写入概要文件输出的目录的路径名定义环境变量LD_PROFILE_OUTPUT,并创建该目录(如果尚不存在):

$ export LD_PROFILE_OUTPUT=$(pwd)/prof_data
$ mkdir -p $LD_PROFILE_OUTPUT

LD_PROFILE会将概要分析输出附加到输出文件(如果已经存在),因此我们确保不存在预先存在的概要数据:

$ rm -f $LD_PROFILE_OUTPUT/$LD_PROFILE.profile

然后,我们运行程序以生成概要分析输出,该概要输出将写入LD_PROFILE_OUTPUT中指定的目录中的文件中:

$ LD_LIBRARY_PATH=. ./prog
$ ls prof_data
libdemo.so.1.profile

然后,我们使用sprof -p选项生成带有计数和刻度的平面轮廓:

$ sprof -p libdemo.so.1 $LD_PROFILE_OUTPUT/libdemo.so.1.profile
Flat profile:

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total
 time   seconds   seconds    calls  us/call  us/call  name
 60.00      0.06     0.06      100   600.00           consumeCpu1
 40.00      0.10     0.04     1000    40.00           consumeCpu2
  0.00      0.10     0.00        1     0.00           x1
  0.00      0.10     0.00        1     0.00           x2

sprof -q选项生成调用图:

$ sprof -q libdemo.so.1 $LD_PROFILE_OUTPUT/libdemo.so.1.profile

index % time    self  children    called     name

                0.00    0.00      100/100         x1 [1]
[0]    100.0    0.00    0.00      100         consumeCpu1 [0]
-----------------------------------------------
                0.00    0.00        1/1           <UNKNOWN>
[1]      0.0    0.00    0.00        1         x1 [1]
                0.00    0.00      100/100         consumeCpu1 [0]
-----------------------------------------------
                0.00    0.00     1000/1000        x2 [3]
[2]      0.0    0.00    0.00     1000         consumeCpu2 [2]
-----------------------------------------------
                0.00    0.00        1/1           <UNKNOWN>
[3]      0.0    0.00    0.00        1         x2 [3]
                0.00    0.00     1000/1000        consumeCpu2 [2]
-----------------------------------------------

上方和下方的""字符串代表位于已分析对象之外的标识符(在此示例中,这些是main()的实例)。

sprof -c选项生成呼叫对及其发生次数的列表:

$ sprof -c libdemo.so.1 $LD_PROFILE_OUTPUT/libdemo.so.1.profile
<UNKNOWN>                  x1                                 1
x1                         consumeCpu1                      100
<UNKNOWN>                  x2                                 1
x2                         consumeCpu2                     1000

另外参见

gprof(1),ldd(1),ld.so(8)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/