0. bpftrace

Alastair 与2016.12创建了bpftrace。bpftrace 是一款基于BPF和BCC的开源跟踪器。其自带了许多多性能工具和支持文档,同时提供了一个高级编程语言环境,可以用来创建强大的单行程序和小工具。

0.1 bpftrace组件

在安装bpftrace的时候,其会存在以下的目录树。其中提供了工具的文档、man帮助文档、示例文件等等。

├── docs		# 参考手册 单行小程序指引
├── libbpf # 库文件
├── src # 前端
│ └── ast #中间代码生成
├── man
│ ├── adoc
│ └── man8 # 帮助文档
├── README
├── INSTALL
└── tools # 工具和实例
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

0.2 bpftrace 帮助信息

使用-h参数以获取帮助信息

[root@bogon bpftrace]# bpftrace -h
USAGE:
bpftrace [options] filename
bpftrace [options] - <stdin input>
bpftrace [options] -e 'program' OPTIONS:

-B MODE output buffering mode ('full', 'none')

-f FORMAT output format ('text', 'json')

-o file redirect bpftrace output to file

-d debug info dry run

-dd verbose debug info dry run

-e 'program' execute this program

-h, --help show this help message

-I DIR add the directory to the include search path

--include FILE add an #include file before preprocessing

-l [search] list probes

-p PID enable USDT probes on PID

-c 'CMD' run CMD and enable USDT probes on resulting process

--usdt-file-activation

activate usdt semaphores based on file path

--unsafe allow unsafe builtin functions

-q keep messages quiet

-v verbose messages

--info Print information about kernel BPF support

-k emit a warning when a bpf helper returns an error (except read functions)

-kk check all bpf helper functions

-V, --version bpftrace version

--no-warnings disable all warning messages ENVIRONMENT:

BPFTRACE_STRLEN [default: 64] bytes on BPF stack per str()

BPFTRACE_NO_CPP_DEMANGLE [default: 0] disable C++ symbol demangling

BPFTRACE_MAP_KEYS_MAX [default: 4096] max keys in a map

BPFTRACE_CAT_BYTES_MAX [default: 10k] maximum bytes read by cat builtin

BPFTRACE_MAX_PROBES [default: 512] max number of probes

BPFTRACE_LOG_SIZE [default: 1000000] log size in bytes

BPFTRACE_PERF_RB_PAGES [default: 64] pages per CPU to allocate for ring buffer

BPFTRACE_NO_USER_SYMBOLS [default: 0] disable user symbol resolution

BPFTRACE_CACHE_USER_SYMBOLS [default: auto] enable user symbol cache

BPFTRACE_VMLINUX [default: none] vmlinux path used for kernel symbol resolution

BPFTRACE_BTF [default: none] BTF file EXAMPLES:

bpftrace -l 'sleep'

list probes containing "sleep"

bpftrace -e 'kprobe:do_nanosleep { printf("PID %d sleeping...\n", pid); }'

trace processes calling sleep

bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'

count syscalls by process name
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

0.3 bpftrace 工具速览表

应用场景 工具名称 使用场景及用法
CPU execsnoop.bt

0.4 bpftrace 探针

类型 缩写 描述
tracepoint t 内核静态插桩点
usdt U 用户静态插桩点
kprobe k 内核动态函数插桩点
kretprobe kr 内核动态函数返回值插桩点
uprobe u 用户动态函数插桩点
uretprobe ur 用户动态函数返回值插桩点
software s 内核软件事件
hardware h 硬件基于计数器的插桩
profile p 对全部cpu进行采样
interval i 一个cpu上周期性报告
BEGIN 启动
END 退出

0.4.1 tracepoint

tracepoint 探针类型会对内核跟踪点进行插桩,格式如下:

# tracepoint_name 是跟踪点全名,包括用来将跟踪点所在列和事件名字分割开的冒号
tracepoint:tracepoint_name
  • 1
  • 2

