rbbcc 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/Gemfile.lock +2 -2
 - data/README.md +4 -0
 - data/docs/README.md +2 -0
 - data/docs/answers/01-hello-world.rb +16 -0
 - data/docs/answers/02-sys_sync.rb +18 -0
 - data/docs/answers/03-hello_fields.rb +33 -0
 - data/docs/answers/04-sync_timing.rb +46 -0
 - data/docs/answers/05-sync_count.rb +54 -0
 - data/docs/answers/06-disksnoop.rb +71 -0
 - data/docs/answers/07-hello_perf_output.rb +59 -0
 - data/docs/answers/08-sync_perf_output.rb +60 -0
 - data/docs/answers/09-bitehist.rb +32 -0
 - data/docs/answers/10-disklatency.rb +51 -0
 - data/docs/answers/11-vfsreadlat.c +46 -0
 - data/docs/answers/11-vfsreadlat.rb +66 -0
 - data/docs/answers/12-urandomread.rb +38 -0
 - data/docs/answers/13-disksnoop_fixed.rb +108 -0
 - data/docs/answers/14-strlen_count.rb +46 -0
 - data/docs/answers/15-nodejs_http_server.rb +44 -0
 - data/docs/answers/16-task_switch.c +23 -0
 - data/docs/answers/16-task_switch.rb +17 -0
 - data/docs/answers/node-server.js +11 -0
 - data/docs/projects_using_rbbcc.md +43 -0
 - data/docs/tutorial_bcc_ruby_developer.md +772 -0
 - data/lib/rbbcc/bcc.rb +41 -13
 - data/lib/rbbcc/clib.rb +1 -0
 - data/lib/rbbcc/table.rb +16 -22
 - data/lib/rbbcc/version.rb +1 -1
 - data/rbbcc.gemspec +1 -1
 - metadata +25 -4
 
| 
         @@ -0,0 +1,108 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            # disksnoop_fixed.rb	Trace block device I/O: basic version of iosnoop.
         
     | 
| 
      
 4 
     | 
    
         
            +
            #		For Linux, uses BCC, eBPF. Embedded C.
         
     | 
| 
      
 5 
     | 
    
         
            +
            # This is ported from original disksnoop.py
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            # Written as a basic example of tracing latency.
         
     | 
| 
      
 8 
     | 
    
         
            +
            #
         
     | 
| 
      
 9 
     | 
    
         
            +
            # Licensed under the Apache License, Version 2.0 (the "License")
         
     | 
| 
      
 10 
     | 
    
         
            +
            #
         
     | 
| 
      
 11 
     | 
    
         
            +
            # 11-Aug-2015	Brendan Gregg	Created disksnoop.py
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            =begin
         
     | 
| 
      
 14 
     | 
    
         
            +
            name: block_rq_issue
         
     | 
| 
      
 15 
     | 
    
         
            +
            ID: 1093
         
     | 
| 
      
 16 
     | 
    
         
            +
            format:
         
     | 
| 
      
 17 
     | 
    
         
            +
                    field:unsigned short common_type;       offset:0;       size:2; signed:0;
         
     | 
| 
      
 18 
     | 
    
         
            +
                    field:unsigned char common_flags;       offset:2;       size:1; signed:0;
         
     | 
| 
      
 19 
     | 
    
         
            +
                    field:unsigned char common_preempt_count;       offset:3;       size:1; signed:0;
         
     | 
| 
      
 20 
     | 
    
         
            +
                    field:int common_pid;   offset:4;       size:4; signed:1;
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    field:dev_t dev;        offset:8;       size:4; signed:0;
         
     | 
| 
      
 23 
     | 
    
         
            +
                    field:sector_t sector;  offset:16;      size:8; signed:0;
         
     | 
| 
      
 24 
     | 
    
         
            +
                    field:unsigned int nr_sector;   offset:24;      size:4; signed:0;
         
     | 
| 
      
 25 
     | 
    
         
            +
                    field:unsigned int bytes;       offset:28;      size:4; signed:0;
         
     | 
| 
      
 26 
     | 
    
         
            +
                    field:char rwbs[8];     offset:32;      size:8; signed:1;
         
     | 
| 
      
 27 
     | 
    
         
            +
                    field:char comm[16];    offset:40;      size:16;        signed:1;
         
     | 
| 
      
 28 
     | 
    
         
            +
                    field:__data_loc char[] cmd;    offset:56;      size:4; signed:1;
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            print fmt: "%d,%d %s %u (%s) %llu + %u [%s]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, REC->bytes, __get_str(cmd), (unsigned long long)REC->sector, REC->nr_sector, REC->comm
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            name: block_rq_complete
         
     | 
