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