跟踪点通常是带有参数的:bpftrace 可以通过内置变量args来访问这些参数信息。假如说我们访问的跟踪点有一个代表数据包长度的参数,名称为len,我们可以用agrs->len来访问这个变量。而一个跟踪点具体具有哪些参数则是可以bpftrace的-lv参数来进行查看:

[root@bogon ik]# bpftrace -lv tracepoint:syscalls:sys_enter_read
tracepoint:syscalls:sys_enter_read
int __syscall_nr
unsigned int fd
char * buf
size_t count
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

我们可以看到这里跟man参数文档描述的其实是不一致的,这里会多一个系统调用号__syscall_nr

ssize_t read(int fd,void *buf,size_t count)
  • 1

0.4.2 usdt

udst探针对用户态静态探针点进行插桩。格式如下:

usdt:binary_path:probe_name
usdt:libary_path:probe_name
usdt:binary_path:namespace:probe_name
usdt:libary_path:namespace:probe_name
  • 1
  • 2
  • 3
  • 4

比如说我们定义了如下的函数:

// 会编译成可执行文件test
namespace bpf_method{
void bpf_test();
}
  • 1
  • 2
  • 3
  • 4

那么对这个函数来说,其探针可以表述usdt:./test:bpf_method:bpf_test。另外,如果是在不确定的话,我们可以使用-l参数列出当前二进制文件之中所有可用的usdt探针。

# 这里存疑,笔者并没有实验成功
bpftrace -l 'usdt:/usr/local/cpython/python'
  • 1
  • 2

除此之外,我们还可以使用 -p pid的方式列出正在运行的程序其支持usdt类型探针:

bpftrace -lp 2266 | grep usdt

usdt:/proc/2266/root/usr/lib64/libc-2.28.so:libc:memory_sbrk_more

usdt:/proc/2266/root/usr/lib64/libc-2.28.so:libc:memory_tcache_double_free

usdt:/proc/2266/root/usr/lib64/libc-2.28.so:libc:memory_tunable_tcache_count

usdt:/proc/2266/root/usr/lib64/libc-2.28.so:libc:memory_tunable_tcache_max_bytes

usdt:/proc/2266/root/usr/lib64/libc-2.28.so:libc:memory_tunable_tcache_unsorted_limit

usdt:/proc/2266/root/usr/lib64/libc-2.28.so:libc:setjmp

[...]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

0.4.3 kprobe和kretprobe

这种探针类型用于内核的动态插桩,格式如下:

kprobe:function_name
kretprobe:function_name
  • 1
  • 2

kprobe对函数的开始进行插桩,其参数arg0,arg1,arg2…是进入函数时的参数,类型均为64位无符号整数。如果其是指向C结构体的指针,可以进行强制转换; kretprobe对函数的结束进行插桩,其内置参数retval是函数的返回值,类型永远是64位无符号整型,如果和上述整型不一致,需要通过类型强制转换为对应的类型

0.4.4 uprobe和uretprobe

这种探针类型用于用户态的动态插桩,格式如下:

uprobe:binary_path:function_name
uprobe:libary_path:function_name
uretprobe:binary_path:function_name
uretprobe:libary_path:function_name
  • 1
  • 2
  • 3
  • 4

uprobe对函数的开始进行插桩,其参数arg0,arg1,arg2…是进入函数时的参数,类型均为64位无符号整数。如果其是指向C结构体的指针,可以进行强制转换; uretprobe对函数的结束进行插桩,其内置参数retval是函数的返回值,类型永远是64位无符号整型,如果和上述整型不一致,需要通过类型强制转换为对应的类型

0.4.5 software和hardware

这些探针的类型是预先定义好的软件事件和硬件事件,类型如下:

software:event_name
software:event_name:count
hardware:event_name
hardware:event_name:count
  • 1
  • 2
  • 3
  • 4

这些事件跟跟踪点是类似的,不过更适合于基于计数器的指标和基于采样的探测。由于事件的频闭可能很高,所以这里存在一个count字段,当每发生count此事件之后,才会触发一次探针。如果没有指定count,则会采用默认的频率。

0.4.6 profile和interval