| 
      
 33 
     | 
    
         
            +
            ID: 1095
         
     | 
| 
      
 34 
     | 
    
         
            +
            format:
         
     | 
| 
      
 35 
     | 
    
         
            +
                    field:unsigned short common_type;       offset:0;       size:2; signed:0;
         
     | 
| 
      
 36 
     | 
    
         
            +
                    field:unsigned char common_flags;       offset:2;       size:1; signed:0;
         
     | 
| 
      
 37 
     | 
    
         
            +
                    field:unsigned char common_preempt_count;       offset:3;       size:1; signed:0;
         
     | 
| 
      
 38 
     | 
    
         
            +
                    field:int common_pid;   offset:4;       size:4; signed:1;
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                    field:dev_t dev;        offset:8;       size:4; signed:0;
         
     | 
| 
      
 41 
     | 
    
         
            +
                    field:sector_t sector;  offset:16;      size:8; signed:0;
         
     | 
| 
      
 42 
     | 
    
         
            +
                    field:unsigned int nr_sector;   offset:24;      size:4; signed:0;
         
     | 
| 
      
 43 
     | 
    
         
            +
                    field:int error;        offset:28;      size:4; signed:1;
         
     | 
| 
      
 44 
     | 
    
         
            +
                    field:char rwbs[8];     offset:32;      size:8; signed:1;
         
     | 
| 
      
 45 
     | 
    
         
            +
                    field:__data_loc char[] cmd;    offset:40;      size:4; signed:1;
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            print fmt: "%d,%d %s (%s) %llu + %u [%d]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, __get_str(cmd), (unsigned long long)REC->sector, REC->nr_sector, REC->error
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            in kernel 5.0.
         
     | 
| 
      
 50 
     | 
    
         
            +
            This implementation shows the count of sector.
         
     | 
| 
      
 51 
     | 
    
         
            +
            =end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            require 'rbbcc'
         
     | 
| 
      
 54 
     | 
    
         
            +
            include RbBCC
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            # load BPF program
         
     | 
| 
      
 57 
     | 
    
         
            +
            b = BCC.new(text: <<CLANG)
         
     | 
| 
      
 58 
     | 
    
         
            +
            #include <uapi/linux/ptrace.h>
         
     | 
| 
      
 59 
     | 
    
         
            +
            #include <linux/blkdev.h>
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            BPF_HASH(start, u32);
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            TRACEPOINT_PROBE(block, block_rq_issue) {
         
     | 
| 
      
 64 
     | 
    
         
            +
              // stash start timestamp by request ptr
         
     | 
| 
      
 65 
     | 
    
         
            +
              u64 ts = bpf_ktime_get_ns();
         
     | 
| 
      
 66 
     | 
    
         
            +
              u32 tid = bpf_get_current_pid_tgid();
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              start.update(&tid, &ts);
         
     | 
| 
      
 69 
     | 
    
         
            +
              return 0;
         
     | 
| 
      
 70 
     | 
    
         
            +
            }
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            TRACEPOINT_PROBE(block, block_rq_complete) {
         
     | 
| 
      
 73 
     | 
    
         
            +
              u64 *tsp, delta;
         
     | 
| 
      
 74 
     | 
    
         
            +
              u32 tid = bpf_get_current_pid_tgid();
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
              tsp = start.lookup(&tid);
         
     | 
| 
      
 77 
     | 
    
         
            +
              if (tsp != 0) {
         
     | 
| 
      
 78 
     | 
    
         
            +
                char dst[8];
         
     | 
| 
      
 79 
     | 
    
         
            +
                int i;
         
     | 
| 
      
 80 
     | 
    
         
            +
                delta = bpf_ktime_get_ns() - *tsp;
         
     | 
| 
      
 81 
     | 
    
         
            +
                if (bpf_probe_read_str(dst, sizeof(dst), args->rwbs) < 0) {
         
     | 
| 
      
 82 
     | 
    
         
            +
                  dst[0] = '?';
         
     | 
| 
      
 83 
     | 
    
         
            +
                  for(i = 1; i < sizeof(dst); ++i)
         
     | 
| 
      
 84 
     | 
    
         
            +
                    dst[i] = 0;
         
     | 
| 
      
 85 
     | 
    
         
            +
                }
         
     | 
| 
      
 86 
     | 
    
         
            +
                bpf_trace_printk("%d %s %d\\n", args->nr_sector,
         
     | 
| 
      
 87 
     | 
    
         
            +
                    dst, delta / 1000);
         
     | 
| 
      
 88 
     | 
    
         
            +
                start.delete(&tid);
         
     | 
| 
      
 89 
     | 
    
         
            +
              }
         
     | 
| 
      
 90 
     | 
    
         
            +
              return 0;
         
     | 
| 
      
 91 
     | 
    
         
            +
            }
         
     | 
