From 9d4f0f03d6e3b09c4df4e22678e9fc6841b1eedf Mon Sep 17 00:00:00 2001 From: immanuwell Date: Mon, 6 Jul 2026 21:28:23 +0400 Subject: [PATCH] fix: dedupe repeated inline rows in list output Signed-off-by: immanuwell --- cmd/stackwhere/list.go | 10 ++++++++++ cmd/stackwhere/list_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/cmd/stackwhere/list.go b/cmd/stackwhere/list.go index de69efb..84c0201 100644 --- a/cmd/stackwhere/list.go +++ b/cmd/stackwhere/list.go @@ -163,6 +163,12 @@ func (psl *programStackList) runListProgram(cmd *cobra.Command, args []string) e w := cmd.OutOrStdout() for _, slots := range usage { + if !*psl.flagCallStack { + slots = slices.CompactFunc(slices.Clone(slots), func(a, b slotUsage) bool { + return a.displayEqual(b) + }) + } + if _, err := fmt.Fprintf(w, "R10-%d:\n", slots[0].Offset); err != nil { return err } @@ -215,6 +221,10 @@ type slotUsage struct { Callstack []callStackEntry `json:"callstack,omitempty"` } +func (s slotUsage) displayEqual(other slotUsage) bool { + return s.Name == other.Name && s.ByteSize == other.ByteSize && s.FileLineCol == other.FileLineCol +} + type callStackEntry struct { Name string `json:"name"` FileLineCol string `json:"file_line_col"` diff --git a/cmd/stackwhere/list_test.go b/cmd/stackwhere/list_test.go index a673986..3e8601a 100644 --- a/cmd/stackwhere/list_test.go +++ b/cmd/stackwhere/list_test.go @@ -211,6 +211,32 @@ func TestListProgramWritesToConfiguredOutput(t *testing.T) { if !strings.Contains(got, "32 - a @") { t.Fatalf("expected stack slot details in configured writer, got %q", got) } + if strings.Count(got, "16 - two_inlined_a @ /src/basic.c:81") != 1 { + t.Fatalf("expected duplicate inline rows to be suppressed in default output, got %q", got) + } + if strings.Count(got, "16 - two_inlined_b @ /src/basic.c:75") != 1 { + t.Fatalf("expected duplicate inline rows to be suppressed in default output, got %q", got) + } +} + +func TestListProgramCallStackPreservesDistinctInlineCallSites(t *testing.T) { + cmd := root() + cmd.SetArgs([]string{"list", "../../testdata/basic.o", "cil_entry", "--call-stack"}) + + var stdout bytes.Buffer + cmd.SetOut(&stdout) + + if err := cmd.Execute(); err != nil { + t.Fatalf("list command failed: %v", err) + } + + got := stdout.String() + if strings.Count(got, "16 - two_inlined_a @ /src/basic.c:81") != 2 { + t.Fatalf("expected both inline call sites in call-stack output, got %q", got) + } + if !strings.Contains(got, "inlined_a @ /src/basic.c:93:9") || !strings.Contains(got, "inlined_a @ /src/basic.c:103:9") { + t.Fatalf("expected both inline call stacks in output, got %q", got) + } } func TestSortedProgramStackUsageOrdersEqualUsageByName(t *testing.T) {