这些是基于定时器的事件,格式如下:

profile:hz:rate
profile:s:rate
profile:ms:rate
profile:us:rate
interval:s:rate
interval:ms:rate
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

profile类型会在全部cpu之上进行激活,可以用作对CPU的使用进行采样;interval类型只在单个CPU上激活,可以用于周期性的打印输出。比如说profile:hz:100就表示100hz周期会激活一次对CPU使用的采样。

1. 安装bpftrace

  • centos
curl https://repos.baslab.org/bpftools.repo --output /etc/yum.repos.d/bpftools.repo

sudo yum install bpftrace bpftrace-tools
  • 1
  • 2
  • 3
  • ubuntu
sudo apt-get update
sudo apt-get install bpftrace
  • 1
  • 2

2. bpftrace 工具

2.1 bpftrace 编程

下面是个bpftrace编程的例子,其展示了bpftrace 编程的基本结构:

# 指定解释器
#!/usr/local/bin/bpftrace # 定义的探针1

kprobe:vfs_read

{

# 将当前进程调用vfs_read 的时间放入一个名为start的map之中

@start[tid] = nsecs;

} # 定义的探针2

kretprobe:vfs_read

# 过滤start 这个map,获取tid这一项

/@start[tid]/

{

# 获取执行时间

\(duration_us</span> <span class="token operator">=</span> <span class="token punctuation">(</span>nsecs - @start<span class="token punctuation">[</span>tid<span class="token punctuation">]</span><span class="token punctuation">)</span> / <span class="token number">1000</span><span class="token punctuation">;</span>
<span class="token comment"># 执行时间放入直方图的bucket之中</span>
@us <span class="token operator">=</span> hist<span class="token punctuation">(</span><span class="token variable">\)duration_us);

# 删除map中这个元素

delete(@start[tid]);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

下面是上面这个文件的输出展示,vfs_exec_time.bt是存放上面代码的文件,bt后缀只是为了辨别:

[root@bogon bpftrace]# bpftrace vfs_exec_time.bt
Attaching 2 probes...
^C
@start[6165]: 6928640480723
@us:
[0] 185 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[1] 56 |@@@@@@@@@@@@@@@ |
[2, 4) 91 |@@@@@@@@@@@@@@@@@@@@@@@@@ |
[4, 8) 44 |@@@@@@@@@@@@ |
[8, 16) 1 | |
[16, 32) 3 | |
[32, 64) 2 | |
[64, 128) 0 | |
[128, 256) 0 | |
[256, 512) 0 | |
[512, 1K) 0 | |
[1K, 2K) 1 | |
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2.1.1 bpftrace 用法

bpftrace主要有单行程序和批处理两种用法:

# bpftrace 单行程序
bpftrace -e 'program'
  • 1
  • 2

-e 参数表示bpftrace会执行program,并开始跟踪其中定义的所有时间。程序会持续运行,直达Ctrl+C组合键被按下或者程序显示的调用exit()为止。

bpftrace file.bt
  • 1

程序还可被保存到一个文件之中,然后使用bpftrace来执行。或者我们也可以使用chmod +x file.bt 来赋予文件可执行权限,这样就可以像其他任何程序一样运行。

2.1.2 程序结构

bpftrace程序的结构是一系列探针+对应的动作,当探针被激活后,相应的动作就会被执行。

probe { actions }
  • 1

: 动作
动作既可以是单条语句,也可以是使用分号分割的多条语句{ action1,action2、action3... }

probe /filter_pattern/ { actions }
  • 1

: 过滤器
filter_pattern是个布尔表达式,其会决定一个动作是否被执行,比如说pid==123表示只有进程123触碰探针才会执行动作。同时,在布尔表达式中也可以运用 &&||等布尔运算符

如果我们希望对多个探针实行同一动作处理,可以在探针之间加上,来分割,如下:

probe1,probe2,... { actions }
  • 1

同时,探针也支持通配符,如下:

# 匹配probe1、probeabc等等...
probe* { actions }
  • 1
  • 2

2.1.3 探针格式

探针以类型名字开始,然后是一系列以:为分隔的标识符:

# ...表示可选
type:identifier1[:identifier2[...]]
  • 1
  • 2

一般来说,内核探针kprobe探针类型对内核态函数进行插桩,只需要一个标识符:内核函数名。uprobe探针类型对用户态函数进行插桩,需要两个标识符: 二进制文件的路径和函数名

2.1.4 变量

在bpftrace之中有三种类型的变量:

  • 内置变量:由bpftrace定义,通常是个只读的信息源,主要有以下几种:
变量 作用
pid 进程id
comm 进程名称
nsecs 时间戳(纳秒)
curtask 当前线程的 task_struct 结构体
  • 临时变量:可以用于临时的计算,以$作为前缀
# 定义变量x并赋值1
$x = 1
  • 1
  • 2
  • 映射表变量:使用BPF映射表来存储对象,名字带有@前缀,可以用于全局存储,在不同动作之间传递数据。
# 定义全局变量a 并赋值1
probe1 { @a = 1;} # 定义array这个映射表,其为数组,给数组中对应的元素赋值

probe2 { @array[tid] = nsecs} # 复合数组映射表

probe2 { @muti_array[pid,tid] = nsecs}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.1.5 控制流

bpftrace支持三种控制流:filter、ternarg和if语句,这些都依靠布尔表达式来有条件的改变对程序执行的流向。

2.1.5.1 filter

probe /filter_pattern/ { actions }
  • 1

: 过滤器
filter_pattern是个布尔表达式,其会决定一个动作是否被执行,比如说pid==123表示只有进程123触碰探针才会执行动作。同时,在布尔表达式中也可以运用 &&||等布尔运算符

2.1.5.2 if 语句

bpftrace的 if 语法如下:

if (test) {
actions
} if (test) {

actions

} else {

other_actions

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2.1.5.3 unroll 循环语句

由于bpftrace运行在受限的环境中,所以这里使用了unroll语句来保证循环时有限的。

2.1.5 函数

bpftrace 的内置函数主要如下:

函数 类型 作用
exit() 普通函数 退出bpftrace
str(char*) 普通函数 输出一个指针,返回字符串
system(format[,arguments …]) 普通函数 在shell之中运行命令
count() 映射表函数 累计统计
sum($var) 映射表函数 求和
hist($var) 映射表函数 直方图展示
delete($var) 映射表函数 删除映射表元素

2.2 bpftrace 示例

2.2.1 单行程序示例

  • hello world:
bpftrace -e 'BEGIN { printf("hello world!\n"); }'
  • 1
[root@bogon bpftrace]# bpftrace -e 'BEGIN { printf("hello world!\n"); }'
Attaching 1 probe...
hello world!
  • 1
  • 2
  • 3
  • 展示系统谁在执行什么命令:
bpftrace -e 'tracepoint:syscalls:sys_enter_execve { printf("%s -> %s\n", comm, str(args->filename)); }'
  • 1
# 在这里,笔者打开了另外一个中断,执行了ls 命令,也就是这里最后一行。
[root@bogon bpftrace]# bpftrace -e 'tracepoint:syscalls:sys_enter_execve { printf("%s -> %s\n", comm, str(args->filename)); }'
Attaching 1 probe...
ksmtuned -> /usr/bin/awk
ksmtuned -> /usr/bin/pgrep
ksmtuned -> /usr/bin/awk
ksmtuned -> /usr/bin/sleep
bash -> /usr/bin/ls
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

: 什么是ksmtuned?
KSM 是一种节省内存的重复数据删除功能,由 CONFIG_KSM=y 启用,在 2.6.32 中添加到 Linux 内核中。
KSM 最初是为与 KVM(在那里称为内核共享内存)一起使用而开发的,通过共享它们之间的公共数据,将更多虚拟机放入物理内存中。但它对于生成相同数据的许多实例的任何应用程序都非常有用。

  • 展示新进程的创建:
bpftrace -e 'tracepoint:syscalls:sys_enter_execve { join(args->argv); }' 
  • 1
# 下面代码中的第一行展示了笔者在另外的终端运行ls的过程,其余代码则是KSM机制所带来的
[root@bogon bpftrace]# bpftrace -e 'tracepoint:syscalls:sys_enter_execve { join(args->argv); }'
Attaching 1 probe...
ls --color=auto
awk /^(MemFree|Buffers|Cached):/ {free += $2}; END {print free} /proc/meminfo
pgrep -d -- ^qemu(-(kvm|system-.+)|:.{1,11})$
awk { sum += $1 }; END { print 0+sum }
sleep 60
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 按照进程统计文件的开启情况:
bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args->filename)); }'
  • 1
