-
Notifications
You must be signed in to change notification settings - Fork 676
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
example: demonstrate tracepoint usage
Signed-off-by: Florian Lehner <dev@der-flo.net>
- Loading branch information
Showing
4 changed files
with
150 additions
and
129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module github.com/cilium/ebpf/_example/tracepoint | ||
|
||
go 1.15 | ||
|
||
require ( | ||
github.com/cilium/ebpf v0.3.0 | ||
github.com/elastic/go-perf v0.0.0-20191212140718-9c656876f595 | ||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
github.com/cilium/ebpf v0.3.0 h1:LI3lsl5GmTh+OFYamrj8sp+R0yam38zHG6NTDhSlNmQ= | ||
github.com/cilium/ebpf v0.3.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= | ||
github.com/elastic/go-perf v0.0.0-20191212140718-9c656876f595 h1:q8n4QjcLa4q39Q3fqHRknTBXBtegjriHFrB42YKgXGI= | ||
github.com/elastic/go-perf v0.0.0-20191212140718-9c656876f595/go.mod h1:s09U1b4P1ZxnKx2OsqY7KlHdCesqZWIhyq0Gs/QC/Us= | ||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk= | ||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
// +build linux | ||
|
||
package main | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"runtime" | ||
"time" | ||
|
||
"github.com/cilium/ebpf" | ||
"github.com/cilium/ebpf/asm" | ||
ringbuffer "github.com/cilium/ebpf/perf" | ||
"golang.org/x/sys/unix" | ||
|
||
"github.com/elastic/go-perf" | ||
) | ||
|
||
// This program demonstrates how to attach an eBPF program to a tracepoint. | ||
// The program will be attached to the sys_enter_open syscall and print out the integer | ||
// 123 everytime the sycall is used. | ||
func main() { | ||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) | ||
defer cancel() | ||
|
||
var originalLimit unix.Rlimit | ||
// Get the original rlimit values so we can restore them laster. | ||
if err := unix.Getrlimit(unix.RLIMIT_MEMLOCK, &originalLimit); err != nil { | ||
panic(fmt.Errorf("failed to get rlimit: %v", err)) | ||
} | ||
|
||
// Increase rlimit so the eBPF map and program can be loaded. | ||
if err := unix.Setrlimit(unix.RLIMIT_MEMLOCK, &unix.Rlimit{ | ||
Cur: unix.RLIM_INFINITY, | ||
Max: unix.RLIM_INFINITY, | ||
}); err != nil { | ||
panic(fmt.Errorf("failed to set temporary rlimit: %v", err)) | ||
} | ||
|
||
events, err := ebpf.NewMap(&ebpf.MapSpec{ | ||
Type: ebpf.PerfEventArray, | ||
Name: "pureGo", | ||
}) | ||
if err != nil { | ||
panic(fmt.Errorf("could not create event map: %v", err)) | ||
} | ||
defer events.Close() | ||
|
||
rd, err := ringbuffer.NewReader(events, os.Getpagesize()) | ||
if err != nil { | ||
panic(fmt.Errorf("could not create event reader: %v", err)) | ||
} | ||
defer rd.Close() | ||
|
||
go func() { | ||
for { | ||
select { | ||
case <-ctx.Done(): | ||
return | ||
default: | ||
} | ||
record, err := rd.Read() | ||
if err != nil { | ||
if ringbuffer.IsClosed(err) { | ||
return | ||
} | ||
panic(fmt.Errorf("could not read from reader: %v", err)) | ||
} | ||
fmt.Println(record) | ||
} | ||
}() | ||
|
||
ins := asm.Instructions{ | ||
// store the integer 123 at FP[-8] | ||
asm.Mov.Imm(asm.R2, 123), | ||
asm.StoreMem(asm.RFP, -8, asm.R2, asm.Word), | ||
|
||
// load registers with arguments for call of FnPerfEventOutput | ||
asm.LoadMapPtr(asm.R2, events.FD()), | ||
asm.LoadImm(asm.R3, 0xffffffff, asm.DWord), | ||
asm.Mov.Reg(asm.R4, asm.RFP), | ||
asm.Add.Imm(asm.R4, -8), | ||
asm.Mov.Imm(asm.R5, 4), | ||
|
||
// call FnPerfEventOutput | ||
asm.FnPerfEventOutput.Call(), | ||
|
||
// set exit code to 0 | ||
asm.Mov.Imm(asm.R0, 0), | ||
asm.Return(), | ||
} | ||
|
||
prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ | ||
Name: "trace_open", | ||
Type: ebpf.TracePoint, | ||
License: "GPL", | ||
Instructions: ins, | ||
}) | ||
if err != nil { | ||
panic(fmt.Errorf("could not create new ebpf program: %v", err)) | ||
} | ||
defer prog.Close() | ||
|
||
ga := new(perf.Attr) | ||
gtp := perf.Tracepoint("syscalls", "sys_enter_open") | ||
if err := gtp.Configure(ga); err != nil { | ||
panic(fmt.Errorf("failed to configure tracepoint: %v", err)) | ||
} | ||
|
||
// Restore original rlimit values. | ||
if err := unix.Setrlimit(unix.RLIMIT_MEMLOCK, &originalLimit); err != nil { | ||
panic(fmt.Errorf("failed to restore original rlimit: %v", err)) | ||
} | ||
|
||
runtime.LockOSThread() | ||
defer runtime.UnlockOSThread() | ||
|
||
openTracepoint, err := perf.Open(ga, perf.AllThreads, 0, nil) | ||
if err != nil { | ||
panic(fmt.Errorf("failed to open perf event on tracepoint: %v", err)) | ||
} | ||
defer openTracepoint.Close() | ||
|
||
if err := openTracepoint.SetBPF(uint32(prog.FD())); err != nil { | ||
panic(fmt.Errorf("failed to attach eBPF to tracepoint: %v", err)) | ||
} | ||
if err := openTracepoint.Enable(); err != nil { | ||
panic(fmt.Errorf("failed to enable eBPF to tracepoint: %v", err)) | ||
} | ||
|
||
<-ctx.Done() | ||
} |
This file was deleted.
Oops, something went wrong.