hello_perf_output.php 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. <?php
  2. $prog = <<<EOT
  3. #include <linux/sched.h>
  4. // define output data structure in C
  5. struct data_t {
  6. u32 pid;
  7. u64 ts;
  8. char comm[TASK_COMM_LEN];
  9. };
  10. BPF_PERF_OUTPUT(events);
  11. int hello(struct pt_regs *ctx) {
  12. struct data_t data = {};
  13. data.pid = bpf_get_current_pid_tgid();
  14. data.ts = bpf_ktime_get_ns();
  15. bpf_get_current_comm(&data.comm, sizeof(data.comm));
  16. events.perf_submit(ctx, &data, sizeof(data));
  17. return 0;
  18. }
  19. EOT;
  20. # load BPF program
  21. $b = new Ebpf($prog);
  22. $b->attach_kprobe($b->get_syscall_fnname("clone"), "hello");
  23. # header
  24. printf("%-18s %-16s %-6s %s\n", "TIME(s)", "COMM", "PID", "MESSAGE");
  25. # process event
  26. $start = 0;
  27. function print_event($cpu, $data, $size) {
  28. global $start;
  29. $event = unpack("Qpid/Qts/A16comm", $data);
  30. if ($start == 0) {
  31. $start = $event['ts'];
  32. }
  33. $time_s = ($event['ts'] - $start) / 1000000000.0;
  34. printf("%-18.9f %-16s %-6d %s\n", $time_s, $event['comm'], $event['pid'], "Hello, perf_output!");
  35. }
  36. # loop with callback to print_event
  37. $b->events->open_perf_buffer("print_event");
  38. while (true) {
  39. try {
  40. $b->perf_buffer_poll();
  41. } catch (Exception $e) {
  42. exit();
  43. }
  44. }