include <linux/sched.h>
2025-07-10 02:29:18作者:范垣楠Rhoda
#include <linux/sched.h>
int do_trace(struct pt_regs *ctx) { char comm[TASK_COMM_LEN]; bpf_get_current_comm(&comm, sizeof(comm)); bpf_trace_printk("%s\n", comm); return 0; }
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=bpf_get_current_comm+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=bpf_get_current_comm+path%3Atools&type=Code)
### 7. bpf_get_current_task()
语法: ```struct task_struct *bpf_get_current_task(void)```
返回值: 当前任务结构体
返回当前任务结构体。注意,此函数仅适用于4.8+内核。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=bpf_get_current_task+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=bpf_get_current_task+path%3Atools&type=Code)
### 8. bpf_log2l()
语法: ```unsigned int bpf_log2l(unsigned long v)```
返回值: 输入值的对数
计算输入值的对数2。这通常用于创建索引直方图,以记录幂次分布的数据。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=bpf_log2l+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=bpf_log2l+path%3Atools&type=Code)
### 9. bpf_get_prandom_u32()
语法: ```u32 bpf_get_prandom_u32(void)```
返回值: 伪随机数
获取伪随机数。注意,此函数仅适用于4.13+内核。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=bpf_get_prandom_u32+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=bpf_get_prandom_u32+path%3Atools&type=Code)
### 10. bpf_probe_read_user()
语法: ```int bpf_probe_read_user(void *dst, int size, const void*src)```
返回值: 成功时返回0
该函数将从用户地址空间复制size字节到BPF堆栈,以便BPF之后可以对其进行操作。为了安全起见,所有用户内存读取都必须通过bpf_probe_read_user()进行。在某些情况下,比如解引用用户变量时,这会自动发生,因为bcc会重新编写BPF程序以包含所需的bpf_probe_read_user()。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=bpf_probe_read_user+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=bpf_probe_read_user+path%3Atools&type=Code)
### 11. bpf_probe_read_user_str()
语法: ```int bpf_probe_read_user_str(void *dst, int size, const void*src)```
返回值:
- \> 0 成功时字符串长度(包括结尾的NULL字符)
- \< 0 出错
该函数将一个以`NULL`结尾的字符串从用户地址空间复制到BPF堆栈中,以便BPF以后可以对其进行操作。如果字符串的长度小于size,则目标不会用更多的`NULL`字节进行填充。如果字符串的长度大于size,则只会复制`size - 1`个字节,并将最后一个字节设置为`NULL`。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=bpf_probe_read_user_str+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=bpf_probe_read_user_str+path%3Atools&type=Code)
### 12. bpf_get_ns_current_pid_tgid()
语法: ```u64 bpf_get_ns_current_pid_tgid(u64 dev, u64 ino, struct bpf_pidns_info *nsdata, u32 size)```
返回值:
- 0 成功时
- -EINVAL 如果大小无效
- -ENOENT 如果pid命名空间不存在
该函数获取与当前任务关联的pid和tgid,以及命名空间信息。用户可以提供dev和ino来标识命名空间。如果为0,将使用当前命名空间。返回的pid和tgid是相对于命名空间的,命名空间信息将填充到nsdata中。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=bpf_get_ns_current_pid_tgid+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=bpf_get_ns_current_pid_tgid+path%3Atools&type=Code)
## 调试
### 1. bpf_override_return()
语法: ```int bpf_override_return(struct pt_regs *regs, u64 rc)```
返回值: 0
该函数覆盖被探测函数的返回值。它需要在内核配置中启用`CONFIG_BPF_KPROBE_OVERRIDE`,并且探测点必须处于错误注入点。这通常用于错误注入测试。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=bpf_override_return+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=bpf_override_return+path%3Atools&type=Code)
## 输出
### 1. bpf_trace_printk()
语法: ```bpf_trace_printk(const char *fmt, ...)```
返回值: 成功时返回0
一个简单的内核工具,用于调试。它将输出写入/sys/kernel/debug/tracing/trace_pipe,以及使用BPF.trace_print()读取。这是一个有限的printf()版本:最多3个参数,一个%s字符串,以及一个%llx或%p。有关详细信息,请参阅内核源代码中的bpf_trace_printk()注释。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=bpf_trace_printk+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=bpf_trace_printk+path%3Atools&type=Code)
### 2. BPF_PERF_OUTPUT
语法: ```BPF_PERF_OUTPUT(name)```
创建一个名为`name`的BPF表,用于将自定义事件数据推送到用户空间,通过perf环形缓冲区。这是将每个事件数据从内核传递到用户空间的推荐方法。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=BPF_PERF_OUTPUT+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=BPF_PERF_OUTPUT+path%3Atools&type=Code)
### 3. perf_submit()
语法: ```int perf_submit((void *)ctx, (void *)data, u32 data_size)```
返回值: 成功时返回0
将自定义事件数据提交到`BPF_PERF_OUTPUT`表中。`ctx`是传递给BPF程序的上下文(例如,在kprobe中是`struct pt_regs *`),`data`是指向要提交的数据的指针,`data_size`是数据的大小。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=perf_submit+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=perf_submit+path%3Atools&type=Code)
### 4. perf_submit_skb()
语法: ```int perf_submit_skb((void *)ctx, u32 packet_size, (void *)data, u32 data_size)```
返回值: 成功时返回0
类似于`perf_submit()`,但专门用于网络数据包数据。`packet_size`是数据包的总大小,`data`是指向要提交的数据的指针,`data_size`是数据的大小。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=perf_submit_skb+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=perf_submit_skb+path%3Atools&type=Code)
### 5. BPF_RINGBUF_OUTPUT
语法: ```BPF_RINGBUF_OUTPUT(name, page_cnt)```
创建一个名为`name`的BPF表,用于将自定义事件数据推送到用户空间,通过ringbuf环形缓冲区。`page_cnt`指定环形缓冲区的大小(以页为单位)。这是5.8+内核中推荐的将每个事件数据从内核传递到用户空间的方法。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=BPF_RINGBUF_OUTPUT+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=BPF_RINGBUF_OUTPUT+path%3Atools&type=Code)
### 6. ringbuf_output()
语法: ```int ringbuf_output(void *ringbuf, void *data, u64 data_size, u64 flags)```
返回值: 成功时返回0
将自定义事件数据提交到`BPF_RINGBUF_OUTPUT`表中。`ringbuf`是指向环形缓冲区的指针,`data`是指向要提交的数据的指针,`data_size`是数据的大小,`flags`是保留的,必须为0。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=ringbuf_output+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=ringbuf_output+path%3Atools&type=Code)
### 7. ringbuf_reserve()
语法: ```void *ringbuf_reserve(void *ringbuf, u64 data_size, u64 flags)```
返回值: 成功时返回指向保留空间的指针,失败时返回NULL
从`BPF_RINGBUF_OUTPUT`表中保留空间。`ringbuf`是指向环形缓冲区的指针,`data_size`是要保留的空间大小,`flags`是保留的,必须为0。返回的指针必须通过`ringbuf_submit()`或`ringbuf_discard()`提交或丢弃。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=ringbuf_reserve+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=ringbuf_reserve+path%3Atools&type=Code)
### 8. ringbuf_submit()
语法: ```void ringbuf_submit(void *data, u64 flags)```
提交通过`ringbuf_reserve()`保留的数据。`data`是指向保留空间的指针,`flags`是保留的,必须为0。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=ringbuf_submit+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=ringbuf_submit+path%3Atools&type=Code)
### 9. ringbuf_discard()
语法: ```void ringbuf_discard(void *data, u64 flags)```
丢弃通过`ringbuf_reserve()`保留的数据。`data`是指向保留空间的指针,`flags`是保留的,必须为0。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=ringbuf_discard+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=ringbuf_discard+path%3Atools&type=Code)
## Maps
### 1. BPF_TABLE
语法: ```BPF_TABLE(_table_type, _key_type, _leaf_type, _name, _max_entries)```
创建一个名为`_name`的BPF表。`_table_type`是表类型(例如,`BPF_HASH`),`_key_type`是键类型,`_leaf_type`是值类型,`_max_entries`是表的最大条目数。
#### 固定映射
语法: ```BPF_TABLE_PINNED(_table_type, _key_type, _leaf_type, _name, _max_entries, _path)```
创建一个名为`_name`的BPF表,并将其固定到`_path`。`_table_type`是表类型(例如,`BPF_HASH`),`_key_type`是键类型,`_leaf_type`是值类型,`_max_entries`是表的最大条目数,`_path`是固定路径。
### 2. BPF_HASH
语法: ```BPF_HASH(name [, key_type [, leaf_type [, size]]])```
创建一个名为`name`的哈希表映射。默认参数为:`BPF_HASH(name, u64, u64, 10240)`。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=BPF_HASH+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=BPF_HASH+path%3Atools&type=Code)
### 3. BPF_ARRAY
语法: ```BPF_ARRAY(name [, leaf_type [, size]])```
创建一个名为`name`的数组映射。默认参数为:`BPF_ARRAY(name, u64, 10240)`。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=BPF_ARRAY+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=BPF_ARRAY+path%3Atools&type=Code)
### 4. BPF_HISTOGRAM
语法: ```BPF_HISTOGRAM(name [, key_type [, size]])```
创建一个名为`name`的直方图映射。默认参数为:`BPF_HISTOGRAM(name, u64, 64)`。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=BPF_HISTOGRAM+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=BPF_HISTOGRAM+path%3Atools&type=Code)
### 5. BPF_STACK_TRACE
语法: ```BPF_STACK_TRACE(name, size)```
创建一个名为`name`的堆栈跟踪映射。`size`是最大条目数。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=BPF_STACK_TRACE+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=BPF_STACK_TRACE+path%3Atools&type=Code)
### 6. BPF_PERF_ARRAY
语法: ```BPF_PERF_ARRAY(name, size)```
创建一个名为`name`的性能事件数组映射。`size`是最大条目数。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=BPF_PERF_ARRAY+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=BPF_PERF_ARRAY+path%3Atools&type=Code)
### 7. BPF_PERCPU_HASH
语法: ```BPF_PERCPU_HASH(name [, key_type [, leaf_type [, size]]])```
创建一个名为`name`的每CPU哈希表映射。默认参数为:`BPF_PERCPU_HASH(name, u64, u64, 10240)`。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=BPF_PERCPU_HASH+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=BPF_PERCPU_HASH+path%3Atools&type=Code)
### 8. BPF_PERCPU_ARRAY
语法: ```BPF_PERCPU_ARRAY(name [, leaf_type [, size]])```
创建一个名为`name`的每CPU数组映射。默认参数为:`BPF_PERCPU_ARRAY(name, u64, 10240)`。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=BPF_PERCPU_ARRAY+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=BPF_PERCPU_ARRAY+path%3Atools&type=Code)
### 9. BPF_LPM_TRIE
语法: ```BPF_LPM_TRIE(name [, key_type [, leaf_type [, size]]])```
创建一个名为`name`的最长前缀匹配trie映射。默认参数为:`BPF_LPM_TRIE(name, struct bpf_lpm_trie_key, u64, 10240)`。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=BPF_LPM_TRIE+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=BPF_LPM_TRIE+path%3Atools&type=Code)
### 10. BPF_PROG_ARRAY
语法: ```BPF_PROG_ARRAY(name, size)```
创建一个名为`name`的程序数组映射。`size`是最大条目数。
示例:
[搜索 /examples](https://github.com/iovisor/bcc/search?q=BPF_PROG_ARRAY+path%3Aexamples&type=Code),
[搜索 /tools](https://github.com/iovisor/bcc/search?q=BPF_PROG_ARRAY+path%3Atools&type=Code)
### 11. BPF_DEVMAP
语法: ```BPF_DEVMAP(name, size)```