[root@bogon bpftrace]# bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args->filename)); }'
Attaching 1 probe...
in:imjournal /run/log/journal/29545612d2ce4e319e6a9edaa0cff1d3/system.journa
systemd-journal /
systemd-journal sys
systemd-journal bus
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

: 什么是systemd-journal?
systemd-journald 是一个收集并存储各类日志数据的系统服务。 它创建并维护一个带有索引的、结构化的日志数据库, 并可以收集来自各种不同渠道的日志:

  1. 通过 kmsg 收集内核日志
  2. 通过 libc 的 syslog(3) 接口收集系统日志
  3. 通过 本地日志接口 sd_journal_print(3) 收集结构化的系统日志
  4. 捕获服务单元的标准输出(STDOUT)与标准错误(STDERR)
  5. 通过内核审计子系统收集审计记录
  • 按照程序统计系统调用次数:
bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'
  • 1
[root@bogon bpftrace]# bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'
Attaching 1 probe...
^C
@[NetworkManager]: 19
@[tuned]: 24
@[sshd]: 24
@[irqbalance]: 40
@[bpftrace]: 67
@[gdbus]: 93
@[in:imjournal]: 673
@[systemd-journal]: 7752
...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 按照探针名字统计系统调用次数:
bpftrace -e 'tracepoint:syscalls:sys_enter_* { @[probe] = count(); }'
  • 1
