2

I am confused when studying the pkg/errors. In the file stack.go, we can see the comment about the struct Frame as below:

// Frame represents a program counter inside a stack frame.
// For historical reasons if Frame is interpreted as a uintptr
// its value represents the program counter + 1.
type Frame uintptr

// pc returns the program counter for this frame;
// multiple frames may have the same PC value.
func (f Frame) pc() uintptr { return uintptr(f) - 1 }

Could anyone tell me Why the pc function get the uintptr(f) - 1 as the program counter value. I write some code about the pc to test, I can get the right answer althought rewrite the pc function as below:

type Frame uintptr

func (f Frame) pc() uintptr { return uintptr(f) }

func (f Frame) line() int {
    fn := runtime.FuncForPC(f.pc())
    if fn == nil {
        return 0
    }
    _, line := fn.FileLine(f.pc())
    return line
}

func main() {

    var pc, _, line, _ = runtime.Caller(0)
    fmt.Printf("pc:%v, line:%v\n", pc, line)

    fmt.Println("-------------")

    frame := Frame(pc)
    line = frame.line()
    fmt.Printf("Frame:%v, line:%v\n", uintptr(frame), line)
}

The result of the code is :

pc:4779003, line:23
-------------
Frame:4779003, line:23
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
RocketMan
  • 21
  • 2

1 Answers1

0

https://github.com/golang/go/blob/897b3da2e079b9b940b309747305a5379fffa6ec/src/runtime/traceback.go#L339

// Normally, pc is a return address. In that case, we want to look up
// file/line information using pc-1, because that is the pc of the
// call instruction (more precisely, the last byte of the call instruction).
// Callers expect the pc buffer to contain return addresses and do the
// same -1 themselves, so we keep pc unchanged.
// When the pc is from a signal (e.g. profiler or segv) then we want
// to look up file/line information using pc, and we store pc+1 in the
// pc buffer so callers can unconditionally subtract 1 before looking up.
// See issue 34123.
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 18 '22 at 17:05
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/30847830) – mbuechmann Jan 24 '22 at 13:55