Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime.Func.FileLine() returns the wrong line number #754

Closed
gopherbot opened this issue Apr 28, 2010 · 6 comments
Closed

runtime.Func.FileLine() returns the wrong line number #754

gopherbot opened this issue Apr 28, 2010 · 6 comments

Comments

@gopherbot
Copy link

by esko.luontola:

What steps will reproduce the problem?

import (
    "testing"
    "runtime"
)

func TestBug(t *testing.T) {
    pc, fileCaller, lineCaller, _ := runtime.Caller(0)
    
    f := runtime.FuncForPC(pc)
    fileFunc, lineFunc := f.FileLine(pc)
    
    t.Log(fileCaller, fileFunc)
    if fileCaller != fileFunc {
        t.Errorf("file wrong: %v != %v", fileCaller, fileFunc)
    }
    
    t.Log(lineCaller, lineFunc)
    if lineCaller != lineFunc {
        t.Errorf("line wrong: %v != %v", lineCaller, lineFunc)
    }
}

What is the expected output? What do you see instead?

--- FAIL: gospec.TestBug
    /home/orfjackal/devel/gospec/src/gospec/bug_test.go 
/home/orfjackal/devel/gospec/src/gospec/bug_test.go
    9 1126
    line wrong: 9 != 1126

What is your $GOOS?  $GOARCH?
linux amd64

Which revision are you using?  (hg identify)
d1615461b60e tip
@gopherbot
Copy link
Author

Comment 1 by esko.luontola:

The functions symtab.c:/^funcline and extern.go:/FileLine appear to have comments, that 
if you edit one of them, you should edit also the other. The code looks too cryptic for 
me to tell whether the two functions do the same thing or not.
Somebody should add an automated test which makes sure that both of the functions do 
the same thing, to avoid the implementations from drifting apart. Even better would be 
to implement one of them by calling the other - that would remove the duplicated code.

@rsc
Copy link
Contributor

rsc commented Apr 28, 2010

Comment 2:

Status changed to Accepted.

@gopherbot
Copy link
Author

Comment 3 by StepLg:

It seems, that the bug is around here:
runtime/extern.go: func (f *Func) FileLine(pc uintptr)
const PcQuant = 1
because in symtab.c:/^funcline there is:
    int32 pcquant;
    switch(thechar) {
    case '5':
        pcquant = 4;
        break;
    default:    // 6, 8
        pcquant = 1;
        break;
    }
i found, that 'thechar' is information about compiler:
$GO/src/pkg/runtime% grep -r thechar .
./amd64/arch.h: thechar = '6'
./386/arch.h:   thechar = '8'
./arm/arch.h:   thechar = '5'
but i don't know how to get the same info in go

@gopherbot
Copy link
Author

Comment 4 by StepLg:

and another difference:
in symtab.c:/^funcline
} else if(*p <= 128) {
    line -= *p - 64;
}
and in runtime/extern.go: func (f *Func) FileLine(pc uintptr)
case p[i] <= 128:
    line += int(p[i] - 64)

@rsc
Copy link
Contributor

rsc commented Sep 11, 2010

Comment 5:

Verified that this bug is now fixed.
I believe it was 
changeset:   6158:523da6275fc6
user:        Russ Cox <rsc@golang.org>
date:        Thu Sep 02 14:19:12 2010 -0400
summary:     runtime: add GOOS, GOARCH; fix FuncLine

Status changed to Fixed.

@gopherbot
Copy link
Author

Comment 6 by esko.luontola:

I found an off-by-one in the line numbers reported by FuncLine(). I've reported it as a
separate issue: https://golang.org/issue/1100
I still think that the best solution would be to refactor the code to remove the code
duplication between extern.go and symtab.c. That would eliminate one "bug breeding
ground" as mentioned in http://jamesshore.com/Agile-Book/no_bugs.html Now that same
copy-pasted function has resulted already in two bugs.

@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants