pkg/proc: Fixed delve's version extraction to allow propsals (#798)

Go recently introduced proposal tags to their version tags, we
are simply allowing delve to handle it appropriately.

See:
0954fdd51e
This commit is contained in:
Nathan Bruer 2017-04-21 17:45:20 -07:00 committed by Derek Parker
parent b6fe5aebaf
commit 43f26fb4d6
6 changed files with 42 additions and 26 deletions

@ -44,7 +44,7 @@ func (a *AMD64) SetGStructOffset(ver GoVersion, isextld bool) {
a.gStructOffset = 0x8a0 a.gStructOffset = 0x8a0
case "linux": case "linux":
a.gStructOffset = 0xfffffffffffffff0 a.gStructOffset = 0xfffffffffffffff0
if isextld || ver.AfterOrEqual(GoVersion{1, 5, -1, 2, 0}) || ver.IsDevel() { if isextld || ver.AfterOrEqual(GoVersion{1, 5, -1, 2, 0, ""}) || ver.IsDevel() {
a.gStructOffset += 8 a.gStructOffset += 8
} }
case "windows": case "windows":

@ -9,15 +9,16 @@ import (
// the Go compiler version used to compile // the Go compiler version used to compile
// the target binary. // the target binary.
type GoVersion struct { type GoVersion struct {
Major int Major int
Minor int Minor int
Rev int Rev int
Beta int Beta int
RC int RC int
Proposal string
} }
var ( var (
GoVer18Beta = GoVersion{1, 8, -1, 0, 0} GoVer18Beta = GoVersion{1, 8, -1, 0, 0, ""}
) )
func ParseVersionString(ver string) (GoVersion, bool) { func ParseVersionString(ver string) (GoVersion, bool) {
@ -25,12 +26,12 @@ func ParseVersionString(ver string) (GoVersion, bool) {
var err1, err2, err3 error var err1, err2, err3 error
if strings.HasPrefix(ver, "devel") { if strings.HasPrefix(ver, "devel") {
return GoVersion{-1, 0, 0, 0, 0}, true return GoVersion{-1, 0, 0, 0, 0, ""}, true
} }
if strings.HasPrefix(ver, "go") { if strings.HasPrefix(ver, "go") {
ver := strings.Split(ver, " ")[0] ver := strings.Split(ver, " ")[0]
v := strings.SplitN(ver[2:], ".", 3) v := strings.SplitN(ver[2:], ".", 4)
switch len(v) { switch len(v) {
case 2: case 2:
r.Major, err1 = strconv.Atoi(v[0]) r.Major, err1 = strconv.Atoi(v[0])
@ -52,6 +53,7 @@ func ParseVersionString(ver string) (GoVersion, bool) {
r.Minor, err2 = strconv.Atoi(vr[0]) r.Minor, err2 = strconv.Atoi(vr[0])
r.Rev = -1 r.Rev = -1
r.Proposal = ""
if err1 != nil || err2 != nil || err3 != nil { if err1 != nil || err2 != nil || err3 != nil {
return GoVersion{}, false return GoVersion{}, false
@ -64,12 +66,25 @@ func ParseVersionString(ver string) (GoVersion, bool) {
r.Major, err1 = strconv.Atoi(v[0]) r.Major, err1 = strconv.Atoi(v[0])
r.Minor, err2 = strconv.Atoi(v[1]) r.Minor, err2 = strconv.Atoi(v[1])
r.Rev, err3 = strconv.Atoi(v[2]) r.Rev, err3 = strconv.Atoi(v[2])
r.Proposal = ""
if err1 != nil || err2 != nil || err3 != nil { if err1 != nil || err2 != nil || err3 != nil {
return GoVersion{}, false return GoVersion{}, false
} }
return r, true return r, true
case 4:
r.Major, err1 = strconv.Atoi(v[0])
r.Minor, err2 = strconv.Atoi(v[1])
r.Rev, err3 = strconv.Atoi(v[2])
r.Proposal = v[3];
if err1 != nil || err2 != nil || err3 != nil || r.Proposal == "" {
return GoVersion{}, false
}
return r, true
default: default:
return GoVersion{}, false return GoVersion{}, false
} }

@ -407,7 +407,7 @@ func TestNextGeneral(t *testing.T) {
ver, _ := proc.ParseVersionString(runtime.Version()) ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0}) { if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
testcases = []nextTest{ testcases = []nextTest{
{17, 19}, {17, 19},
{19, 20}, {19, 20},
@ -1004,12 +1004,13 @@ func versionAfterOrEqual(t *testing.T, verStr string, ver proc.GoVersion) {
} }
func TestParseVersionString(t *testing.T) { func TestParseVersionString(t *testing.T) {
versionAfterOrEqual(t, "go1.4", proc.GoVersion{1, 4, 0, 0, 0}) versionAfterOrEqual(t, "go1.4", proc.GoVersion{1, 4, 0, 0, 0, ""})
versionAfterOrEqual(t, "go1.5.0", proc.GoVersion{1, 5, 0, 0, 0}) versionAfterOrEqual(t, "go1.5.0", proc.GoVersion{1, 5, 0, 0, 0, ""})
versionAfterOrEqual(t, "go1.4.2", proc.GoVersion{1, 4, 2, 0, 0}) versionAfterOrEqual(t, "go1.4.2", proc.GoVersion{1, 4, 2, 0, 0, ""})
versionAfterOrEqual(t, "go1.5beta2", proc.GoVersion{1, 5, -1, 2, 0}) versionAfterOrEqual(t, "go1.5beta2", proc.GoVersion{1, 5, -1, 2, 0, ""})
versionAfterOrEqual(t, "go1.5rc2", proc.GoVersion{1, 5, -1, 0, 2}) versionAfterOrEqual(t, "go1.5rc2", proc.GoVersion{1, 5, -1, 0, 2, ""})
versionAfterOrEqual(t, "go1.6.1 (appengine-1.9.37)", proc.GoVersion{1, 6, 1, 0, 0}) versionAfterOrEqual(t, "go1.6.1 (appengine-1.9.37)", proc.GoVersion{1, 6, 1, 0, 0, ""})
versionAfterOrEqual(t, "go1.8.1.typealias", proc.GoVersion{1, 6, 1, 0, 0, ""})
ver, ok := proc.ParseVersionString("devel +17efbfc Tue Jul 28 17:39:19 2015 +0000 linux/amd64") ver, ok := proc.ParseVersionString("devel +17efbfc Tue Jul 28 17:39:19 2015 +0000 linux/amd64")
if !ok { if !ok {
t.Fatalf("Could not parse devel version string") t.Fatalf("Could not parse devel version string")
@ -1759,7 +1760,7 @@ func TestPackageVariables(t *testing.T) {
func TestIssue149(t *testing.T) { func TestIssue149(t *testing.T) {
ver, _ := proc.ParseVersionString(runtime.Version()) ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major > 0 && !ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0}) { if ver.Major > 0 && !ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
return return
} }
// setting breakpoint on break statement // setting breakpoint on break statement
@ -1951,7 +1952,7 @@ func TestIssue509(t *testing.T) {
func TestUnsupportedArch(t *testing.T) { func TestUnsupportedArch(t *testing.T) {
ver, _ := proc.ParseVersionString(runtime.Version()) ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major < 0 || !ver.AfterOrEqual(proc.GoVersion{1, 6, -1, 0, 0}) || ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0}) { if ver.Major < 0 || !ver.AfterOrEqual(proc.GoVersion{1, 6, -1, 0, 0, ""}) || ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
// cross compile (with -N?) works only on select versions of go // cross compile (with -N?) works only on select versions of go
return return
} }
@ -2090,7 +2091,7 @@ func TestStepIgnorePrivateRuntime(t *testing.T) {
// (such as runtime.convT2E in this case) // (such as runtime.convT2E in this case)
ver, _ := proc.ParseVersionString(runtime.Version()) ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0}) { if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
testseq("teststepprog", contStep, []nextTest{ testseq("teststepprog", contStep, []nextTest{
{21, 13}, {21, 13},
{13, 14}, {13, 14},
@ -2543,7 +2544,7 @@ func TestStacktraceWithBarriers(t *testing.T) {
// struct. // struct.
// In Go 1.9 stack barriers have been removed and this test must be disabled. // In Go 1.9 stack barriers have been removed and this test must be disabled.
if ver, _ := proc.ParseVersionString(runtime.Version()); ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 9, -1, 0, 0}) { if ver, _ := proc.ParseVersionString(runtime.Version()); ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 9, -1, 0, 0, ""}) {
return return
} }

@ -233,7 +233,7 @@ func Test1NextGeneral(t *testing.T) {
ver, _ := proc.ParseVersionString(runtime.Version()) ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0}) { if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
testcases = []nextTest{ testcases = []nextTest{
{17, 19}, {17, 19},
{19, 20}, {19, 20},

@ -269,7 +269,7 @@ func TestNextGeneral(t *testing.T) {
ver, _ := proc.ParseVersionString(runtime.Version()) ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0}) { if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
testcases = []nextTest{ testcases = []nextTest{
{17, 19}, {17, 19},
{19, 20}, {19, 20},
@ -1161,7 +1161,7 @@ func TestClientServer_Issue528(t *testing.T) {
// f744717d1924340b8f5e5a385e99078693ad9097 // f744717d1924340b8f5e5a385e99078693ad9097
ver, _ := proc.ParseVersionString(runtime.Version()) ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major > 0 && !ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0}) { if ver.Major > 0 && !ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
t.Log("Test skipped") t.Log("Test skipped")
return return
} }

@ -645,7 +645,7 @@ func TestEvalExpression(t *testing.T) {
} }
ver, _ := proc.ParseVersionString(runtime.Version()) ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major >= 0 && !ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0}) { if ver.Major >= 0 && !ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
for i := range testcases { for i := range testcases {
if testcases[i].name == "iface3" { if testcases[i].name == "iface3" {
testcases[i].value = "interface {}(*map[string]go/constant.Value) *[]" testcases[i].value = "interface {}(*map[string]go/constant.Value) *[]"
@ -766,7 +766,7 @@ func TestIssue426(t *testing.T) {
} }
ver, _ := proc.ParseVersionString(runtime.Version()) ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 8, -1, 0, 0}) { if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 8, -1, 0, 0, ""}) {
testcases[2].typ = `struct { main.val go/constant.Value }` testcases[2].typ = `struct { main.val go/constant.Value }`
testcases[3].typ = `func(struct { main.i int }, interface {}, struct { main.val go/constant.Value })` testcases[3].typ = `func(struct { main.i int }, interface {}, struct { main.val go/constant.Value })`
testcases[4].typ = `struct { main.i int; main.j int }` testcases[4].typ = `struct { main.i int; main.j int }`
@ -821,7 +821,7 @@ func TestPackageRenames(t *testing.T) {
} }
ver, _ := proc.ParseVersionString(runtime.Version()) ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major > 0 && !ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0}) { if ver.Major > 0 && !ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
// Not supported on 1.6 or earlier // Not supported on 1.6 or earlier
return return
} }