gpt4 book ai didi

c - 用 C 编写 DTrace 使用者

转载 作者:太空狗 更新时间:2023-10-29 16:53:25 27 4
gpt4 key购买 nike

我想在 FreeBSD 10.1 上编写一个 C 程序,使用 libdtrace 实现 DTrace 消费者

我知道我需要先调用 dtrace_open() - 例如我找到了 this旧演示文稿,但我什至无法开始,因为没有安装 dtrace.h(仅在系统源代码树中)。

共享库已安装,例如FreeBSD 中包含的 /usr/sbin/dtrace 工具可以充当 DTrace 使用者,该工具链接到 /lib/libdtrace.so.2(也指向通过来自 /usr/lib/libdtrace.so 的符号链接(symbolic link)。

任何基本示例,包括构建说明 (FreeBSD 10.1/clang) 都会对我有很大帮助。


编写自定义消费者的实际目标是创建一个 CFFI基于包装器可用于 Python 和 PyPy . 意思是:上面的C程序只是入门,学习再进行。

CFFI 是将 PyPy 与共享库连接起来的推荐的现代高性能方式。

CFFI 可用于 ABI和 API 级别。后者需要一个头文件来包含,前者需要声明从库中使用的东西。


改编自 Adam 的回答,这是一个适用于 FreeBSD 10.1 的完整示例。

生成文件:

all:
cc \
-I /usr/src/cddl/compat/opensolaris/include \
-I /usr/src/cddl/contrib/opensolaris/lib/libdtrace/common/ \
-I /usr/src/sys/cddl/compat/opensolaris \
-I /usr/src/sys/cddl/contrib/opensolaris/uts/common/ \
hello_dtrace.c \
-l dtrace -l proc -l ctf -l elf -l z -l rtld_db -l pthread -l util \
-o hello_dtrace

hello_dtrace.c:

#include <dtrace.h>
#include <signal.h>
#include <stdio.h>

static dtrace_hdl_t* g_dtp;

static int chewrec (const dtrace_probedata_t *data, const dtrace_recdesc_t *rec, void *arg) {
printf("chewing dtrace record ..\n");
// A NULL rec indicates that we've processed the last record.
if (rec == NULL) {
return (DTRACE_CONSUME_NEXT);
}
return (DTRACE_CONSUME_THIS);
}

static const char* g_prog = "BEGIN { printf(\"hello from dtrace\\n\"); }";
//static const char* g_prog = "syscall::open*:entry { printf(\"%s %s\\n\", execname, copyinstr(arg0)); }";

static int g_intr;
static int g_exited;

static void intr (int signo) {
g_intr = 1;
}


int main (int argc, char** argv) {
int err;

if ((g_dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) {
fprintf(stderr, "failed to initialize dtrace: %s\n", dtrace_errmsg(NULL, err));
return -1;
}
printf("Dtrace initialized\n");

(void) dtrace_setopt(g_dtp, "bufsize", "4m");
(void) dtrace_setopt(g_dtp, "aggsize", "4m");
printf("dtrace options set\n");

dtrace_prog_t* prog;
if ((prog = dtrace_program_strcompile(g_dtp, g_prog, DTRACE_PROBESPEC_NAME, 0, 0, NULL)) == NULL) {
fprintf(stderr, "failed to compile dtrace program\n");
return -1;
} else {
printf("dtrace program compiled\n");
}

dtrace_proginfo_t info;
if (dtrace_program_exec(g_dtp, prog, &info) == -1) {
fprintf(stderr, "failed to enable dtrace probes\n");
return -1;
} else {
printf("dtrace probes enabled\n");
}

struct sigaction act;
(void) sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_handler = intr;
(void) sigaction(SIGINT, &act, NULL);
(void) sigaction(SIGTERM, &act, NULL);

if (dtrace_go(g_dtp) != 0) {
fprintf(stderr, "could not start instrumentation\n");
return -1;
} else {
printf("instrumentation started ..\n");
}

int done = 0;
do {
if (!g_intr && !done) {
dtrace_sleep(g_dtp);
}

if (done || g_intr || g_exited) {
done = 1;
if (dtrace_stop(g_dtp) == -1) {
fprintf(stderr, "could not stop tracing\n");
return -1;
}
}

switch (dtrace_work(g_dtp, stdout, NULL, chewrec, NULL)) {
case DTRACE_WORKSTATUS_DONE:
done = 1;
break;
case DTRACE_WORKSTATUS_OKAY:
break;
default:
fprintf(stderr, "processing aborted");
return -1;
}
} while (!done);

printf("closing dtrace\n");
dtrace_close(g_dtp);

return 0;
}

运行:

[oberstet@brummer2 ~/hello_dtrace]$ make; sudo ./hello_dtrace
cc -I /usr/src/cddl/contrib/opensolaris/lib/libdtrace/common/ -I /usr/src/sys/cddl/compat/opensolaris -I /usr/src/sys/cddl/contrib/opensolaris/uts/common/ hello_dtrace.c -l dtrace -l proc -l ctf -l elf -l rtld_db -l z -l pthread -l util -o hello_dtrace
Dtrace initialized
dtrace options set
dtrace program compiled
dtrace probes enabled
instrumentation started ..
chewing dtrace record ..
hello from dtrace
chewing dtrace record ..
^Cclosing dtrace

最佳答案

libdtrace API 不一定适用于稳定的消费者,但可以很容易地从一些现有消费者那里学习并开始使用。最简单和最现代的是plockstat ,用于用户空间锁定统计的 illumos 实用程序。

这是一个简单的 DTrace 消费者程序的基本流程:

dtrace_open() 获取 dtrace_hdl_t,其他 libdtrace 交互的句柄
dtrace_setopt() 配置选项(-x 标记为 dtrace(1M))
dtrace_strcompile() 编译 D 程序的字符串
dtrace_program_exec() 将该程序发送到内核
dtrace_go() 检测系统并开始记录数据
dtrace_close() 最后清理

对于主数据收集循环(在 dtrace_go()dtrace_close() 之间)执行以下操作:

dtrace_sleep() 根据 DTrace 选项(switchrate 和 aggrate)暂停
dtrace_work() 处理跟踪数据
dtrace_stop() 中止

参见plockstat.c中的主循环了解更多。

对于其他简单的 DTrace 使用者,请查看 intrstatlockstat .对于厨房水槽,查看 dtrace(1M) 命令行实用程序的代码。

关于c - 用 C 编写 DTrace 使用者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28011495/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com