bpftrace 使用笔记

bpftrace 是基于BPF和BCC的开源系统跟踪工具. bpftrace 自带了许多性能工具,同时还提供一个高级编程语言环境,用于创建自定义的工具.
一般Linux发行版都可直接通过安装包安装使用, 我自己的环境由于升级了KERNEL导致不能正常使用, 只能通过源码重新构建使用.

环境准备:

$ uname -a
Linux fc29 5.12.7-300.fc29.x86_64 #1 SMP Fri May 28 13:45:39 CST 2021 x86_64 x86_64 x86_64 GNU/Linux

KENREL配置需确保以下功能模块是开启状态:

CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT=y
CONFIG_HAVE_EBPF_JIT=y
CONFIG_BPF_EVENTS=y
CONFIG_FTRACE_SYSCALLS=y
CONFIG_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_DYNAMIC_FTRACE=y
CONFIG_HAVE_KPROBES=y
CONFIG_KPROBES=y
CONFIG_KPROBE_EVENTS=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_UPROBES=y
CONFIG_UPROBE_EVENTS=y
CONFIG_DEBUG_FS=y

build

$ sudo dnf install -y bison flex cmake make git gcc-c++ elfutils-libelf-devel zlib-devel llvm-devel clang-devel bcc-devel systemtap-sdt-devel binutils-devel libbpf-devel gtest-devel gmock-devel
$ cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_TESTING:BOOL=OFF -DBUILD_SHARED_LIBS:BOOL=OFF .
$ make
$ make install
$ bpftrace--info
SystemOS: Linux 5.12.7-300.fc29.x86_64 #1 SMP Fri May 28 13:45:39 CST 2021Arch: x86_64Buildversion: v0.12.1LLVM: 7.0.1foreach_sym: yesunsafe uprobe: nobfd: yesbpf_attach_kfunc: yesbcc_usdt_addsem: yesbcc bpf_attach_uprobe refcount: yeslibbpf: yeslibbpf btf dump: yeslibbpf btf dump type decl: yesKernel helpersprobe_read: yesprobe_read_str: yesprobe_read_user: yesprobe_read_user_str: yesprobe_read_kernel: yesprobe_read_kernel_str: yesget_current_cgroup_id: yessend_signal: yesoverride_return: noget_boot_ns: yesdpath: yesKernel featuresInstruction limit: 1000000Loop support: yesbtf (depends on Build:libbpf): yesmap batch (depends on Build:libbpf): yesuprobe refcount (depends on Build:bcc bpf_attach_uprobe refcount): yesMap typeshash: yespercpu hash: yesarray: yespercpu array: yesstack_trace: yesperf_event_array: yesProbe typeskprobe: yestracepoint: yesperf_event: yeskfunc: yesiter:task: yesiter:task_file: yes

基本语法:

{...}: Action 执行代码块
/.../: Filtering 过滤条件
//, /*: 注释

Probes

Alias Type Description
t tracepoint 内核静态探针
U usdt 用户态静态定义探针
k kprobe 内核态动态函数探针
kr kretprobe 内核态动态函数返回值探针
f kfunc 基于BPF的内核态动态函数探针
fr kretfunc 基于BPF的内核态动态函数返回值探针
u uprobe 用户态函数探针
ur uretprobe 用户态函数返回值探针
s software 内核软件事件
h hardware 基于硬件计数器的探针
w watchpoint 基于内存的监测点事件
p profile 对所有CPU进行时间采样
i interval 周期性报告(从一个CPU)
iter 遍历跟踪内核对象
BEGIN bpftrace 启动执行动作
END bpftrace 退出执行动作

列出bpftrace支持的探针

