diff --git a/cmd/stackwhere/list_test.go b/cmd/stackwhere/list_test.go index ca20e85..4fe1bf3 100644 --- a/cmd/stackwhere/list_test.go +++ b/cmd/stackwhere/list_test.go @@ -110,6 +110,22 @@ func TestListCollectionIncludesInstructionOnlyStackUsage(t *testing.T) { } } +func TestListCollectionIncludesVoidFunction(t *testing.T) { + cmd := root() + cmd.SetArgs([]string{"list", "../../testdata/noinline.o"}) + + var stdout bytes.Buffer + cmd.SetOut(&stdout) + + if err := cmd.Execute(); err != nil { + t.Fatalf("list command failed: %v", err) + } + + if got := stdout.String(); !strings.Contains(got, "0 bytes - helper") { + t.Fatalf("expected void helper in collection output, got %q", got) + } +} + func TestListCollectionWritesToConfiguredOutput(t *testing.T) { cmd := root() cmd.SetArgs([]string{"list", "../../testdata/basic.o"}) diff --git a/internal/stackview/stackview.go b/internal/stackview/stackview.go index e3bf2b2..aeb1c48 100644 --- a/internal/stackview/stackview.go +++ b/internal/stackview/stackview.go @@ -324,7 +324,9 @@ func isBPFProgram(n *dbgdwarf.Node) bool { return false } - if n.Entry().Val(dbgdwarf.AttrType) == nil { + // Concrete functions have an address or ranges. Unlike declarations, void + // functions have executable code but no return type attribute. + if n.Entry().Val(dbgdwarf.AttrLowpc) == nil && n.Entry().Val(dbgdwarf.AttrRanges) == nil { return false }