15.2. 使用 Dyninst

15.2.1. 使用带有 SystemTap 的 Dyninst

要将 DyninstSystemTap 结合使用,允许非root 用户检测用户空间可执行文件,使用 --dyninst (或 --runtime=dyninst)命令行选项运行 stap 命令。这会告知 stapSystemTap 脚本转换为使用 Dyninst 库的 C 代码,将这个 C 代码编译到共享库,然后加载共享库并运行脚本。请注意,当执行类似此操作时,stap 命令还需要指定 -c-x 命令行选项。

使用 Dyninst 运行时检测可执行文件:

$ scl enable devtoolset-11 "stap --dyninst -c 'command' option... argument..."

同样,使用 Dyninst 运行时检测用户的进程:

$ scl enable devtoolset-11 "stap --dyninst -x process_id option... argument..."

有关 Red Hat Developer Toolset 版本的信息,请参阅 第 12 章 SystemTap 。有关 SystemTap 及其用法的常规介绍,请参见 Red Hat Enterprise Linux 7 的 SystemTap 入门指南

例 15.1. 使用带有 SystemTap 的 Dyninst

考虑一个名为 exercise.C 的源文件,其内容如下:

#include <stdio.h>

void print_iteration(int value) {
  printf("Iteration number %d\n", value);
}

int main(int argc, char **argv) {
  int i;
  printf("Enter the starting number: ");
  scanf("%d", &i);
  for(; i>0; --i)
    print_iteration(i);
  return 0;
}

这个程序提示用户输入起始数字,然后计入 1,针对每个迭代调用 print_iteration() 函数,以便将数字打印到标准输出。使用 Red Hat Developer Toolset 中的 g++ 编译器在命令行中编译该程序:

$ scl enable devtoolset-11 'g++ -g -o exercise exercise.C'

现在,考虑另一个名为 count.stp 的源文件,其内容如下:

#!/usr/bin/stap

global count = 0

probe process.function("print_iteration") {
  count++
}

probe end {
  printf("Function executed %d times.\n", count)
}

SystemTap 脚本在执行进程的过程中打印调用 print_iteration() 函数的次数。在 练习 二进制文件中运行此脚本:

$ scl enable devtoolset-11 "stap --dyninst -c './exercise' count.stp"
Enter the starting number: 5
Iteration number 5
Iteration number 4
Iteration number 3
Iteration number 2
Iteration number 1
Function executed 5 times.