# 下面的代码会统计运行期间符合‘tracepoint:syscalls:sys_enter_*’ 正则匹配的所有探针的调用次数
[root@bogon bpftrace]# bpftrace -e 'tracepoint:syscalls:sys_enter_* { @[probe] = count(); }'
Attaching 341 probes...
^C
@[tracepoint:syscalls:sys_enter_waitid]: 1
@[tracepoint:syscalls:sys_enter_getpid]: 1
@[tracepoint:syscalls:sys_enter_timerfd_create]: 1
@[tracepoint:syscalls:sys_enter_socket]: 1
@[tracepoint:syscalls:sys_enter_rt_sigreturn]: 1
@[tracepoint:syscalls:sys_enter_munmap]: 2
@[tracepoint:syscalls:sys_enter_mmap]: 2
@[tracepoint:syscalls:sys_enter_sendmsg]: 5
@[tracepoint:syscalls:sys_enter_writev]: 5
@[tracepoint:syscalls:sys_enter_ftruncate]: 5
@[tracepoint:syscalls:sys_enter_inotify_add_watch]: 5
...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 按照进程统计系统调用数量:
bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[pid, comm] = count(); }'
  • 1
[root@bogon bpftrace]# bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[pid, comm] = count(); }'
Attaching 1 probe...
^C
@[3126, gpg-agent]: 1
@[3171, gpg-agent]: 1
@[3139, gpg-agent]: 1
@[985, sssd]: 1
@[1084, tuned]: 2
@[2848, gmain]: 3
@[2751, gmain]: 4
@[698, systemd-journal]: 2178
...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 按照进程展示运行期间内总的读取字节数:
bpftrace -e 'tracepoint:syscalls:sys_exit_read /args->ret/ { @[comm] = sum(args->ret); }'
  • 1
