<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<atom:link href="http://gentoo-zh.org/extern.php?action=feed&amp;tid=868&amp;type=rss" rel="self" type="application/rss+xml" />
		<title><![CDATA[Gentoo中文社区 / Gentoo伯克利子系统之二:基于BCC的BPF示例程序]]></title>
		<link>http://www.gentoo-zh.org/viewtopic.php?id=868</link>
		<description><![CDATA[Gentoo伯克利子系统之二:基于BCC的BPF示例程序 最近发表的帖子。]]></description>
		<lastBuildDate>Thu, 13 Jun 2024 13:31:35 +0000</lastBuildDate>
		<generator>FluxBB</generator>
		<item>
			<title><![CDATA[Gentoo伯克利子系统之二:基于BCC的BPF示例程序]]></title>
			<link>http://www.gentoo-zh.org/viewtopic.php?pid=988#p988</link>
			<description><![CDATA[<p>结合前面一篇针对BPF的学习，本篇文章重点介绍编写一个对内核系统调用exec的例子。本测试例子基本上包含了全部的，syscall类别系统调用的BPF的框架。</p><br /><p>```python<br />#!/usr/bin/python<br />from __future__ import print_function<br />from bcc import BPF<br />from collections import defaultdict</p><p>bpf_text = &quot;&quot;&quot;<br />#include<br />#include<br />#include<br />#define ARGSIZE 256<br />struct data_t {<br />&#160; &#160; &#160; u32 pid; // PID as in the userspace term (i.e. task-&gt;tgid in kernel)<br />&#160; &#160; &#160; char comm[TASK_COMM_LEN];<br />&#160; &#160; &#160; char argv[ARGSIZE];<br /> };<br />BPF_PERF_OUTPUT(events);<br />int syscall__execve(struct pt_regs *ctx,<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;const char __user *filename,<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;const char __user *const __user *__argv,<br />&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;const char __user *const __user *__envp)<br />{<br />&#160; &#160; struct data_t data = {};<br />&#160; &#160; bpf_trace_printk(&quot;Hello, World!222%s\\n&quot;,filename);<br />&#160; &#160; data.pid = bpf_get_current_pid_tgid();<br />&#160; &#160; bpf_get_current_comm(&amp;data.comm,sizeof(data.comm));<br />&#160; &#160; bpf_probe_read_user(data.argv, sizeof(data.argv), filename);<br />&#160; &#160; events.perf_submit(ctx, &amp;data, sizeof(struct data_t));<br />&#160; &#160; return 0;<br />}<br />&quot;&quot;&quot;<br />b = BPF(text=bpf_text)<br />execve_fnname = b.get_syscall_fnname(&quot;execve&quot;)<br />b.attach_kprobe(event=execve_fnname, fn_name=&quot;syscall__execve&quot;)<br />print(&quot;%-18s %-16s %-14s&quot; % (&quot;COMM&quot;, &quot;PID&quot;,&quot;ARGS&quot;))</p><p> <br />argv = defaultdict(list)</p><p>def print_event(cpu, data, size):<br />&#160; &#160; event = b[&quot;events&quot;].event(data)<br />&#160; &#160; argv[event.pid].append(event.argv)</p><p>&#160; &#160; argv_text = b&#039; &#039;.join(argv[event.pid]).replace(b&#039;\n&#039;, b&#039;\\n&#039;)</p><p>&#160; &#160; print(&quot;%-18s %-16d %-14s&quot; % (event.comm, event.pid,argv_text))</p><p> <br />b[&quot;events&quot;].open_perf_buffer(print_event)<br />while 1:<br />&#160; &#160; try:<br />&#160; &#160; &#160; &#160; b.perf_buffer_poll()<br />&#160; &#160; except KeyboardInterrupt:<br />&#160; &#160; &#160; &#160; exit()<br />```</p><p>主要注意点：</p><p>1. BPF_PERF_OUTPUT&#160; &#160;创建BPF的table，通过Perf 的环形缓存区，把用户定义的event事件的数据推送到用户空间，这是把事件数据推送到用户空间的首选的方式。 也就是如果把从内核中获取到的数据，push到用户空间进行处理和展示，在代码中添加该宏。</p><p>2. b.attach_kprobe(event=execve_fnname, fn_name=&quot;syscall__execve&quot;) 这里的fn_name=&quot;syscal__execve&quot;函数名，保持格式的绝对一致，也就是syscall__ 后面两个下划线，execve名字和内核中syscall保持一致。<br />3.&#160; 在内核中插桩syscall__execve 函数时，这里的第一个参数struct pt_regs *ctx 保持固定，其余的参数是syscall类函数保持一致的，下面是调用execve的参数。</p><p> int execve(const char *pathname, char *const argv[], char *const envp[]);</p><p>4.&#160; 其实整个程序包含了两个部分，一个是python的客户端，一个是以字符串的形式bpf_text出现的插桩函数，使用C语言编写，整个测试程序包含了，用户空间和内核空间的代码。</p><p>5&#160; bpf_trace_printk函数，类似于C语言中printf，编写bpf程序时，可以用来调试打印相关信息。注意该打印函数会将信息输出到下面的文件中：/sys/kernel/debug/tracing/trace_pipe，通过跟踪该文件进行查看。</p><p>6. print_even 函数时对内核中获取的数据和信息的统一展示。</p>]]></description>
			<author><![CDATA[dummy@example.com (batsom)]]></author>
			<pubDate>Thu, 13 Jun 2024 13:31:35 +0000</pubDate>
			<guid>http://www.gentoo-zh.org/viewtopic.php?pid=988#p988</guid>
		</item>
	</channel>
</rss>