$ bpftrace -l
$ bpftrace -l "k:*net*"
$ bpftrace -l "k:tcp*"
$ bpftrace -l "kprobe:*net*"
$ bpftrace -l "f:tcp*"
$ bpftrace -l "kfunc:tcp*"
$ bpftrace -l "t:*"
$ bpftrace -l "tracepoint:*"
$ bpftrace -l "tracepoint:net:*"
$ bpftrace -l "tracepoint:syscalls:*"
$ bpftrace -l "tracepoint:syscalls:sys_enter_*"
$ bpftrace -l 'tracepoint:sock:*'
tracepoint:sock:inet_sock_set_state
tracepoint:sock:sock_exceed_buf_limit
tracepoint:sock:sock_rcvqueue_full

列出 tracepoint 函数调用参数

$ bpftrace  -lv tracepoint:net:netif_receive_skb
tracepoint:net:netif_receive_skbvoid * skbaddrunsigned int len__data_loc char[] name$ bpftrace  -lv tracepoint:net:net_dev_xmit
tracepoint:net:net_dev_xmitvoid * skbaddrunsigned int lenint rc__data_loc char[] name

列出内核 struct 结构体数据:

$ bpftrace -lv "struct path"
struct path {struct vfsmount *mnt;struct dentry *dentry;
};
$ bpftrace  -lv "struct sock"
$ bpftrace  -lv "struct sock_common"

列出 kprobe/kfunc 函数调用参数

通过内核 vmlinux 检查 kprobe 函数调用参数,
# gdb -q  ~/rpmbuild/BUILD/kernel-5.12.7/linux-5.12.7-300.fc29.x86_64/vmlinux --ex 'p tcp_set_state'
Reading symbols from /root/rpmbuild/BUILD/kernel-5.12.7/linux-5.12.7-300.fc29.x86_64/vmlinux...done.
$1 = {void (struct sock *, int)} 0xffffffff81a40730 <tcp_set_state>
(gdb) q# grep tcp_set_state /usr/src/kernels/5.12.7-300.fc29.x86_64/include/* -r
/usr/src/kernels/5.12.7-300.fc29.x86_64/include/net/tcp.h:void tcp_set_state(struct sock *sk, int state);$ bpftrace  -lv "kfunc:tcp_set_state"
kfunc:tcp_set_statestruct sock * skint state$ bpftrace  -e 'kprobe:tcp_set_state { printf("%p %d\n", arg0, arg1); }'

内核动态探针 kprobe/kretprobe/kfunc/kretfunc

可对内核函数开始或结束位置进行动态跟踪(插桩).

示例1:

$ cat ./vfs_open.bt
#!/usr/bin/env bpftrace
#include <linux/path.h>
#include <linux/dcache.h>kprobe:vfs_open
{printf("open path: %s\n", str(((struct path *)arg0)->dentry->d_name.name));
}

跟踪 kprobe:vfs_open()函数,将vfs_open 第一个参数打开的目录路径arg0转换为(struct path *)并输出.

$ bpftrace -lv 'f:vfs_open'
kfunc:vfs_openconst struct path * pathstruct file * fileint retval$ sudo ./vfs_open.bt
Attaching 1 probe...
open path: cat
open path: ld-2.28.so
open path: ld.so.cache
open path: libc-2.28.so
open path: locale-archive
open path: tcpstates.bt
open path: ls
open path: ld-2.28.so
open path: ld.so.cache
open path: libselinux.so.1
open path: libcap.so.2.25
open path: libc-2.28.so
open path: libpcre2-8.so.0.8.0
open path: libdl-2.28.so
open path: libpthread-2.28.so
open path: locale-archive
open path: tools
open path: interrupts
open path: stat
^C

示例2:
统计 vfs_read 每次执行耗时分布:

$ bpftrace -e 'kprobe:vfs_read { @start[tid] = nsecs; } kretprobe:vfs_read /@start[tid]/ { @ns[comm] = hist(nsecs - @start[tid]); delete(@start[tid]); }'
Attaching 2 probes...
^C@ns[NetworkManager]:
[2K, 4K)               1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|@ns[pmdaxfs]:
[512, 1K)              3 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[1K, 2K)               1 |@@@@@@@@@@@@@@@@@                                   |
[2K, 4K)               2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                  |
[4K, 8K)               0 |                                                    |
[8K, 16K)              0 |                                                    |
[16K, 32K)             0 |                                                    |
[32K, 64K)             0 |                                                    |
[64K, 128K)            1 |@@@@@@@@@@@@@@@@@                                   |@ns[pmcd]:
[512, 1K)              1 |@@@@@@@@@@                                          |
[1K, 2K)               5 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[2K, 4K)               1 |@@@@@@@@@@                                          |
[4K, 8K)               0 |                                                    |
[8K, 16K)              0 |                                                    |
[16K, 32K)             1 |@@@@@@@@@@                                          |@ns[cat]:
[512, 1K)              6 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[1K, 2K)               2 |@@@@@@@@@@@@@@@@@                                   |
[2K, 4K)               2 |@@@@@@@@@@@@@@@@@                                   |
[4K, 8K)               1 |@@@@@@@@                                            |
[8K, 16K)              0 |                                                    |
[16K, 32K)             0 |                                                    |
[32K, 64K)             0 |                                                    |
[64K, 128K)            0 |                                                    |
[128K, 256K)           0 |                                                    |
[256K, 512K)           1 |@@@@@@@@                                            |@ns[in:imjournal]:
[512, 1K)              2 |@@@                                                 |
[1K, 2K)              31 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[2K, 4K)               1 |@                                                   |@ns[pmdakvm]:
[1K, 2K)              40 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[2K, 4K)               2 |@@                                                  |@ns[bash]:
[512, 1K)              8 |@@@@@@@@@@                                          |
[1K, 2K)               5 |@@@@@@                                              |
[2K, 4K)              39 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[4K, 8K)               1 |@                                                   |
[8K, 16K)              2 |@@                                                  |
[16K, 32K)             6 |@@@@@@@@                                            |
[32K, 64K)             0 |                                                    |
[64K, 128K)            0 |                                                    |
[128K, 256K)           1 |@                                                   |
[256K, 512K)           1 |@                                                   |
[512K, 1M)             1 |@                                                   |@ns[ls]:
[512, 1K)             58 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[1K, 2K)              31 |@@@@@@@@@@@@@@@@@@@@@@@@@@@                         |
[2K, 4K)               7 |@@@@@@                                              |@ns[sshd]:
[1K, 2K)              46 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@                        |
[2K, 4K)              84 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[4K, 8K)               4 |@@                                                  |
[8K, 16K)             11 |@@@@@@                                              |
[16K, 32K)             2 |@                                                   |@ns[pmdalinux]:
[256, 512)            25 |@@@@@@@@@@@@@@@@@                                   |
[512, 1K)             58 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@           |
[1K, 2K)              23 |@@@@@@@@@@@@@@@@                                    |
[2K, 4K)              17 |@@@@@@@@@@@@                                        |
[4K, 8K)              21 |@@@@@@@@@@@@@@                                      |
[8K, 16K)             73 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[16K, 32K)             4 |@@                                                  |
[32K, 64K)             9 |@@@@@@                                              |
[64K, 128K)            4 |@@                                                  |
[128K, 256K)           1 |                                                    |@ns[irqbalance]:
[256, 512)             7 |@@@                                                 |
[512, 1K)              9 |@@@@                                                |
[1K, 2K)              52 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@                        |
[2K, 4K)               4 |@@                                                  |
[4K, 8K)              78 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@         |
[8K, 16K)             94 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[16K, 32K)             6 |@@@                                                 |
[32K, 64K)             5 |@@                                                  |
[64K, 128K)            5 |@@                                                  |@ns[pmdaproc]:
[512, 1K)              3 |                                                    |
[1K, 2K)               0 |                                                    |
[2K, 4K)             389 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[4K, 8K)              42 |@@@@@                                               |
[8K, 16K)              3 |                                                    |@start[1905]: 1922797996393161
@start[1907]: 1922797996743168
@start[1904]: 1922798001240070
@start[1906]: 1922798017500978
@start[5624]: 1922821038865193
@start[19276]: 1922821050726967

