Use CallersFrames to build StackFrames (required for go 1.12) #114
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Goal
Go 1.12 uses more aggressive function call inlining which requires employing
runtime.CallersFrames()
to rebuild the function call stack correctly. (see https://golang.org/doc/go1.12#compiler). Included test case demonstrates the problem when trying to reconstruct the stack captured by thejackfan.us.kg/pkg/errors
package.If you run the test with the debug prints uncommented (and without the fix), you'll see that the top frame in the original stack and the top frame in the stack built by
StackFrames()
don't match. This is because theerrors.New()
call is (likely) inlined and therefore this part of https://golang.org/pkg/runtime/#FuncForPC appliesDesign
Use the
runtime.CallersFrames()
function to reconstruct the stack as documented.Changeset
Since the use of
FuncForPC
should be avoided we need to createStackFrames
fromruntime.Frames
instead of PCs. The change modifiesStackFrames()
andNewStackFrame()
accordingly.Tests
Added
Test_StackFrames
to demonstrate the problem. I tried to reproduce it without using thejackfan.us.kg/pkg/errors
at first but was struggling to get the compiler to inline. So I reverted back to using the errors package where I first observed the problem. We can try harder to reproduce without the package or otherwise include it in the dependencies (My test runs pulled the package from my GOPATH).Discussion
I made this PR largely to document the problem and propose the solution. Feel free to reject it for a different approach.
Alternative Approaches
This is the documented way to reconstruct the call stack, it's probably not worth trying to come up with alternative solutions.
Outstanding Questions
github.com/pkg/errors
in the test case. Can it be added as a dependency or should we try harder to reproduce inlining without it?Review
For the submitter, initial self-review:
For the pull request reviewer(s), this changeset has been reviewed for: