提交 1128c26b 编写于 作者: A aarzilli 提交者: Derek Parker

cmd/dlv: do not pass "linkmode internal" for windows on go1.9 and later

go1.9 no longer needs "linkmode internal" on windows.

Fixes #755
Fixes #477
Fixes #631
上级 a17de32c
......@@ -15,6 +15,7 @@ import (
"unicode"
"github.com/derekparker/delve/pkg/config"
"github.com/derekparker/delve/pkg/goversion"
"github.com/derekparker/delve/pkg/terminal"
"github.com/derekparker/delve/pkg/version"
"github.com/derekparker/delve/service"
......@@ -76,8 +77,11 @@ func New(docCall bool) *cobra.Command {
conf = config.LoadConfig()
buildFlagsDefault := ""
if runtime.GOOS == "windows" {
// Work-around for https://github.com/golang/go/issues/13154
buildFlagsDefault = "-ldflags='-linkmode internal'"
ver, _ := goversion.Installed()
if ver.Major > 0 && !ver.AfterOrEqual(goversion.GoVersion{1, 9, -1, 0, 0, ""}) {
// Work-around for https://github.com/golang/go/issues/13154
buildFlagsDefault = "-ldflags='-linkmode internal'"
}
}
// Main dlv root command.
......
package proc
package goversion
import (
"os/exec"
"strconv"
"strings"
)
......@@ -13,7 +14,7 @@ type GoVersion struct {
Minor int
Rev int
Beta int
RC int
RC int
Proposal string
}
......@@ -21,7 +22,8 @@ var (
GoVer18Beta = GoVersion{1, 8, -1, 0, 0, ""}
)
func ParseVersionString(ver string) (GoVersion, bool) {
// Parse parses a go verison string
func Parse(ver string) (GoVersion, bool) {
var r GoVersion
var err1, err2, err3 error
......@@ -130,3 +132,21 @@ func (v *GoVersion) AfterOrEqual(b GoVersion) bool {
func (v *GoVersion) IsDevel() bool {
return v.Major < 0
}
const goVersionPrefix = "go version "
// Installed runs "go verison" and parses the output
func Installed() (GoVersion, bool) {
out, err := exec.Command("go", "version").CombinedOutput()
if err != nil {
return GoVersion{}, false
}
s := string(out)
if !strings.HasPrefix(s, goVersionPrefix) {
return GoVersion{}, false
}
return Parse(s[len(goVersionPrefix):])
}
package goversion
import (
"runtime"
"testing"
)
func versionAfterOrEqual(t *testing.T, verStr string, ver GoVersion) {
pver, ok := Parse(verStr)
if !ok {
t.Fatalf("Could not parse version string <%s>", verStr)
}
if !pver.AfterOrEqual(ver) {
t.Fatalf("Version <%s> parsed as %v not after %v", verStr, pver, ver)
}
t.Logf("version string <%s> → %v", verStr, ver)
}
func TestParseVersionString(t *testing.T) {
versionAfterOrEqual(t, "go1.4", GoVersion{1, 4, 0, 0, 0, ""})
versionAfterOrEqual(t, "go1.5.0", GoVersion{1, 5, 0, 0, 0, ""})
versionAfterOrEqual(t, "go1.4.2", GoVersion{1, 4, 2, 0, 0, ""})
versionAfterOrEqual(t, "go1.5beta2", GoVersion{1, 5, -1, 2, 0, ""})
versionAfterOrEqual(t, "go1.5rc2", GoVersion{1, 5, -1, 0, 2, ""})
versionAfterOrEqual(t, "go1.6.1 (appengine-1.9.37)", GoVersion{1, 6, 1, 0, 0, ""})
versionAfterOrEqual(t, "go1.8.1.typealias", GoVersion{1, 6, 1, 0, 0, ""})
ver, ok := Parse("devel +17efbfc Tue Jul 28 17:39:19 2015 +0000 linux/amd64")
if !ok {
t.Fatalf("Could not parse devel version string")
}
if !ver.IsDevel() {
t.Fatalf("Devel version string not correctly recognized")
}
}
func TestInstalled(t *testing.T) {
installedVersion, ok := Installed()
if !ok {
t.Fatalf("could not parse output of go version")
}
runtimeVersion, ok := Parse(runtime.Version())
if !ok {
t.Fatalf("could not parse output of runtime.Version() %q", runtime.Version())
}
t.Logf("installed: %v", installedVersion)
t.Logf("runtime: %v", runtimeVersion)
if installedVersion != runtimeVersion {
t.Fatalf("version mismatch %#v %#v", installedVersion, runtimeVersion)
}
}
......@@ -9,7 +9,6 @@ import (
"go/token"
"path/filepath"
"strconv"
"strings"
)
type functionDebugInfo struct {
......
......@@ -20,6 +20,7 @@ import (
"time"
"github.com/derekparker/delve/pkg/dwarf/frame"
"github.com/derekparker/delve/pkg/goversion"
"github.com/derekparker/delve/pkg/proc"
"github.com/derekparker/delve/pkg/proc/gdbserial"
"github.com/derekparker/delve/pkg/proc/native"
......@@ -429,9 +430,9 @@ func testseq(program string, contFunc contFunc, testcases []nextTest, initialLoc
func TestNextGeneral(t *testing.T) {
var testcases []nextTest
ver, _ := proc.ParseVersionString(runtime.Version())
ver, _ := goversion.Parse(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
if ver.Major < 0 || ver.AfterOrEqual(goversion.GoVersion{1, 7, -1, 0, 0, ""}) {
testcases = []nextTest{
{17, 19},
{19, 20},
......@@ -582,9 +583,9 @@ func TestNextFunctionReturn(t *testing.T) {
func TestNextFunctionReturnDefer(t *testing.T) {
var testcases []nextTest
ver, _ := proc.ParseVersionString(runtime.Version())
ver, _ := goversion.Parse(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 9, -1, 0, 0, ""}) {
if ver.Major < 0 || ver.AfterOrEqual(goversion.GoVersion{1, 9, -1, 0, 0, ""}) {
testcases = []nextTest{
{5, 6},
{6, 9},
......@@ -1062,34 +1063,6 @@ func TestContinueMulti(t *testing.T) {
})
}
func versionAfterOrEqual(t *testing.T, verStr string, ver proc.GoVersion) {
pver, ok := proc.ParseVersionString(verStr)
if !ok {
t.Fatalf("Could not parse version string <%s>", verStr)
}
if !pver.AfterOrEqual(ver) {
t.Fatalf("Version <%s> parsed as %v not after %v", verStr, pver, ver)
}
t.Logf("version string <%s> → %v", verStr, ver)
}
func TestParseVersionString(t *testing.T) {
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.4.2", proc.GoVersion{1, 4, 2, 0, 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.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")
if !ok {
t.Fatalf("Could not parse devel version string")
}
if !ver.IsDevel() {
t.Fatalf("Devel version string not correctly recognized")
}
}
func TestBreakpointOnFunctionEntry(t *testing.T) {
protest.AllowRecording(t)
withTestProcess("testprog", t, func(p proc.Process, fixture protest.Fixture) {
......@@ -1882,8 +1855,8 @@ func TestPackageVariables(t *testing.T) {
}
func TestIssue149(t *testing.T) {
ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major > 0 && !ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
ver, _ := goversion.Parse(runtime.Version())
if ver.Major > 0 && !ver.AfterOrEqual(goversion.GoVersion{1, 7, -1, 0, 0, ""}) {
return
}
// setting breakpoint on break statement
......@@ -2074,8 +2047,8 @@ func TestIssue509(t *testing.T) {
}
func TestUnsupportedArch(t *testing.T) {
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, ""}) {
ver, _ := goversion.Parse(runtime.Version())
if ver.Major < 0 || !ver.AfterOrEqual(goversion.GoVersion{1, 6, -1, 0, 0, ""}) || ver.AfterOrEqual(goversion.GoVersion{1, 7, -1, 0, 0, ""}) {
// cross compile (with -N?) works only on select versions of go
return
}
......@@ -2184,8 +2157,8 @@ func TestStepCallPtr(t *testing.T) {
func TestStepReturnAndPanic(t *testing.T) {
// Tests that Step works correctly when returning from functions
// and when a deferred function is called when panic'ing.
ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 9, -1, 0, 0, ""}) {
ver, _ := goversion.Parse(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(goversion.GoVersion{1, 9, -1, 0, 0, ""}) {
testseq("defercall", contStep, []nextTest{
{17, 5},
{5, 6},
......@@ -2227,9 +2200,9 @@ func TestStepDeferReturn(t *testing.T) {
func TestStepIgnorePrivateRuntime(t *testing.T) {
// Tests that Step will ignore calls to private runtime functions
// (such as runtime.convT2E in this case)
ver, _ := proc.ParseVersionString(runtime.Version())
ver, _ := goversion.Parse(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
if ver.Major < 0 || ver.AfterOrEqual(goversion.GoVersion{1, 7, -1, 0, 0, ""}) {
testseq("teststepprog", contStep, []nextTest{
{21, 13},
{13, 14},
......@@ -2705,7 +2678,7 @@ func TestStacktraceWithBarriers(t *testing.T) {
// struct.
// 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, _ := goversion.Parse(runtime.Version()); ver.Major < 0 || ver.AfterOrEqual(goversion.GoVersion{1, 9, -1, 0, 0, ""}) {
return
}
......
......@@ -13,7 +13,7 @@ import (
protest "github.com/derekparker/delve/pkg/proc/test"
"github.com/derekparker/delve/pkg/proc"
"github.com/derekparker/delve/pkg/goversion"
"github.com/derekparker/delve/service"
"github.com/derekparker/delve/service/api"
"github.com/derekparker/delve/service/rpc1"
......@@ -240,9 +240,9 @@ func testnext(testcases []nextTest, initialLocation string, t *testing.T) {
func Test1NextGeneral(t *testing.T) {
var testcases []nextTest
ver, _ := proc.ParseVersionString(runtime.Version())
ver, _ := goversion.Parse(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
if ver.Major < 0 || ver.AfterOrEqual(goversion.GoVersion{1, 7, -1, 0, 0, ""}) {
testcases = []nextTest{
{17, 19},
{19, 20},
......@@ -1025,8 +1025,8 @@ func Test1SkipPrologue2(t *testing.T) {
callme3 := findLocationHelper(t, c, "main.callme3", false, 1, 0)[0]
callme3Z := findLocationHelper(t, c, "main.callme3:0", false, 1, 0)[0]
ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(proc.GoVer18Beta) {
ver, _ := goversion.Parse(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(goversion.GoVer18Beta) {
findLocationHelper(t, c, "callme.go:19", false, 1, callme3)
} else {
// callme3 does not have local variables therefore the first line of the
......
......@@ -15,7 +15,7 @@ import (
protest "github.com/derekparker/delve/pkg/proc/test"
"github.com/derekparker/delve/pkg/proc"
"github.com/derekparker/delve/pkg/goversion"
"github.com/derekparker/delve/service"
"github.com/derekparker/delve/service/api"
"github.com/derekparker/delve/service/rpc2"
......@@ -285,9 +285,9 @@ func testnext2(testcases []nextTest, initialLocation string, t *testing.T) {
func TestNextGeneral(t *testing.T) {
var testcases []nextTest
ver, _ := proc.ParseVersionString(runtime.Version())
ver, _ := goversion.Parse(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
if ver.Major < 0 || ver.AfterOrEqual(goversion.GoVersion{1, 7, -1, 0, 0, ""}) {
testcases = []nextTest{
{17, 19},
{19, 20},
......@@ -1099,8 +1099,8 @@ func TestSkipPrologue2(t *testing.T) {
callme3 := findLocationHelper(t, c, "main.callme3", false, 1, 0)[0]
callme3Z := findLocationHelper(t, c, "main.callme3:0", false, 1, 0)[0]
ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(proc.GoVer18Beta) {
ver, _ := goversion.Parse(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(goversion.GoVer18Beta) {
findLocationHelper(t, c, "callme.go:19", false, 1, callme3)
} else {
// callme3 does not have local variables therefore the first line of the
......@@ -1200,8 +1200,8 @@ func TestClientServer_Issue528(t *testing.T) {
// Was fixed in go 1.7 // Commit that fixes the issue in go:
// f744717d1924340b8f5e5a385e99078693ad9097
ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major > 0 && !ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
ver, _ := goversion.Parse(runtime.Version())
if ver.Major > 0 && !ver.AfterOrEqual(goversion.GoVersion{1, 7, -1, 0, 0, ""}) {
t.Log("Test skipped")
return
}
......
......@@ -7,6 +7,7 @@ import (
"strings"
"testing"
"github.com/derekparker/delve/pkg/goversion"
"github.com/derekparker/delve/pkg/proc"
"github.com/derekparker/delve/pkg/proc/gdbserial"
"github.com/derekparker/delve/pkg/proc/native"
......@@ -441,8 +442,8 @@ func TestEmbeddedStruct(t *testing.T) {
}
assertNoError(proc.Continue(p), t, "Continue()")
ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major >= 0 && !ver.AfterOrEqual(proc.GoVersion{1, 9, -1, 0, 0, ""}) {
ver, _ := goversion.Parse(runtime.Version())
if ver.Major >= 0 && !ver.AfterOrEqual(goversion.GoVersion{1, 9, -1, 0, 0, ""}) {
// on go < 1.9 embedded fields had different names
for i := range testcases {
if testcases[i].name == "b2" {
......@@ -711,8 +712,8 @@ func TestEvalExpression(t *testing.T) {
{"tm", false, "main.truncatedMap {v: []map[string]main.astruct len: 1, cap: 1, [[...]]}", "main.truncatedMap {v: []map[string]main.astruct len: 1, cap: 1, [...]}", "main.truncatedMap", nil},
}
ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major >= 0 && !ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
ver, _ := goversion.Parse(runtime.Version())
if ver.Major >= 0 && !ver.AfterOrEqual(goversion.GoVersion{1, 7, -1, 0, 0, ""}) {
for i := range testcases {
if testcases[i].name == "iface3" {
testcases[i].value = "interface {}(*map[string]go/constant.Value) *[]"
......@@ -836,8 +837,8 @@ func TestIssue426(t *testing.T) {
{"anoniface1", `interface { OtherFunction(int, int); SomeFunction(struct { val go/constant.Value }) }`},
}
ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(proc.GoVersion{1, 8, -1, 0, 0, ""}) {
ver, _ := goversion.Parse(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(goversion.GoVersion{1, 8, -1, 0, 0, ""}) {
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[4].typ = `struct { main.i int; main.j int }`
......@@ -892,8 +893,8 @@ func TestPackageRenames(t *testing.T) {
{"iface2iface", true, `interface {}(*interface { AMethod(int) int; AnotherMethod(int) int }) **github.com/derekparker/delve/_fixtures/vendor/dir0/pkg.SomeType {X: 4}`, "", "interface {}", nil},
}
ver, _ := proc.ParseVersionString(runtime.Version())
if ver.Major > 0 && !ver.AfterOrEqual(proc.GoVersion{1, 7, -1, 0, 0, ""}) {
ver, _ := goversion.Parse(runtime.Version())
if ver.Major > 0 && !ver.AfterOrEqual(goversion.GoVersion{1, 7, -1, 0, 0, ""}) {
// Not supported on 1.6 or earlier
return
}
......@@ -902,7 +903,7 @@ func TestPackageRenames(t *testing.T) {
withTestProcess("pkgrenames", t, func(p proc.Process, fixture protest.Fixture) {
assertNoError(proc.Continue(p), t, "Continue() returned an error")
for _, tc := range testcases {
if ver.Major > 0 && !ver.AfterOrEqual(proc.GoVersion{1, 9, -1, 0, 0, ""}) {
if ver.Major > 0 && !ver.AfterOrEqual(goversion.GoVersion{1, 9, -1, 0, 0, ""}) {
// before 1.9 embedded struct field have fieldname == type
if tc.name == "astruct2" {
tc.value = `interface {}(*struct { github.com/derekparker/delve/_fixtures/vendor/dir1/pkg.SomeType; X int }) *{github.com/derekparker/delve/_fixtures/vendor/dir1/pkg.SomeType: github.com/derekparker/delve/_fixtures/vendor/dir1/pkg.SomeType {X: 1, Y: 2}, X: 10}`
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册