内核静态探针 Tracepoints

示例:

1. Listing probes
bpftrace -l 'tracepoint:syscalls:sys_enter_*'2. Hello world
bpftrace -e 'BEGIN { printf("hello world\n"); }'3. File opens
bpftrace -e 'tracepoint:syscalls:sys_enter_open { printf("%s %s\n", comm, str(args->filename)); }'4. Syscall counts by process
bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'5. Distribution of read() bytes
bpftrace -e 'tracepoint:syscalls:sys_exit_read /pid == 18644/ { @bytes = hist(args->retval); }'6. Kernel dynamic tracing of read() bytes
bpftrace -e 'kretprobe:vfs_read { @bytes = lhist(retval, 0, 2000, 200); }'7. Timing read()s
bpftrace -e 'kprobe:vfs_read { @start[tid] = nsecs; }kretprobe:vfs_read /@start[tid]/ { @ns[comm] = hist(nsecs - @start[tid]); delete(@start[tid]); }'8. Count process-level events
bpftrace -e 'tracepoint:sched:sched* { @[name] = count(); } interval:s:5 { exit(); }'9. Profile on-CPU kernel stacks
bpftrace -e 'profile:hz:99 { @[stack] = count(); }'10. Scheduler tracing
bpftrace -e 'tracepoint:sched:sched_switch { @[stack] = count(); }'11. Block I/O tracing
bpftrace -e 'tracepoint:block:block_rq_complete { @ = hist(args->nr_sector * 512); }'

inet_sock_set_state

tracepoint:sock:inet_sock_set_state:

$ bpftrace -lv t:sock:inet_sock_set_state
tracepoint:sock:inet_sock_set_stateconst void * skaddrint oldstateint newstate__u16 sport__u16 dport__u16 family__u16 protocol__u8 saddr[4]__u8 daddr[4]__u8 saddr_v6[16]__u8 daddr_v6[16]
$ bpftrace  -e 'tracepoint:sock:inet_sock_set_state { printf("%d %d\n", args->oldstate, args->newstate); }'
Attaching 1 probe...
7 2
2 1
10 3
3 1
7 2
2 1
1 4
4 11
11 7
1 4
1 8
8 9
4 5
5 7
9 7$ bpftrace  -e 'tracepoint:sock:inet_sock_set_state { printf("%-15s %-15s %d %d\n", ntop(2, args->saddr), ntop(2, args->daddr), args->oldstate, args->newstate); }'

用户态函数探针 uprobe/uretprobe

uprobe/uretprobe 分别为用户态函数调用和函数返回探针:

uprobe: arg0, arg1, ..., argN
uretprobe: retval

以下示例演示跟踪用户态主函数main:

# cat /root/wrks/test.c
#include <stdio.h>int main(int argc, char **argv)
{printf("hello world!\n");return 0;
}# gcc -g test.c -o test

通过用户态函数地址跟踪

# objdump -tT test |grep main
0000000000000000       F *UND*  0000000000000000              __libc_start_main@@GLIBC_2.2.5
0000000000401126 g     F .text  0000000000000020              main
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 __libc_start_main
$ bpftrace -e 'uprobe:/root/wrks/test:0x401126 { printf("test\n");}'
Attaching 1 probe...
# /root/wrks/test
hello world!
$ bpftrace -e 'uprobe:/root/wrks/test:0x401126 { printf("test\n");}'
Attaching 1 probe...
test
^C

通过用户态函数名称跟踪

