为了降低使用 eBPF 的门槛,社区开发了 bcc,bpftrace 等工具,因为 bpftrace 在语法上贴近 awk,所以我一眼就爱上了,本文将通过它来讲解如何用 eBPF 分析 Golang 应用...通过 bpftrace 分析 golang 方法的参数和返回值 下面是演示代码 main.go,我们的目标是通过 bpftrace 分析 sum 方法的输入输出: package main func...,如何用 bpftrace 分析 golang 程序,如果类型更复杂的话,比如说是一个 struct,那么原理也是类似的,篇幅所限,本文就不再赘述了,有兴趣的读者可以参考文章后面的相关链接。...uretprobe 虽然在 golang 程序中使用 uretprobe 是不安全的,但是好在 uprobe 还可以放心用。...通过 bpftrace 分析 golang 中 slice 是如何扩容的 本例代码依然以 go1.17 版本为例,它的逻辑就是不断追加数据,迫使 slice 扩容: package main import
\n"); } filter是可选的,有时候我们只需要探测特定条件下函数的行为,比如参数为某个值的时候,就可以用到filter,这需要了解bpftrace如何访问probe的变量,我们稍晚再说。...comm:进程名称,通常为进程可执行文件名。 kstack:内核栈。 ustack: 用户栈。 arg0, arg1, ..., argN:函数参数。...., sargN:函数参数(栈中)。 retval:返回值。 func:函数名,可以在可执行文件的符号表中这个函数名。...probe:探针的完整名称,也就是 bpftrace 中 形如 'kprobe:do_nanosleep' curtask:当前 task struct。 rand:一个无符号 32 位随机数。...00:00:00 cron ^C ustack 当使用 uprobe 时,很可能需要关注用户进程的 stack 情况,ustack 函数接受 2 个参数,这两个参数可以同时使用,或者只用 1 个。
size 这个参数表示bpf_attr union 这个对象以字节为单位的大小 1.2 eBPF的系统调用命令 即上面bpf系统调用中的CMD,其作为第一个参数传递: 可以使用命令创建和修改eBPF...帮助函数进行套接字重定向 可以使用bpf_map_lookup_elem()函数和bpf_map_update_elem()函数从eBPF程序或用户空间程序访问所有map对象 某些map类型,如套接字类型...然后,BCC负责使用bpf()系统调用函数,将eBPF字节码加载到内核中 如果加载失败,例如内核验证器检查失败,则BCC提供有关加载失败原因的提示,如,“提示:如果在没有首先检查指针是否为空的情况下,...,如: bpf_get_current_pid_tgid: 用于获取进程的pid和tgid(线程组ID,同一个进程下的所有线程都是同一个tgid),该函数返回一个64位的uint值,高32位为线程组...函数的参数 所以,编写eBPF程序的时候都可以在ctx后加入对应系统调用接口的入参即可,在eBPF执行的时候会自动进行参数绑定 为什么data_t的c结构体最后会在python中读取为python对象
与 kprobes 类似,只是跟踪的函数为用户程序中的函数。 tracepoints:内核中静态跟踪。...eBPF 的使用 eBPF 提供多种使用方式:BCC、BPFTrace、libbpf C/C++ Library、eBPF GO library等 更早期的工具使用 C 语言来编写 BPF 程序,使用...以kprobe__为前缀的C函数,被当作内核函数名使用,本文是sys_clone()。 void *ctx: ctx 传递参数,当前不传递参数则使用void *。.../monitor-exec BPFTrace BPFTrace 使用 LLVM 将脚本编译成 BPF 二进制码,后续使用 BCC 与 Linux 内核进行交互。...-DCMAKE_BUILD_TYPE=Release .. make -j8 && make install # 统计内核中函数堆栈的次数 # bpftrace -e 'profile:hz:99 {
为了更好解释 ply,我们把第 3 部分中的 BPFtrace 例子和与 ply 实现进行对比: BPFtrace:要运行该例子,你需要数百 MB 的 LLVM/clang、libelf 和其他依赖项:...)【译者注:当前最新版本为 2.1.1,最近一次代码提交是 8 个月前,活跃度一般】,除了一些示例之外,该语言还不不稳定或缺乏文档,它不如完整的 BCC 强大,也没有 BPFtrace 丰富的功能特性,...Gobpf Gobpf 及其合并的子项目(goebpf, gobpf-elf-loader),是 IOVisor 项目的一部分,为 BCC 提供 Golang 语言绑定。...打开的文件名作为 do_sys_open call 的第二个参数传递,可以从代表函数入口的 CPU 寄存器的上下文结构中访问。...在我们的例子中,区域为 kprobe、license 和 version。
BPF辅助函数进行套接字重定向 可以使用bpf_map_lookup_elem()和 bpf_map_update_elem()函数从eBPF或用户空间程序访问所有Map. 2.5 如何用C编写eBPF...kprobes类型的探针用于跟踪内核函数调用,是一种功能强大的探针类型,让我们可以追踪成千上万的内核函数。由于它们用来跟踪底层内核的,开发者需要熟悉内核源代码,理解这些探针的参数、返回值的意义。...如果内核版本不同,内核函数名、参数、返回值等可能会变化。如果尝试将相同的探针附加到具有两个不同内核版本的系统上,则相同的代码可能会停止工作。...安装使用 bpftrace是建立在eBPF之上的一种编程语言,考虑到部分特性需满足Linux内核的支持,因此建议Linux的内核版本在4.9以上,部分功能在低版本内核中是不支持的,例如Tracepoints...如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
在上面的例子中,我们使用了 BPF.SOCKET_FILTER 程序类型,其结果是我们挂载的 C 函数得到一个网络数据包缓冲区作为 context 上下文参数【译者注:本例中为 struct _sk_buff...我们还可以使用 BPF.KPROBE 程序类型来探测任意的内核函数。...我们继续优化,不再使用与上面相同的接口,而是使用一个特殊的 kprobe_* 函数名称前缀,以描述一个更高级别的 BCC API。...它使用了一些非常高层次的热门概念,如 “通用输入/输出”,专注于向云/数据中心开发人员和用户提供 eBPF 技术。...这些工具使得使用 eBPF 非常容易,用户只需 “apt-get install bpftrace” 就可以运行单行程序,或者使用 Hover 守护程序将 eBPF 程序(IO 模块)部署到 1000
它是一个允许你分析系统在幕后正在执行的操作的追踪工具,可以告诉你代码中正在被调用的函数、传递给函数的参数、函数的调用次数等。..._* { @[probe] = count(); }' 一些探针类型允许使用通配符匹配多个探针,你也可以使用一个逗号隔开的列表为一个操作块指明多个连接点。...映射的键 comm 代表调用系统调用的进程名;内建函数 sum() 累计每个映射项或进程写的字节数;args 是一个 bpftrace 内建指令,用于访问追踪点的参数和返回值。...下一个例子使用探测用户级函数结尾处的 uretprobe ,获取系统中运行的每个 bash 发出的命令行: $ sudo bpftrace -e 'uretprobe:/bin/bash:readline...使用 uprobes 时,你可以用 arg0..argN 访问参数。需要调用 str() 将 char * 指针转化成一个字符串。
如红色箭头所指,可以清晰的看出killall命令,给进程daemon.sh(pid为3615)发送了SIGTERM(即sig=15)。...然后调用systemtap的函数pid2execname得到该pid的进程名。 当条件为真时,表明kill要发送的目标pid就是我们要监视服务进程。...最后使用通过systemtap的argstr,打印kill的完整参数 看一下执行效果 ?...第三个方法:bpftrace bpftrace是Brendan Gregg使用bpf开发的一套trace工具。对于当前问题,我们选择其中的killsnoop来trace kill调用。 ?...第五个方法:直接编写bpftrace代码 在第三个方法中,我们直接使用bpftrace提供的现成工具,实际上我们也可以编写bpftrace来完成这个任务。 #!
将 BPF 字节码加载到内核中:可以使用用户空间工具(如 bpftool 或 ip 命令的 bpf 子命令)加载 BPF 字节码,以在内核中创建 BPF 程序。...例如,可以使用 xxx_user.c 中的函数调用 bpftool 等命令执行 BPF 示例相关的操作。 以上步骤是一种常见的使用方法,具体的使用方式取决于您的需求和所使用的工具。 3....在上面的例子中,我们使用了 BPF.SOCKET_FILTER 程序类型,其结果是我们挂载的 C 函数得到一个网络数据包缓冲区作为 context 上下文参数【译者注:本例中为 struct _sk_buff...我们还可以使用 BPF.KPROBE 程序类型来探测任意的内核函数。我们继续优化,不再使用与上面相同的接口,而是使用一个特殊的 kprobe_* 函数名称前缀,以描述一个更高级别的 BCC API。...它使用了一些非常高层次的热门概念,如 “通用输入/输出”,专注于向云/数据中心开发人员和用户提供 eBPF 技术。
bpftrace 使用 LLVM 作为后端将脚本编译为 BPF 字节码,并利用BCC与 Linux BPF 系统进行交互,以及现有的 Linux 跟踪功能:内核动态跟踪(kprobes)、用户级动态跟踪...及更高版本) 三、bpftrace使用入门 3.1 探针 图中,如kprobeb/kretprobe为动态跟踪、内核级探针,kprobeb是检测函数执行的开始,kretprobe为检测结束(返回)。...uprobe/uretprobe为动态跟踪、用户级探针,uprobeb是检测用户级函数执行的开始,uretprobe为检测结束(返回)。tracepoint为静态跟踪、用户级探针。...bpftrace -l 可以列出bpftrace所支撑的探针。如bpftrace -l ‘*nanosleep’可以列出bpftrace支持的nanosleep函数相关的所有探针。...3.2.1 单行语句 如系统函数raw_syscalls:sys_enter的调用统计,语法为:bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm
摘要 bpftrace提供了一种快速利用eBPF实现动态追踪的方法,可以作为简单的命令行工具或者入门级编程工具来使用。本文以bpftrace为例,介绍如何利用eBPF实现内核的动态追踪。...bpftrace[3]是Linux中基于eBPF的高级追踪语言,使用LLVM作为后端来编译eBPF字节码脚本,并使用BCC与Linux BPF系统交互。...kprobes类型的探针用于跟踪内核函数调用,是一种功能强大的探针类型,让我们可以追踪成千上万的内核函数。由于它们用来跟踪底层内核的,开发者需要熟悉内核源代码,理解这些探针的参数、返回值的意义。...如果内核版本不同,内核函数名、参数、返回值等可能会变化。如果尝试将相同的探针附加到具有两个不同内核版本的系统上,则相同的代码可能会停止工作。...从脚本中对抓取信息的解析和处理中我们可以看出,如前文所述,在使用kprobes探针时,需要知道想要追踪的函数签名(Function Signature),这里一方面需要开发者对内核函数有一个比较清晰的认识
多个 goroutine 共同通过 Deposit 函数使用了包级别的变量 balance,从而产生了竞争条件。 可见,在并发环境中,竞争条件是非常严重的一个问题。 2.2....竞争条件的避免 那么,如何在程序中避免竞争条件呢?...通过通道实现互斥锁 由于 GoLang 中的通道阻塞机制,我们可以自己通过一个容量为 1 的通道来实现互斥锁。...RWMutex 的加解锁性能相对于 Mutex 要低一些,所以如非必要,尽量仍然使用 sync.Mutex 来实现加解锁操作,只有读操作远多于写操作,且锁竞争非常激烈时,RWMutex 才能显示出他的优势...线程标识 每个操作系统的线程都拥有一个唯一的标识,但在使用中,很多程序员将线程标识与业务耦合在一起,从而造成了很多十分诡异的现象和问题,这与鼓励简单编程的 GoLang 风格相左,所以 GoLang 拒绝为每个
perf top: 实时监控系统性能,动态显示最耗时的函数和指令。 具体案例:在Linux系统中,可以使用perf record命令对特定程序进行性能采样分析。...常见命令: bpftrace: 使用BPF跟踪器执行跟踪脚本,如监控文件系统调用、网络包等。 bpftool: 是一个BPF程序和映射的管理工具,可以用来创建、查询和删除BPF程序。...具体案例:可以使用bpftrace脚本来跟踪所有的系统调用,并使用bpftool将结果导出到一个跟踪文件中。...常见命令 trace: 执行BPF跟踪脚本,如监控内核函数的执行。 profile: 执行BPF性能分析脚本,统计函数的执行频率和耗时。...perf script将采样数据转换为文本格式,然后使用flamegraph.pl脚本生成火焰图flamegraph.svg,可视化地显示应用程序中的CPU使用情况,快速定位热点函数。
类似 JavaScript 中的事件处理机制,比如单机,双击鼠标触发的事件回调 BPF 则允许内核在系统和应用程序事件(如磁盘 I/O 事件)发生时运行一段小程序,这样就催生了新的系统编程技术。...有许多工具并不跟踪事件,而是使用固定的计数器统计监测事件的频次,然后打印出摘要信息,如Linux top()。...比如,有不少用 Python 开发的 BCC程序,它们使用 Python 的 argparse 库来提供复杂、精细的工具命令行参数支持。 ply 目前处在开发阶段的BPF 前端。...使用扩展的BPF(伯克利分组过滤器),正式名称为eBPF,Linux3.15 中首次添加的一项新功能。BCC使用的大部分内容都需要Linux4.1或更高版本。...当工具停止执行后(用户按下 Ctrl+C 组合键),摘要信息就被打印出来了笔者使用了命令行参数-m来使得统计值以毫秒为单位输出。
Linux内核中,因此你无需再安装任何新的内核组件,就可以在生产环境中使用BPF。...BCC和bpftrace 直接使用BPF指令进行编程非常繁琐,因此很有必要提供高级语言前端方便用户使用,于是就出现了BCC和bpftrace。...Stack Trace Stack Trace是程序执行过程中,在特定时间点的函数调用列表。...火焰图 根据前面对Stack Trace的统计信息,可以绘制出如下的火焰图: 火焰图具有以下特性: 每个长方块代表了函数调用栈中的一个函数 Y 轴显示堆栈的深度(堆栈中的帧数)。...AsyncGetCallTrace是JDK内部提供的一个函数,它的原型如下: typedef struct { jint lineno; // BCI in the source file
还可以使用 make 函数来创建指定长度和容量的切片: numbers := make([]int, 5, 10) 该语句创建了一个长度为 5,容量为 10 的整数类型切片。...可以使用 delete() 函数从映射中删除条目: delete(ages, "Bob") 此时映射中不再包含键为 Bob 的条目。...以下是一些关于Golang复合数据结构体(Struct)类型的一些例子 以下是一些使用 Golang 结构体的例子: package main import "fmt" // 定义一个表示人的结构体...在Go中,使用&操作符获取变量的地址,使用*操作符获取指针所指向的变量的值。指针可以用于传递函数参数、处理数据结构等方面。...然后我们使用 * 运算符访问指针所指向的变量的值,并打印出来。 最后,我们演示了如何在函数中使用指针参数。我们定义了一个 increment 函数,并接收一个指针类型参数 p。
本章的我们来学习uprobe ,顾名思义,相对于内核函数/地址的监控,主要用于用户态函数/地址的监控。听起来是不是有点神奇,内核怎么监控用户态函数的调用呢?...: 将 probe 添加到全局列表中,并创建对应的 uprobe debugfs 目录,即上文示例中的 p_test_0x115a 对于uprobe其实整个流程跟kprobe基本类似,我们重点关注于...与 kprobe 类似,我们可以在触发 uprobe 时候根据对应寄存器去提取当前执行的上下文信息,比如函数的调用参数等。同时 uprobe 也有类似的同族: uretprobe。...,使用uprobe一般都是编写内核驱动,在模块中定义uprobe_consumer ,然后调用uprobe的API(uprobe_register)来进行注册uprobe #include <linux...直接编写 BPF 程序可能比较痛苦,因此需要通过 bpftrace 来使用它。
图片2.2 VMebpf是一个使用RISC指令集的虚拟机,他使用PC,11个64位寄存器和一个固定大小为512字节的栈。...如果程序只有一个bpf函数,则直接返回2. 过滤掉所有的内部函数调用指令(可以理解为inline展开)3. 对于每个函数调用,构造一个子程序的数据结构并初始化(struct bpf_prog)4....当使用kprobe动态追踪时,我们还需要定义需要注入的hook函数(在目标函数前后)。...图片注意ebpf函数的第一个参数总是 struct pt_regs *.通过调用 bpf_get_current_pid_tgid 获取当前pid,调用 bpf_ktime_get_ns 获取当前timestamp... args->*在format文件中的参数名* 获取) 来更新map,还有一点需要注意的是我们使用 dev(id) + sector(id) 来作为 key (这个是来自Gregg’s 对写IO requests
/httptest_demo 0.055s 通过这个示例我们就掌握了如何使用httptest在HTTP Server服务中为请求处理函数编写单元测试了。...gock 上面的示例介绍了如何在HTTP Server服务类场景下为请求处理函数编写单元测试,那么如果我们是在代码中请求外部API的场景(比如通过API调用其他服务获取返回值)又该怎么编写单元测试呢?...// api.go // ReqParam API请求参数 type ReqParam struct { X int `json:"x"` } // Result API返回结果 type Result...这里推荐使用gock这个库。 安装 go get -u gopkg.in/h2non/gock.v1 使用示例 使用gock对外部API进行mock,即mock指定参数返回约定好的响应内容。...总结 在日常工作开发中为代码编写单元测试时如何处理外部依赖是最常见的问题,本文介绍了如何使用httptest和gock工具mock相关依赖。
领取专属 10元无门槛券
手把手带您无忧上云