15.2.2. 使用 Dyninst 作为独立库
在将 Dyninst 库用作应用程序的一部分之前,将 DYNINSTAPI_RT_LIB
环境变量的值设置为到运行时库文件的路径:
export DYNINSTAPI_RT_LIB=/opt/rh/devtoolset-11/root/usr/lib64/dyninst/libdyninstAPI_RT.so
$ export DYNINSTAPI_RT_LIB=/opt/rh/devtoolset-11/root/usr/lib64/dyninst/libdyninstAPI_RT.so
这会在当前 shell 会话中设置 DYNINSTAPI_RT_LIB
环境变量。
例 15.2 “使用 Dyninst 作为独立应用程序” 演示了如何编写和构建用于监控用户空间进程的执行程序。有关如何使用 Dyninst 的详细解释,请查看 第 15.3 节 “其它资源” 中列出的资源。
例 15.2. 使用 Dyninst 作为独立应用程序
考虑来自 例 15.1 “使用带有 SystemTap 的 Dyninst” 的 exercise.C
源文件:此程序提示用户输入启动号,然后计入 1,为每个迭代调用 print_iteration()
函数,以便将数字输出到标准输出。
现在,考虑另一个名为 count.C
的源文件,其内容如下:
请注意,在调用任何 Dyninst 库销毁器之前,客户端应用程序应该销毁所有 Bpatch
对象。否则,mutator 可能会意外终止分段错误。要临时解决这个问题,请将 mutator 的 BPatch
对象设置为 main()
函数中的本地变量。或者,如果您需要使用 BPatch
作为全局变量,请在变异退出前手动分离所有 mutatee 进程。
这个程序接受进程 ID 和函数名称作为命令行参数,然后在执行进程期间显示调用函数的总数量。您可以使用以下 Makefile
构建这两个文件:
要使用 Red Hat Developer Toolset 的 g++
编译器在命令行中编译两个程序,请运行 make
工具程序:
scl enable devtoolset-11 make
$ scl enable devtoolset-11 make
g++ -g -I/opt/rh/devtoolset-11/root/usr/include/dyninst count.C -c
g++ -g -I/opt/rh/devtoolset-11/root/usr/include/dyninst count.o -L /opt/rh/devtoolset-11/root/usr/lib64/dyninst -ldyninstAPI -o count
g++ -g -I/opt/rh/devtoolset-11/root/usr/include/dyninst exercise.C -o exercise
这会创建一个名为 exercise
的新二进制文件,并在当前工作目录中 计数
。
在一个 shell 会话中,按如下所示执行 练习
二进制文件,并等待它提示您进入起始数字:
./exercise
$ ./exercise
Enter the starting number:
不要输入这个数字。相反,启动另一个 shell 会话并在提示符下键入以下内容来设置 DYNINSTAPI_RT_LIB
环境变量并执行 计数
二进制文件:
export DYNINSTAPI_RT_LIB=/opt/rh/devtoolset-11/root/usr/lib64/dyninst/libdyninstAPI_RT.so ./count `pidof exercise` print_iteration
$ export DYNINSTAPI_RT_LIB=/opt/rh/devtoolset-11/root/usr/lib64/dyninst/libdyninstAPI_RT.so
$ ./count `pidof exercise` print_iteration
Finding function print_iteration(): OK
Instrumenting function print_iteration(): OK
Waiting for process 8607 to exit...
现在,切换回第一个 shell 会话,并根据 练习
程序请求的起始数字输入。例如:
当 练习
程序终止时,计数
程序会显示在执行 print_iteration()
函数的次数:
Function executed 5 times.
Function executed 5 times.