# objdump  -d test
...
0000000000401126 <main>:401126:   55                      push   %rbp401127:  48 89 e5                mov    %rsp,%rbp40112a: 48 83 ec 10             sub    $0x10,%rsp40112e:    89 7d fc                mov    %edi,-0x4(%rbp)401131:   48 89 75 f0             mov    %rsi,-0x10(%rbp)401135:  bf 10 20 40 00          mov    $0x402010,%edi40113a:    e8 f1 fe ff ff          callq  401030 <puts@plt>40113f:  b8 00 00 00 00          mov    $0x0,%eax401144: c9                      leaveq 401145:  c3                      retq   401146:  66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)40114d:  00 00 00
...
$ bpftrace -e 'uprobe:/root/wrks/test:main { printf("test\n");}'
Attaching 1 probe...
test$ bpftrace -e 'uprobe:/root/wrks/test:main { printf("arg0: %d\n", arg0);}'
Attaching 1 probe...
arg0: 1

unsafe

基于硬件计数器的探针 hardware

当前系统支持的硬件计数器:

$ bpftrace  -lv 'h:*'
hardware:backend-stalls:
hardware:branch-instructions:
hardware:branch-misses:
hardware:bus-cycles:
hardware:cache-misses:
hardware:cache-references:
hardware:cpu-cycles:
hardware:frontend-stalls:
hardware:instructions:
hardware:ref-cycles:

示例 - 统计30秒内cache-missed次数超过1000000的进程

bpftrace -e 'hardware:cache-misses:1000000 { @[pid] = count(); } interval:s:30 { exit(); }'

其他示例

kstack

分析内核实时函数栈, 统计ip_output 调用栈:

$ bpftrace -e 'kprobe:ip_output { @[kstack()] = count(); } interval:s:10 { exit(); }'
Attaching 2 probes......
@[ip_output+1__ip_queue_xmit+349__tcp_transmit_skb+2718tcp_write_xmit+971tcp_tsq_handler+57tcp_tasklet_func+205tasklet_action_common.isra.18+102__do_softirq+223irq_exit_rcu+218common_interrupt+127asm_common_interrupt+30cpuidle_enter_state+219cpuidle_enter+41do_idle+573cpu_startup_entry+25start_secondary+273secondary_startup_64_no_verify+194
]: 8
@[ip_output+1__ip_queue_xmit+349__tcp_transmit_skb+2718tcp_write_xmit+971__tcp_push_pending_frames+50tcp_sendmsg_locked+3206tcp_sendmsg+39sock_sendmsg+84sock_write_iter+140new_sync_write+376vfs_write+445ksys_write+157do_syscall_64+51entry_SYSCALL_64_after_hwframe+68
]: 45
...
#  bpftrace -e 'kprobe:ip_output { @[kstack(3)] = count(); }'
Attaching 1 probe...
^C@[ip_output+1__ip_queue_xmit+349__tcp_transmit_skb+2718
]: 54

tcp_sendmsg

