]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: skip trailing wrappers in runtime_expandFinalInlineFrame
authorTolyan Korniltsev <korniltsev.anatoly@gmail.com>
Sat, 4 Feb 2023 06:53:34 +0000 (14:53 +0800)
committerGopher Robot <gobot@golang.org>
Thu, 9 Feb 2023 20:43:56 +0000 (20:43 +0000)
The existing runtime_expandFinalInlineFrame implementation doesn't skip trailing wrappers, but
gentraceback does skip wrapper functions.
This change makes runtime_expandFinalInlineFrame handling wrapper functions consistent to gentraceback.

Fixes #58288

Change-Id: I1b0e2c10b0a89bcb1e787b98d27730cb40a34406
Reviewed-on: https://go-review.googlesource.com/c/go/+/465097
Reviewed-by: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Michael Pratt <mpratt@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
Reviewed-by: David Chase <drchase@google.com>
src/runtime/pprof/pprof_test.go
src/runtime/symtab.go

index 53688ad825b514d7aac1a4a659dc0b4f573ca502..b19ac16170a969c2a4009c2f9c4205accf5ef440 100644 (file)
@@ -333,6 +333,23 @@ func inlinedCalleeDump(pcs []uintptr) {
        dumpCallers(pcs)
 }
 
+type inlineWrapperInterface interface {
+       dump(stack []uintptr)
+}
+
+type inlineWrapper struct {
+}
+
+func (h inlineWrapper) dump(pcs []uintptr) {
+       dumpCallers(pcs)
+}
+
+func inlinedWrapperCallerDump(pcs []uintptr) {
+       var h inlineWrapperInterface
+       h = &inlineWrapper{}
+       h.dump(pcs)
+}
+
 func TestCPUProfileRecursion(t *testing.T) {
        matches := matchAndAvoidStacks(stackContains, []string{"runtime/pprof.inlinedCallee", "runtime/pprof.recursionCallee", "runtime/pprof.recursionCaller"}, avoidFunctions())
        p := testCPUProfile(t, matches, func(dur time.Duration) {
@@ -2054,6 +2071,8 @@ func TestTryAdd(t *testing.T) {
        for i := range pcs {
                inlinedCallerStack[i] = uint64(pcs[i])
        }
+       wrapperPCs := make([]uintptr, 1)
+       inlinedWrapperCallerDump(wrapperPCs)
 
        if _, found := findInlinedCall(recursionChainBottom, 4<<10); !found {
                t.Skip("Can't determine whether anything was inlined into recursionChainBottom.")
@@ -2226,6 +2245,17 @@ func TestTryAdd(t *testing.T) {
                        {Value: []int64{70, 70 * period}, Location: []*profile.Location{{ID: 1}}},
                        {Value: []int64{80, 80 * period}, Location: []*profile.Location{{ID: 2}, {ID: 1}}},
                },
+       }, {
+               name: "expand_wrapper_function",
+               input: []uint64{
+                       3, 0, 500, // hz = 500. Must match the period.
+                       4, 0, 50, uint64(wrapperPCs[0]),
+               },
+               count:    2,
+               wantLocs: [][]string{{"runtime/pprof.inlineWrapper.dump"}},
+               wantSamples: []*profile.Sample{
+                       {Value: []int64{50, 50 * period}, Location: []*profile.Location{{ID: 1}}},
+               },
        }}
 
        for _, tc := range testCases {
index dead27e5f238ace82a8b3a4146130faca8a0bc91..da83fd93ea7cccddfe08af8f6d50562ac950bcf3 100644 (file)
@@ -230,7 +230,11 @@ func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr {
        }
 
        // N.B. we want to keep the last parentPC which is not inline.
-       stk = append(stk, pc)
+       if f.funcID == funcID_wrapper && elideWrapperCalling(lastFuncID) {
+               // Ignore wrapper functions (except when they trigger panics).
+       } else {
+               stk = append(stk, pc)
+       }
 
        return stk
 }