[root@bogon bpftrace]# bpftrace -e 'tracepoint:syscalls:sys_exit_read /args->ret/ { @[comm] = sum(args->ret); }'
Attaching 1 probe...
^C
@[sshd]: 54
@[in:imjournal]: 63
@[gmain]: 188
@[sedispatch]: 756
@[systemd-journal]: 18056
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 按照进程展示read 返回结果大小的分布:
bpftrace -e 'tracepoint:syscalls:sys_exit_read { @[comm] = hist(args->ret); }'
  • 1
[root@bogon ik]# bpftrace -e 'tracepoint:syscalls:sys_exit_read { @[comm] = hist(args->ret); }'
Attaching 1 probe...
^C
@[sshd]:
[2, 4) 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@ |
[4, 8) 0 | |
[8, 16) 0 | |
[16, 32) 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@ |
[32, 64) 2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 展示进程的磁盘IO尺寸:
bpftrace -e 'tracepoint:block:block_rq_issue { printf("%d %s %d\n", pid, comm, args->bytes); }'
  • 1
[root@bogon ik]# bpftrace -e 'tracepoint:block:block_rq_issue { printf("%d %s %d\n", pid, comm, args->bytes); }'
Attaching 1 probe...
# pid name bytes
251 kworker/2:1H 4096
284 kworker/4:1H 0
251 kworker/2:1H 0
288 kworker/7:1H 14848
288 kworker/7:1H 0
3684 kworker/2:0 8
3684 kworker/2:0 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 按照进程展示页换入数量:
bpftrace -e 'software:major-faults:1 { @[comm] = count(); }'
  • 1
[root@bogon ik]# bpftrace -e 'software:major-faults:1 { @[comm] = count(); }'
Attaching 1 probe...
^C
@[sssd_nss]: 2
  • 1
  • 2
  • 3
  • 4
  • 按照进程展示缺页中断数量:
bpftrace -e 'software:faults:1 { @[comm] = count(); }'
  • 1
[root@bogon ik]# bpftrace -e 'software:faults:1 { @[comm] = count(); }'
Attaching 1 probe...
^C
@[systemd-journal]: 5
@[in:imjournal]: 5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 对pid为xxx的进程以yyhz抓取其用户态的调用栈信息:
bpftrace -e 'profile:hz:yy /pid == xxx/ { @[ustack] = count(); }'
  • 1
文章知识点与官方知识档案匹配,可进一步学习相关知识
CS入门技能树Linux入门初识Linux31450 人正在系统学习中

【转帖】bpftrace 指南的更多相关文章

  1. 【转帖】Mysql多维数据仓库指南 第一篇 第1章

     Mysql多维数据仓库指南 第一篇基本原理 章节列表: 第1章:基本组成 第2章:维度历史 第3章:维度可加性 第4章:维度查询 本篇概述 你将运用关系数据库来实施一个维度数据仓库.事实表和维表这两 ...

  2. [转帖]可能是东半球最好的 Curl 学习指南,强烈建议收藏!

    可能是东半球最好的 Curl 学习指南,强烈建议收藏! http://www.itpub.net/2019/09/30/3302/ 记得转帖过.. 简介 curl 是常用的命令行工具,用来请求 Web ...

  3. [转帖]CentOS 6 服务器安全配置指南(通用)

    CentOS 6 服务器安全配置指南(通用) http://seanlook.com/2014/09/07/linux-security-general-settings/  发表于 2014-09- ...

  4. [转帖]2019 简易Web开发指南

    2019 简易Web开发指南     2019年即将到来,各位同学2018年辛苦了. 不管大家2018年过的怎么样,2019年还是要继续加油的! 在此我整理了个人认为在2019仍是或者将成为主流的技术 ...

  5. [转帖]cocos2d-x 3.0rc开发指南:Windows下Android环境搭建

    原文请看:http://blog.csdn.net/linzhengqun/article/details/21663341 鲜红字体请注意:文中红色字体乃是本文博主阳光下的蒲公英添加.红色字体部分造 ...

  6. Nutch相关框架安装使用最佳指南(转帖)

    Nutch相关框架安装使用最佳指南 Chinese installing and using instruction  -  The best guidance in installing and u ...

  7. [转帖]Kubernetes - nginx-ingress 配置跳坑指南

    Kubernetes - nginx-ingress 配置跳坑指南 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https:// ...

  8. [转帖]curl 的用法指南

    curl 的用法指南   作者: 阮一峰 日期: 2019年9月 5日 感谢 腾讯课堂NEXT学院 赞助本站,腾讯官方的前端课程 免费试学. http://www.ruanyifeng.com/blo ...

  9. [转帖]curl网站开发指南

    curl网站开发指南 http://www.ruanyifeng.com/blog/2011/09/curl.html linux 里面有非常多很好的工具 比如这个 curl 之前 以为 wget 就 ...

  10. [转帖]站点部署,IIS配置优化指南

    站点部署,IIS配置优化指南 https://www.cnblogs.com/heyuquan/p/deploy-iis-set-performance-guide.html 挺值得学习的 毕竟之前很 ...