$ bpftrace -e 'k:tcp_sendmsg { @size = hist(arg2); } interval:s:10 { exit(); }'
Attaching 2 probes...@size:
[32, 64)               6 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                     |
[64, 128)              2 |@@@@@@@@@@                                          |
[128, 256)             5 |@@@@@@@@@@@@@@@@@@@@@@@@@@                          |
[256, 512)            10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[512, 1K)              1 |@@@@@                                               |#bpftrace -e 'kr:tcp_sendmsg { @retvals[retval > 0 ? 0 : retval] = count(); } interval:s:30 { exit(); }'
Attaching 2 probes...@retvals[0]: 148
#!/usr/local/bin/bpftrace#include <net/sock.h>k:tcp_sendmsg
{@sk[tid] = arg0;@size[tid] = arg2;
}kr:tcp_sendmsg
/@sk[tid]/
{$sk = (struct sock *)@sk[tid];$size = @size[tid];$af = $sk->__sk_common.skc_family;if ($af == AF_INET) {$daddr = ntop($af, $sk->__sk_common.skc_daddr);$saddr = ntop($af, $sk->__sk_common.skc_rcv_saddr);$lport = $sk->__sk_common.skc_num;$dport = $sk->__sk_common.skc_dport;$dport = ($dport >> 8) | (($dport << 8) & 0xff00);printf("%-15s %-5d -> %-15s %-5d: %d bytes, retval %d\n",$saddr, $lport, $daddr, $dport, $size, retval);} else {printf("IPv6...\n");}delete(@sk[tid]);delete(@size[tid]);
}
# ./tcp_sendmsg.bt Attaching 2 probes...10.0.0.65       49978 -> 52.37.243.173   443  : 63 bytes, retval 63127.0.0.1       58566 -> 127.0.0.1       22   : 36 bytes, retval 36127.0.0.1       22    -> 127.0.0.1       58566: 36 bytes, retval 36[...]
监控tcp_sendmsg发送大于8192字节进程pid
bpftrace -e 'k:tcp_sendmsg /arg2 > 8192/ { printf("PID %d: %d bytes\n", pid, arg2); }'统计调用tcp_sendmsg进程发送字节分布
bpftrace -e 'k:tcp_sendmsg { @size[pid, comm] = hist(arg2); }'
Attaching 1 probe...
^C@size[2326, sshd]:
[32, 64)              22 |@@@@@@@@@@@@@@@@@@@                                 |
[64, 128)             19 |@@@@@@@@@@@@@@@@                                    |
[128, 256)            59 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[256, 512)            33 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                       |统计tcp_sendmsg 返回值分布
bpftrace -e 'kr:tcp_sendmsg { @return[retval] = count(); }'每秒统计tcp_sendmsg 调用次数&发送总计&平均字节
bpftrace -e 'k:tcp_sendmsg { @size = stats(arg2); }  interval:s:1 { print(@size); clear(@size); }'统计 tcp_sendmsg 调用栈分布
bpftrace -e 'k:tcp_sendmsg { @[kstack] = count(); }'限制调用栈层次为3层, 统计 tcp_sendmsg 调用栈分布
bpftrace -e 'k:tcp_sendmsg { @[kstack(3)] = count(); }'bpftrace -e 'k:tcp_sendmsg { @ts[tid] = nsecs; }kr:tcp_sendmsg /@ts[tid]/ { @ns = hist(nsecs - @ts[tid]); delete(@ts[tid]); }'
Attaching 2 probes...
^C@ns:
[512, 1K)             21 |@                                                   |
[1K, 2K)              14 |@                                                   |
[2K, 4K)             291 |@@@@@@@@@@@@@@@@@@@@@@@@@@                          |
[4K, 8K)             574 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[8K, 16K)             33 |@@                                                  |
[16K, 32K)             5 |                                                    |@ts[1614]: 1826887636941576

hrtimer_start

统计每个hrtimer_start函数的参数调用频率

$ bpftrace -lv 't:timer:hrtimer_start'
tracepoint:timer:hrtimer_startvoid * hrtimervoid * functions64 expiress64 softexpiresenum hrtimer_mode mode
$ bpftrace -e 't:timer:hrtimer_start { @[ksym(args->function)] = count(); }'
Attaching 1 probe...
^C@[timerfd_tmrproc]: 5
@[posix_timer_fn]: 8
@[it_real_fn]: 13
@[watchdog_timer_fn]: 256
@[hrtimer_wakeup]: 431
@[tick_sched_timer]: 22141

Reference

Kernel analysis with bpftrace
bpftrace Reference Guide
bpftrace Install Guide
bpftrace Cheat Sheet
BPF Performance Tools (book)
Linux Extended BPF (eBPF) Tracing Tools
tutorial_one_liners_chinese
Tracing a packet journey using Linux tracepoints, perf and eBPF
https://github.com/yadutaf/tracepkt