| 
      
 92 
     | 
    
         
            +
            CLANG
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            # header
         
     | 
| 
      
 95 
     | 
    
         
            +
            puts("%-18s %-8s %-7s %8s" % ["TIME(s)", "RWBS", "SECTORS", "LAT(ms)"])
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            # format output
         
     | 
| 
      
 98 
     | 
    
         
            +
            loop do
         
     | 
| 
      
 99 
     | 
    
         
            +
              begin
         
     | 
| 
      
 100 
     | 
    
         
            +
                task, pid, cpu, flags, ts, msg = b.trace_fields
         
     | 
| 
      
 101 
     | 
    
         
            +
                sector_s, rwbs, us_s = msg.split
         
     | 
| 
      
 102 
     | 
    
         
            +
                ms = us_s.to_i.to_f / 1000
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                puts("%-18.9f %-8s %-7s %8.2f" % [ts, rwbs, sector_s, ms])
         
     | 
| 
      
 105 
     | 
    
         
            +
              rescue Interrupt
         
     | 
| 
      
 106 
     | 
    
         
            +
                exit
         
     | 
| 
      
 107 
     | 
    
         
            +
              end
         
     | 
| 
      
 108 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rbbcc'
         
     | 
| 
      
 2 
     | 
    
         
            +
            include RbBCC
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            # load BPF program
         
     | 
| 
      
 5 
     | 
    
         
            +
            b = BCC.new(text: <<BPF)
         
     | 
| 
      
 6 
     | 
    
         
            +
            #include <uapi/linux/ptrace.h>
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            struct key_t {
         
     | 
| 
      
 9 
     | 
    
         
            +
                char c[80];
         
     | 
| 
      
 10 
     | 
    
         
            +
            };
         
     | 
| 
      
 11 
     | 
    
         
            +
            BPF_HASH(counts, struct key_t);
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            int count(struct pt_regs *ctx) {
         
     | 
| 
      
 14 
     | 
    
         
            +
                if (!PT_REGS_PARM1(ctx))
         
     | 
| 
      
 15 
     | 
    
         
            +
                    return 0;
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                struct key_t key = {};
         
     | 
| 
      
 18 
     | 
    
         
            +
                u64 zero = 0, *val;
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                bpf_probe_read(&key.c, sizeof(key.c), (void *)PT_REGS_PARM1(ctx));
         
     | 
| 
      
 21 
     | 
    
         
            +
                // could also use `counts.increment(key)`
         
     | 
| 
      
 22 
     | 
    
         
            +
                val = counts.lookup_or_try_init(&key, &zero);
         
     | 
| 
      
 23 
     | 
    
         
            +
                if (val) {
         
     | 
| 
      
 24 
     | 
    
         
            +
                  (*val)++;
         
     | 
| 
      
 25 
     | 
    
         
            +
                }
         
     | 
| 
      
 26 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 27 
     | 
    
         
            +
            };
         
     | 
| 
      
 28 
     | 
    
         
            +
            BPF
         
     | 
| 
      
 29 
     | 
    
         
            +
            b.attach_uprobe(name: "c", sym: "strlen", fn_name: "count")
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            # header
         
     | 
| 
      
 32 
     | 
    
         
            +
            print("Tracing strlen()... Hit Ctrl-C to end.")
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            # sleep until Ctrl-C
         
     | 
| 
      
 35 
     | 
    
         
            +
            begin
         
     | 
| 
      
 36 
     | 
    
         
            +
              sleep(99999999)
         
     | 
| 
      
 37 
     | 
    
         
            +
            rescue Interrupt
         
     | 
| 
      
 38 
     | 
    
         
            +
              puts
         
     | 
| 
      
 39 
     | 
    
         
            +
            end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            # print output
         
     | 
| 
      
 42 
     | 
    
         
            +
            puts("%10s %s" % ["COUNT", "STRING"])
         
     | 
| 
      
 43 
     | 
    
         
            +
            counts = b.get_table("counts")
         
     | 
| 
      
 44 
     | 
    
         
            +
            counts.items.sort_by{|k, v| v.to_bcc_value }.each do |k, v|
         
     | 
