diff --git a/main.go b/main.go index fc3a2f3..5cf3b54 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,7 @@ package main import ( "embed" "fmt" - "io/ioutil" + "io" "log" "os" "path/filepath" @@ -72,7 +72,22 @@ func (t Target) Arg(i int) string { return fmt.Sprintf("reg(\"%s\")", regs[i]) } - return fmt.Sprintf("sarg%d", i) + // FIX: WARNING: sarg* is deprecated and will be removed in the future. Use *(reg("sp") + ) instead. + return fmt.Sprintf(`*(reg("sp") + %d)`, 8*(i+1)) +} + +// RetArg maps return argument indices to bpftrace built-ins taking into account which ABI +// is in use +func (t Target) RetArg(i, offset int) string { + if t.RegsABI { + // rax, rbx, rcx, rdi, rsi, r8, r9, r10, r11 should do + if i < 0 || i >= len(regs) { + panic("argument out of bounds. roll your own") + } + return fmt.Sprintf("reg(\"%s\")", regs[i]) + } + + return fmt.Sprintf(`*(reg("sp") + %d)`, 8*(i+1+offset)) } func NewTarget(exe string, arguments func(string) []string) (*Target, error) { @@ -128,14 +143,14 @@ func main() { log.Fatal(err) } - scriptTemplate, err := ioutil.ReadFile(scriptFile) + scriptTemplate, err := os.ReadFile(scriptFile) if err != nil { // try embedded files f, err1 := templates.Open(scriptFile) if err1 != nil { log.Fatalf("failed to open %s on filesystem: (%s), tried embedded files got %s", scriptFile, err, err1) } - scriptTemplate, err = ioutil.ReadAll(f) + scriptTemplate, err = io.ReadAll(f) if err != nil { panic(err) } diff --git a/templates/httpsnoop.bt b/templates/httpsnoop.bt index 31821fd..ae9a9c5 100644 --- a/templates/httpsnoop.bt +++ b/templates/httpsnoop.bt @@ -11,7 +11,8 @@ struct url { }; struct request { - uint8_t pad[16]; + uint8_t *method; + int methodlen; struct url *url; }; @@ -28,45 +29,45 @@ uprobe:{{ .ExePath }}:runtime.execute { } tracepoint:sched:sched_process_exit { + delete(@rmethod[@gids[tid], pid]); delete(@rscheme[@gids[tid], pid]); delete(@rhost[@gids[tid], pid]); delete(@rpath[@gids[tid], pid]); -{{ if not .RegsABI }} - delete(@addr[@gids[tid], pid]); -{{ end }} delete(@gids[tid]); } - uprobe:{{ .ExePath }}:"net/http.(*Client).do" { - $url = ((struct request *){{ .Arg 1 }})->url; + $request = ((struct request *){{ .Arg 1 }}); + $url = $request->url; + $method = str($request->method, $request->methodlen); $scheme = str($url->scheme, $url->schemelen); $host = str($url->host, $url->hostlen); $path = str($url->path, $url->pathlen); + @rmethod[@gids[tid], pid] = $method; @rscheme[@gids[tid], pid] = $scheme; @rhost[@gids[tid], pid] = $host; @rpath[@gids[tid], pid] = $path; } - -{{ range $index, $r := $.SymbolReturns "net/http.(*Client).do" -}} +{{range $index, $r := $.SymbolReturns "net/http.(*Client).do" -}} {{ if $index }}, {{ end }} uprobe:{{ $.ExePath }}:"net/http.(*Client).do" + {{ $r -}} {{ end }} { - {{ if $.RegsABI }} - $resp = (struct response *)reg("ax"); - {{ else }} - @addr[@gids[tid], pid] = *(reg("sp") + 24); - $resp = (struct response *)@addr[@gids[tid], pid]; - {{ end }} + $resp = (struct response *){{ .RetArg 0 2 }}; + if ($resp == 0) { - printf("error %s://%s%s\n", @rscheme[@gids[tid], pid], @rhost[@gids[tid], pid], @rpath[@gids[tid], pid]); + printf("error %s %s://%s%s\n", + @rmethod[@gids[tid], pid], + @rscheme[@gids[tid], pid], + @rhost[@gids[tid], pid], + @rpath[@gids[tid], pid]); } else { - printf("%d: %s://%s%s\n", $resp->statuscode, @rscheme[@gids[tid], pid], @rhost[@gids[tid], pid], @rpath[@gids[tid], pid]); + printf("%d: %s %s://%s%s\n", + $resp->statuscode, + @rmethod[@gids[tid], pid], + @rscheme[@gids[tid], pid], + @rhost[@gids[tid], pid], + @rpath[@gids[tid], pid]); } print(ustack()); } - - - -