bpftrace 使用笔记相关推荐

  1. BPF学习笔记(五)--Systemtap BPF/BCC bpftrace 实践对比

    文章目录 1. 使用BPF/BCC 1.1在centos8操作系统上安装对应的软件二进制包 1.2 源码包安装 1.3 程序示例 2. Systemtap 2.1安装 systemtap 2.2 St ...

  2. 【读书笔记】知易行难,多实践

    前言: 其实,我不喜欢看书,只是喜欢找答案,想通过专业的解答来解决我生活的困惑.所以,我听了很多书,也看了很多书,但看完书,没有很多的实践,导致我并不很深入在很多时候. 分享读书笔记: <高效1 ...

  3. 【运维学习笔记】生命不息,搞事开始。。。

    001生命不息,搞事不止!!! 这段时间和hexesdesu搞了很多事情! 之前是机械硬盘和固态硬盘的测速,我就在那默默的看着他一个硬盘一个机械测来测去. 坐在他后面,每天都能看到这位萌萌的小男孩,各 ...

  4. SSAN 关系抽取 论文笔记

    20210621 https://zhuanlan.zhihu.com/p/353183322 [KG笔记]八.文档级(Document Level)关系抽取任务 共指id嵌入一样 但是实体嵌入的时候 ...

  5. pandas以前笔记

    # -*- coding: utf-8 -*- """ Created on Sat Jul 21 20:06:20 2018@author: heimi "& ...

  6. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  7. 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  8. 容器云原生DevOps学习笔记——第二期:如何快速高质量的应用容器化迁移

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  9. 王道考研 计算机网络笔记 第六章:应用层

    本文基于2019 王道考研 计算机网络: 2019 王道考研 计算机网络 个人笔记总结 第一章:王道考研 计算机网络笔记 第一章:概述&计算机网络体系结构 第二章:王道考研 计算机网络笔记 第 ...

  10. 王道考研 计算机网络笔记 第五章:传输层

    本文基于2019 王道考研 计算机网络: 2019 王道考研 计算机网络 个人笔记总结 第一章:王道考研 计算机网络笔记 第一章:概述&计算机网络体系结构 第二章:王道考研 计算机网络笔记 第 ...

最新文章

  1. 数据工程师生存必备工具!
  2. MacOS 安装monkey教程
  3. MXNet 安装 Windows
  4. linux内核mtd分区,linux-kernel – ubifs卷与mtd分区
  5. vert.x_选择Vert.x的3个理由
  6. oracle9i 是否安全,指纹识别与Oracle 9i安全特性解析
  7. Eclipse错误:Syntax error on tokens, delete these tokens问题解决
  8. ISE使用中RAM IP核配置及ram测试(两种测试)
  9. Android 项目中用得最多最火的第三方框架可能都在这里了
  10. vasp计算脚本放在服务器的位置,vasp计算所需服务器配置
  11. 北航计算机组成原理课程设计-2020秋 PreProject-Logisim-时序逻辑电路
  12. proteus软件安装包8.11
  13. 人工智能产生式系统动物识别实验python
  14. 毁掉一家公司最好的方式,就是跟员工讨价还价
  15. matlab矩阵的白化,白化原理及Matlab实现
  16. 建立你的第一个vue程序
  17. Android圆盘刻度,类似体重测试仪,效果不错哦
  18. python中如何打开csv文件_Python如何读取csv文件
  19. 4. 假设一年期定期利率为 3.25%,计算一下需要过多少年,一万元的一年定期存款连本带息能翻番?
  20. 【微信小程序】横向/纵向布局(98/100)

热门文章

  1. Controller类中方法返回值详解
  2. Win7下 安全、彻底删除Orcale数据库
  3. [2018.10.23 T3] 新的家园
  4. shell中算术运算、相加减
  5. php 页面字体大小,CSS_做网页字体大小参考 网页中同字号字体的不同单位对比列表,对于WEB前端页面开发,字体大 - phpStudy...
  6. mysql忽略大小写 chmod_Ubuntu18.04下Mysql8.0.15关闭大小写敏感
  7. 不能bostype没有元数据异常_金蝶EAS - BOS工作笔记
  8. python开发环境一般用哪个_python开发环境哪个好用?如何搭建?
  9. 使用rem单位布局的时候有什么好处_好程序员web前端技术分享移动端页面布局
  10. 树莓派python智能家居_用树莓派DIY一个智能家居服务器