| 
      
 45 
     | 
    
         
            +
              puts("%10d %s" % [v.to_bcc_value, k[0, k.size].unpack("Z*")[0]])
         
     | 
| 
      
 46 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,44 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rbbcc'
         
     | 
| 
      
 2 
     | 
    
         
            +
            include RbBCC
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            if ARGV.size != 1
         
     | 
| 
      
 5 
     | 
    
         
            +
              print("USAGE: #{$0} PID")
         
     | 
| 
      
 6 
     | 
    
         
            +
              exit()
         
     | 
| 
      
 7 
     | 
    
         
            +
            end
         
     | 
| 
      
 8 
     | 
    
         
            +
            pid = ARGV[0]
         
     | 
| 
      
 9 
     | 
    
         
            +
            debug = !!ENV['DEBUG']
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            # load BPF program
         
     | 
| 
      
 12 
     | 
    
         
            +
            bpf_text = <<BPF
         
     | 
| 
      
 13 
     | 
    
         
            +
            #include <uapi/linux/ptrace.h>
         
     | 
| 
      
 14 
     | 
    
         
            +
            int do_trace(struct pt_regs *ctx) {
         
     | 
| 
      
 15 
     | 
    
         
            +
                uint64_t addr;
         
     | 
| 
      
 16 
     | 
    
         
            +
                char path[128]={0};
         
     | 
| 
      
 17 
     | 
    
         
            +
                bpf_usdt_readarg(6, ctx, &addr);
         
     | 
| 
      
 18 
     | 
    
         
            +
                bpf_probe_read(&path, sizeof(path), (void *)addr);
         
     | 
| 
      
 19 
     | 
    
         
            +
                bpf_trace_printk("path:%s\\n", path);
         
     | 
| 
      
 20 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 21 
     | 
    
         
            +
            };
         
     | 
| 
      
 22 
     | 
    
         
            +
            BPF
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            # enable USDT probe from given PID
         
     | 
| 
      
 25 
     | 
    
         
            +
            u = USDT.new(pid: pid.to_i)
         
     | 
| 
      
 26 
     | 
    
         
            +
            u.enable_probe(probe: "http__server__request", fn_name: "do_trace")
         
     | 
| 
      
 27 
     | 
    
         
            +
            if debug
         
     | 
| 
      
 28 
     | 
    
         
            +
              puts(u.get_text)
         
     | 
| 
      
 29 
     | 
    
         
            +
              puts(bpf_text)
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            # initialize BPF
         
     | 
| 
      
 33 
     | 
    
         
            +
            b = BCC.new(text: bpf_text, usdt_contexts: [u])
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            puts("%-18s %-16s %-6s %s" % ["TIME(s)", "COMM", "PID", "ARGS"])
         
     | 
| 
      
 36 
     | 
    
         
            +
            loop do
         
     | 
| 
      
 37 
     | 
    
         
            +
              begin
         
     | 
| 
      
 38 
     | 
    
         
            +
                b.trace_fields do |task, pid, cpu, flags, ts, msg|
         
     | 
| 
      
 39 
     | 
    
         
            +
                  puts("%-18.9f %-16s %-6d %s" % [ts, task, pid, msg])
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
              rescue Interrupt
         
     | 
| 
      
 42 
     | 
    
         
            +
                exit
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #include <uapi/linux/ptrace.h>
         
     | 
| 
      
 2 
     | 
    
         
            +
            #include <linux/sched.h>
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            struct key_t {
         
     | 
| 
      
 5 
     | 
    
         
            +
                u32 prev_pid;
         
     | 
| 
      
 6 
     | 
    
         
            +
                u32 curr_pid;
         
     | 
| 
      
 7 
     | 
    
         
            +
            };
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            BPF_HASH(stats, struct key_t, u64, 1024);
         
     | 