随机推荐

  1. 文心一言 VS 讯飞星火 VS chatgpt (50)-- 算法导论6.2 2题

    二.参考过程 MAX-HEAPIFY,写出能够维护相应最小堆的 MIN-HEAPIFY(A,i)的伪代码,并比较 MIN-HEAPIFY 与 MAX-HEAPIFY 的运行时间. 文心一言: MIN- ...

  2. 学了这么久的高并发编程,连Java中的并发原子类都不知道?

    摘要:保证线程安全是 Java 并发编程必须要解决的重要问题,本文和大家聊聊Java中的并发原子类,看它如何确保多线程的数据一致性. 本文分享自华为云社区<学了这么久的高并发编程,连Java中的 ...

  3. AI新手语音入门:认识词错率WER与字错率CER

    摘要:本文介绍了词错率WER和字错率CER的概念,引入了编辑距离的概念与计算方法,从而推导得到词错率或字错率的计算方法. 本文分享自华为云社区<新手语音入门(一):认识词错率WER与字错率CER ...

  4. Chrome扩展程序导出备份与本地导入浏览器

    现在即使在国内下载个chrome,转个插件也千难万难.现在科学下网也越来越难,由于众所周知的原因,连qiang这个话题都是敏感词.哀默于心死,还是回避这个话题 只要把之前装的chrome打包,然后再重 ...

  5. Axure 多人协作

    创建团队项目 团队 => 从当前文件创建团队项目 签出的文件才能被修改 签出 签入 发布评论 邀请 编辑的5种状态 和SVN差不多的概念 已有项目导入 https://www.bilibili. ...

  6. selenium-web自动化(po模型)

    什么是po模型呢?简单理解就是:把每个页面当成一个对象,给这些页面当成一个类,主要就是完成元素定位和业务操作:把它和测试脚本区分开来,需要什么取这些页面类去调用即可.这样的好处在于页面元素发生变化时, ...

  7. 互联网公司Python高性能编程

    虽然Python一直被吐槽执行速度慢,但是架不住简洁的语法和丰富的第三方库使其能够节省开发时间.众所周知在互联网公司中要求频繁的迭代.快速的上线,而Python的优点就特别适合这种需求,所以Pytho ...

  8. auth认证模块 auth_user表扩展

    目录 auth认证模块前戏 django后台管理功能 创建超级管理员 auth认证相关模块及操作 用户注册 用户登录 网站首页效果 校验用户登录的装饰器 用户修改密码 用户注销登录 auth_user ...

  9. 【每日一题】31.「土」秘法地震 (二维前缀和 / DP)

    补题链接:Here 题意就是要找每一个 \(k * k\) 的小正方形里至少有一个1的数量 显然我们可以通过二维前缀和处理出(1, 1) 到 (n, m) 的数量 然后通过枚举处理出答案,具体思想是容 ...

  10. Serverless 应用托管助力企业加速创新

    作者: 熊峰 | 阿里云技术专家 云原生时代的 Serverless 应用托管架构 回顾过去十年,数字化转型将科技创新与商业元素不断融合.重构,重新定义了新业态下的增长极.商业正在从大工业时代的固化范 ...