ZBLOG

10个ebpf uprobe golang的代码案例

以下是10个使用eBPF、uprobes和Golang的代码案例示例:

  1. 监控函数调用次数:
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/iovisor/gobpf/bcc"
  5. )
  6. const program = `
  7. #include <uapi/linux/ptrace.h>
  8. BPF_HASH(counts, u64);
  9. int count_calls(struct pt_regs *ctx) {
  10. u64 key = PT_REGS_IP(ctx);
  11. u64* val = counts.lookup_or_init(&key, 0);
  12. (*val)++;
  13. return 0;
  14. }
  15. `
  16. func main() {
  17. module := bcc.NewModule(program, []string{})
  18. defer module.Close()
  19. uprobe, err := module.LoadUprobe("count_calls")
  20. if err != nil {
  21. fmt.Fprintf(os.Stderr, "Failed to load uprobe: %v\n", err)
  22. os.Exit(1)
  23. }
  24. err = module.AttachUprobe("/path/to/binary", "function_name", uprobe, -1)
  25. if err != nil {
  26. fmt.Fprintf(os.Stderr, "Failed to attach uprobe: %v\n", err)
  27. os.Exit(1)
  28. }
  29. perfMap, err := bcc.InitPerfMap(module.LookupTable("counts"), printOutput)
  30. if err != nil {
  31. fmt.Fprintf(os.Stderr, "Failed to initialize perf map: %v\n", err)
  32. os.Exit(1)
  33. }
  34. perfMap.Start()
  35. defer perfMap.Stop()
  36. select {}
  37. }
  38. func printOutput() {
  39. fmt.Println("Function called!")
  40. }
  1. 统计函数执行时间:
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/iovisor/gobpf/bcc"
  5. )
  6. const program = `
  7. #include <uapi/linux/ptrace.h>
  8. struct data_t {
  9. u64 timestamp;
  10. };
  11. BPF_HASH(start, u32, struct data_t);
  12. int trace_start(struct pt_regs *ctx) {
  13. u32 pid = bpf_get_current_pid_tgid();
  14. struct data_t data = {};
  15. data.timestamp = bpf_ktime_get_ns();
  16. start.update(&pid, &data);
  17. return 0;
  18. }
  19. int trace_end(struct pt_regs *ctx) {
  20. u32 pid = bpf_get_current_pid_tgid();
  21. struct data_t* start_data = start.lookup(&pid);
  22. if (start_data == 0) {
  23. return 0;
  24. }
  25. u64 delta = bpf_ktime_get_ns() - start_data->timestamp;
  26. bpf_trace_printk("%d: Execution time: %llu ns\\n", pid, delta / 1000);
  27. start.delete(&pid);
  28. return 0;
  29. }
  30. `
  31. func main() {
  32. module := bcc.NewModule(program, []string{})
  33. defer module.Close()
  34. uprobeStart, err := module.LoadUprobe("trace_start")
  35. if err != nil {
  36. fmt.Fprintf(os.Stderr, "Failed to load uprobe: %v\n", err)
  37. os.Exit(1)
  38. }
  39. err = module.AttachUprobe("/path/to/binary", "function_name", uprobeStart, -1)
  40. if err != nil {
  41. fmt.Fprintf(os.Stderr, "Failed to attach uprobe: %v\n", err)
  42. os.Exit(1)
  43. }
  44. uprobeEnd, err := module.LoadUprobe("trace_end")
  45. if err != nil {
  46. fmt.Fprintf(os.Stderr, "Failed to load uprobe: %v\n", err)
  47. os.Exit(1)
  48. }
  49. err = module.AttachUretprobe("/path/to/binary", "function_name", uprobeEnd, -1)
  50. if err != nil {
  51. fmt.Fprintf(os.Stderr, "Failed to attach uprobe: %v\n", err)
  52. os.Exit(1)
  53. }
  54. bcc.NewTable(module.TableId("start"), module).SetMaxEntries(4096)
  55. table := bcc.NewTable(module.TableId("counts"), module)
  56. channel := make(chan []byte)
  57. module["output"].Attach(channel)
  58. defer module["output"].Detach()
  59. go func() {
  60. for {
  61. data := <-channel
  62. fmt.Println(string(data))
  63. }
  64. }()
  65. select {}
  66. }
  1. 监控文件读写操作:
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/iovisor/gobpf/bcc"
  5. )
  6. const program = `
  7. #include <uapi/linux/ptrace.h>
  8. #include <linux/fs.h>
  9. BPF_HASH(counts, int);
  10. int trace_read(struct pt_regs *ctx) {
  11. int pid = bpf_get_current_pid_tgid();
  12. counts.increment(pid);
  13. return 0;
  14. }
  15. int trace_write(struct pt_regs *ctx) {
  16. int pid = bpf_get_current_pid_tgid();
  17. counts.increment(pid);
  18. return 0;
  19. }
  20. `
  21. func main() {
  22. module := bcc.NewModule(program, []string{})
  23. defer module.Close()
  24. uprobeRead, err := module.LoadUprobe("trace_read")
  25. if err != nil {
  26. fmt.Fprintf(os.Stderr, "Failed to load uprobe: %v\n", err)
  27. os.Exit(1)
  28. }
  29. err = module.AttachUprobe("/path/to/binary", "read_function_name", uprobeRead, -1)
  30. if err != nil {
  31. fmt.Fprintf(os.Stderr, "Failed to attach uprobe: %v\n", err)
  32. os.Exit(1)
  33. }
  34. uprobeWrite, err := module.LoadUprobe("trace_write")
  35. if err != nil {
  36. fmt.Fprintf(os.Stderr, "Failed to load uprobe: %v\n", err)
  37. os.Exit(1)
  38. }
  39. err = module.AttachUprobe("/path/to/binary", "write_function_name", uprobeWrite, -1)
  40. if err != nil {
  41. fmt.Fprintf(os.Stderr, "Failed to attach uprobe: %v\n", err)
  42. os.Exit(1)
  43. }
  44. table := bcc.NewTable(module.TableId("counts"), module)
  45. channel := make(chan []byte)
  46. module["output"].Attach(channel)
  47. defer module["output"].Detach()
  48. go func() {
  49. for {
  50. data := <-channel
  51. fmt.Println(string(data))
  52. }
  53. }()
  54. select {}
  55. }
  1. 检测网络数据包:
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/iovisor/gobpf/bcc"
  5. )
  6. const program = `
  7. #include <uapi/linux/ptrace.h>
  8. #include <linux/if_ether.h>
  9. #include <linux/ip.h>
  10. #include <linux/tcp.h>
  11. BPF_PERF_OUTPUT(events);
  12. int trace_packet(struct __sk_buff *skb) {
  13. u8* cursor = 0;
  14. struct ethhdr* eth = bpf_hdr_pointer(skb);
  15. if (eth->h_proto == htons(ETH_P_IP)) {
  16. struct iphdr* ip = (struct iphdr *)(cursor + sizeof(struct ethhdr));
  17. if (ip->protocol == IPPROTO_TCP) {
  18. struct tcphdr* tcp = (struct tcphdr *)(cursor + sizeof(struct ethhdr) + sizeof(struct iphdr));
  19. events.perf_submit(skb, skb->len);
  20. }
  21. }
  22. return 0;
  23. }
  24. `
  25. func main() {
  26. module := bcc.NewModule(program, []string{})
  27. defer module.Close()
  28. uprobePacket, err := module.LoadUprobe("trace_packet")
  29. if err != nil {
  30. fmt.Fprintf(os.Stderr, "Failed to load uprobe: %v\n", err)
  31. os.Exit(1)
  32. }
  33. err = module.AttachUprobe("/path/to/binary", "packet_function_name", uprobePacket, -1)
  34. if err != nil {
  35. fmt.Fprintf(os.Stderr, "Failed to attach uprobe: %v\n", err)
  36. os.Exit(1)
  37. }
  38. table := bcc.NewTable(module.TableId("events"), module)
  39. channel := make(chan []byte)
  40. module["output"].Attach(channel)
  41. defer module["output"].Detach()
  42. go func() {
  43. for {
  44. data := <-channel
  45. fmt.Println(string(data))
  46. }
  47. }()
  48. select {}
  49. }
  1. 监控文件IO耗时:
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/iovisor/gobpf/bcc"
  5. )
  6. const program = `
  7. #include <uapi/linux/ptrace.h>
  8. #include <linux/blkdev.h>
  9. BPF_HASH(start, u64);
  10. int trace_start(struct pt_regs *ctx) {
  11. u64 timestamp = bpf_ktime_get_ns();
  12. start.update(&ctx->pid, &timestamp);
  13. return 0;
  14. }
  15. int trace_end(struct pt_regs *ctx) {
  16. u64* timestamp_ptr = start.lookup(&ctx->pid);
  17. if (timestamp_ptr == NULL) {
  18. return 0;
  19. }
  20. u64 delta = bpf_ktime_get_ns() - *timestamp_ptr;
  21. bpf_trace_printk("%d: IO Time: %llu ns\\n", ctx->pid, delta / 1000);
  22. start.delete(&ctx->pid);
  23. return 0;
  24. }
  25. `
  26. func main() {
  27. module := bcc.NewModule(program, []string{})
  28. defer module.Close()
  29. uprobeStart, err := module.LoadUprobe("trace_start")
  30. if err != nil {
  31. fmt.Fprintf(os.Stderr, "Failed to load uprobe: %v\n", err)
  32. os.Exit(1)
  33. }
  34. err = module.AttachUprobe("/path/to/binary", "start_function_name", uprobeStart, -1)
  35. if err != nil {
  36. fmt.Fprintf(os.Stderr, "Failed to attach uprobe: %v\n", err)
  37. os.Exit(1)
  38. }
  39. uprobeEnd, err := module.LoadUprobe("trace_end")
  40. if err != nil {
  41. fmt.Fprintf(os.Stderr, "Failed to load uprobe: %v\n", err)
  42. os.Exit(1)
  43. }
  44. err = module.AttachUretprobe("/path/to/binary", "end_function_name", uprobeEnd, -1)
  45. if err != nil {
  46. fmt.Fprintf(os.Stderr, "Failed to attach uprobe: %v\n", err)
  47. os.Exit(1)
  48. }
  49. table := bcc.NewTable(module.TableId("counts"), module)
  50. channel := make(chan []byte)
  51. module["output"].Attach(channel)
  52. defer module["output"].Detach()
  53. go func() {
  54. for {
  55. data := <-channel
  56. fmt.Println(string(data))
  57. }
  58. }()
  59. select {}
  60. }
  1. 检测TCP连接状态:
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/iovisor/gobpf/bcc"
  5. )
  6. const program = `
  7. #include <uapi/linux/ptrace.h>
  8. #include <linux/tcp.h>
  9. BPF_HASH(counts, u32);
  10. int trace_tcp_state(struct pt_regs *ctx) {
  11. u32 pid = bpf_get_current_pid_tgid();
  12. struct tcp_sock* tp = (struct tcp_sock*)bpf_get_smp_processor_id();
  13. if (tp == NULL) {
  14. return 0;
  15. }
  16. u32 state = tp->state;
  17. counts.increment(state);
  18. return 0;
  19. }
  20. `
  21. func main() {
  22. module := bcc.NewModule(program, []string{})
  23. defer module.Close()
  24. uprobeState, err := module.LoadUprobe("trace_tcp_state")
  25. if err != nil {
  26. fmt.Fprintf(os.Stderr, "Failed to load uprobe: %v\n", err)
  27. os.Exit(1)
  28. }
  29. err = module.AttachUprobe("/path/to/binary", "tcp_function_name", uprobeState, -1)
  30. if err != nil {
  31. fmt.Fprintf(os.Stderr, "Failed to attach uprobe: %v\n", err)
  32. os.Exit(1)
  33. }
  34. table := bcc.NewTable(module.TableId("counts"), module)
  35. channel := make(chan []byte)
  36. module["output"].Attach(channel)
  37. defer module["output"].Detach()
  38. go func() {
  39. for {
  40. data := <-channel
  41. fmt.Println(string(data))
  42. }
  43. }()
  44. select {}
  45. }
  1. 监控系统调用:
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/iovisor/gobpf/bcc"
  5. )
  6. const program = `
  7. #include <uapi/linux/ptrace.h>
  8. BPF_HASH(counts, int);
  9. int trace_syscall_entry(struct pt_regs *ctx) {
  10. int pid = bpf_get_current_pid_tgid();
  11. counts.increment(pid);
  12. return 0;
  13. }
  14. `
  15. func main() {
  16. module := bcc.NewModule(program, []string{})
  17. defer module.Close()
  18. uprobeSyscallEntry, err := module.LoadUprobe("trace_syscall_entry")
  19. if err != nil {
  20. fmt.Fprintf(os.Stderr, "Failed to load uprobe: %v\n", err)
  21. os.Exit(1)
  22. }
  23. err = module.AttachUprobe("/path/to/binary", "__x64_sys_function_name", uprobeSyscallEntry, -1)
  24. if err != nil {
  25. fmt.Fprintf(os.Stderr, "Failed to attach uprobe: %v\n", err)
  26. os.Exit(1)
  27. }
  28. table := bcc.NewTable(module.TableId("counts"), module)
  29. channel := make(chan []byte)
  30. module["output"].Attach(channel)
  31. defer module["output"].Detach()
  32. go func() {
  33. for {
  34. data := <-channel
  35. fmt.Println(string(data))
  36. }
  37. }()
  38. select {}
  39. }
  1. 跟踪内存分配和释放:

”`go package main

import (

  1. "fmt"
  2. "github.com/iovisor/gobpf/bcc"

)

const program = ` #include

BPF_HASH(counts, u64);

int trace_alloc(struct pt_regs *ctx) {

  1. counts.increment(0);
  2. return 0;

}

int trace_free(struct pt_regs *ctx) {

  1. counts.decrement(0);
  2. return 0;

} `

func main() {

  1. module := bcc.NewModule(program, []string{})
  2. defer module.Close()
  3. uprobeAlloc, err := module.LoadUprobe("trace_alloc")
  4. if err != nil {
  5. fmt.Fprintf(os.Stderr, "Failed to load uprobe: %v\n", err)
  6. os.Exit(1)
  7. }
  8. err = module.AttachUprobe("/path/to/binary", "alloc_function_name", uprobeAlloc, -1)
  9. if err != nil {
  10. fmt.Fprintf(os.Stderr, "Failed to attach uprobe: %v\n", err)
  11. os.Exit(1)
  12. }
  13. uprobeFree, err := module.LoadUprobe("trace_free")
  14. if err != nil {
  15. fmt.Fprintf(os.Stderr, "Failed to load uprobe: %v\n", err)
  16. os.Exit(1)
  17. }
  18. err = module.AttachUprobe("/path/to/binary", "free_function_name", uprobeFree, -1)
  19. if err != nil {
  20. fmt.Fprintf(os.Stderr, "Failed to attach uprobe: %v\n", err)
  21. os.Exit(1)
  22. }
  23. table := bcc.NewTable(module.TableId("counts"), module)
  24. channel := make(chan []byte)
  25. module["output"].Attach(channel)
  26. defer module["output"].Detach<br/><br/><br/><font size=1 color=#CCCCCC>内容由零声教学AI助手提供,问题来源于学员提问</font>

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=18473

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?