| 
      
 10 
     | 
    
         
            +
            int count_sched(struct pt_regs *ctx, struct task_struct *prev) {
         
     | 
| 
      
 11 
     | 
    
         
            +
                struct key_t key = {};
         
     | 
| 
      
 12 
     | 
    
         
            +
                u64 zero = 0, *val;
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                key.curr_pid = bpf_get_current_pid_tgid();
         
     | 
| 
      
 15 
     | 
    
         
            +
                key.prev_pid = prev->pid;
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                // could also use `stats.increment(key);`
         
     | 
| 
      
 18 
     | 
    
         
            +
                val = stats.lookup_or_try_init(&key, &zero);
         
     | 
| 
      
 19 
     | 
    
         
            +
                if (val) {
         
     | 
| 
      
 20 
     | 
    
         
            +
                  (*val)++;
         
     | 
| 
      
 21 
     | 
    
         
            +
                }
         
     | 
| 
      
 22 
     | 
    
         
            +
                return 0;
         
     | 
| 
      
 23 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Original task_switch.rb Copyright (c) PLUMgrid, Inc.
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Licensed under the Apache License, Version 2.0 (the "License")
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require 'rbbcc'
         
     | 
| 
      
 6 
     | 
    
         
            +
            include RbBCC
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            b = BCC.new(src_file: "16-task_switch.c")
         
     | 
| 
      
 9 
     | 
    
         
            +
            b.attach_kprobe(event: "finish_task_switch", fn_name: "count_sched")
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            # generate many schedule events
         
     | 
| 
      
 12 
     | 
    
         
            +
            100.times { sleep 0.01 }
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            b["stats"].each do |_k, v|
         
     | 
| 
      
 15 
     | 
    
         
            +
              k = _k[0, 8].unpack("i! i!") # Handling pointer without type!!
         
     | 
| 
      
 16 
     | 
    
         
            +
              puts("task_switch[%5d->%5d]=%u" % [k[0], k[1], v.to_bcc_value])
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            var http = require("http");
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            var server = http.createServer(function (req, res) {
         
     | 
| 
      
 4 
     | 
    
         
            +
                res.writeHead(200, {"Content-Type": "text/plain"});
         
     | 
| 
      
 5 
     | 
    
         
            +
                res.end("Sample node.js server, returns contents in any path.\n");
         
     | 
| 
      
 6 
     | 
    
         
            +
            });
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            var port = process.env.PORT || 8081;
         
     | 
| 
      
 9 
     | 
    
         
            +
            server.listen(port, function() {
         
     | 
| 
      
 10 
     | 
    
         
            +
                console.log("Do curl http://localhost:" + port);
         
     | 
| 
      
 11 
     | 
    
         
            +
            });
         
     | 
| 
         @@ -0,0 +1,43 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Projects Using RbBCC
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            ## bpfql
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            [bpfql](https://github.com/udzura/bpfql) is a tool to run an eBPF tracing query, using YAML or Ruby DSL.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 8 
     | 
    
         
            +
            BPFQL do
         
     | 
| 
      
 9 
     | 
    
         
            +
              select "*"
         
     | 
| 
      
 10 
     | 
    
         
            +
              from "tracepoint:random:urandom_read"
         
     | 
| 
      
 11 
     | 
    
         
            +
              where "comm", is: "ruby"
         
     | 
| 
      
 12 
     | 
    
         
            +
            end
         
     | 
| 
      
 13 
     | 
    
         
            +
            ```
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            ```console
         
     | 
| 
      
 16 
     | 
    
         
            +
            $ sudo bundle exec bpfql examples/random.rb
         
     | 
| 
      
 17 
     | 
    
         
            +
            Found fnc: tracepoint__random__urandom_read
         
     | 
| 
      
 18 
     | 
    
         
            +
            Attach: random:urandom_read
         
     | 
| 
      
 19 
     | 
    
         
            +
            TS                 COMM             PID    GOT_BITS POOL_LEFT INPUT_LEFT
         
     | 
| 
      
 20 
     | 
    
         
            +
            0.000000000        ruby             32485  128      0        2451
         
     | 
| 
      
 21 
     | 
    
         
            +
            0.002465663        ruby             32485  128      0        2451
         
     | 
| 
      
 22 
     | 
    
         
            +
            ^CExiting bpfql...
         
     | 
| 
      
 23 
     | 
    
         
            +
            ```
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            See [its repo](https://github.com/udzura/bpfql) for more details.
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            ## rack-ebpf and rack application tracing
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            [rack-ebpf](https://github.com/udzura/rack-ebpf) is a rack middleware that invoke USDT probes every time start/end the requests.
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            Combine this rack middleware and `rack-ebpf-run` command, we can trace and analyze system stats per request.
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            e.g.
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            * Count of syscall invocations(like read, write) per request
         
     | 
| 
      
 36 
     | 
    
         
            +
            * Consumed time for syscall ops(like read, write) per request
         
     | 
| 
      
 37 
     | 
    
         
            +
            * Created Ruby objects per request, using Ruby itself's USDT (this requires ruby itself as `--enable-dtrace` build)
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            For detailed usage, see [rack-ebpf's repo](https://github.com/udzura/rack-ebpf)
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            ----
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            Also we're going to prepare some BCC tools made with Ruby. TBA!
         
     |