From 55eed318fdccdc902ea4975e1d7d174c9a11d55c Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Sun, 30 Jun 2019 19:34:47 +0200 Subject: [PATCH] Go 1.13 support (#1546) * tests: fix tests for Go 1.13 - Go 1.13 doesn't autogenerate init functions anymore, tests that expected that now fail and should be skipped. - Plugin tests now need -gcflags'all=-N -l' now, we were probably getting lucky with -gcflags='-N -l' before. * proc: allow signed integers as shift counts Go1.13 allows signed integers to be used as the right hand side of a shift operator, change eval to match. * goversion: update maximum supported version * travis: force Go to use vendor directory Travis scripts get confused by "go: downloading" lines, the exact reason is not clear. Testing that the vendor directory is up to date is a good idea anyway. --- .travis.yml | 1 + pkg/goversion/compat.go | 2 +- pkg/proc/eval.go | 4 ++-- pkg/proc/proc_test.go | 13 +++++++++---- pkg/proc/test/support.go | 12 +++++++++--- pkg/terminal/command_test.go | 7 +++++++ service/test/variables_test.go | 7 +++---- 7 files changed, 32 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 889859d8..dde50897 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,4 +16,5 @@ matrix: - go: tip before_install: + - export GOFLAGS=-mod=vendor - if [ $TRAVIS_OS_NAME = "linux" ]; then sudo apt-get -qq update; sudo apt-get install -y dwz; fi diff --git a/pkg/goversion/compat.go b/pkg/goversion/compat.go index b0b034c9..23e41014 100644 --- a/pkg/goversion/compat.go +++ b/pkg/goversion/compat.go @@ -6,7 +6,7 @@ import ( var ( minSupportedVersionOfGoMinor = 10 - maxSupportedVersionOfGoMinor = 12 + maxSupportedVersionOfGoMinor = 13 goTooOldErr = fmt.Errorf("Version of Go is too old for this version of Delve (minimum supported version 1.%d, suppress this error with --check-go-version=false)", minSupportedVersionOfGoMinor) dlvTooOldErr = fmt.Errorf("Version of Delve is too old for this version of Go (maximum supported version 1.%d, suppress this error with --check-go-version=false)", maxSupportedVersionOfGoMinor) ) diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go index f0fd0489..b016d361 100644 --- a/pkg/proc/eval.go +++ b/pkg/proc/eval.go @@ -927,8 +927,8 @@ func negotiateType(op token.Token, xv, yv *Variable) (godwarf.Type, error) { case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: // ok case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - if yv.DwarfType != nil || constant.Sign(yv.Value) < 0 { - return nil, fmt.Errorf("shift count type %s, must be unsigned integer", yv.Kind.String()) + if constant.Sign(yv.Value) < 0 { + return nil, fmt.Errorf("shift count must not be negative") } default: return nil, fmt.Errorf("shift count type %s, must be unsigned integer", yv.Kind.String()) diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 8934dfbd..0789ea81 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -1810,6 +1810,11 @@ func TestIssue332_Part2(t *testing.T) { } func TestIssue396(t *testing.T) { + if goversion.VersionAfterOrEqual(runtime.Version(), 1, 13) { + // CL 161337 in Go 1.13 and later removes the autogenerated init function + // https://go-review.googlesource.com/c/go/+/161337 + t.Skip("no autogenerated init function in Go 1.13 or later") + } withTestProcess("callme", t, func(p proc.Process, fixture protest.Fixture) { _, err := proc.FindFunctionLocation(p, "main.init", 0) assertNoError(err, t, "FindFunctionLocation()") @@ -4247,9 +4252,9 @@ func TestDeadlockBreakpoint(t *testing.T) { } func TestListImages(t *testing.T) { - pluginFixtures := protest.WithPlugins(t, "plugin1/", "plugin2/") + pluginFixtures := protest.WithPlugins(t, protest.AllNonOptimized, "plugin1/", "plugin2/") - withTestProcessArgs("plugintest", t, ".", []string{pluginFixtures[0].Path, pluginFixtures[1].Path}, 0, func(p proc.Process, fixture protest.Fixture) { + withTestProcessArgs("plugintest", t, ".", []string{pluginFixtures[0].Path, pluginFixtures[1].Path}, protest.AllNonOptimized, func(p proc.Process, fixture protest.Fixture) { assertNoError(proc.Continue(p), t, "first continue") f, l := currentLineNumber(p, t) plugin1Found := false @@ -4367,9 +4372,9 @@ func TestCallConcurrent(t *testing.T) { } func TestPluginStepping(t *testing.T) { - pluginFixtures := protest.WithPlugins(t, "plugin1/", "plugin2/") + pluginFixtures := protest.WithPlugins(t, protest.AllNonOptimized, "plugin1/", "plugin2/") - testseq2Args(".", []string{pluginFixtures[0].Path, pluginFixtures[1].Path}, 0, t, "plugintest2", "", []seqTest{ + testseq2Args(".", []string{pluginFixtures[0].Path, pluginFixtures[1].Path}, protest.AllNonOptimized, t, "plugintest2", "", []seqTest{ {contContinue, 41}, {contStep, "plugin1.go:9"}, {contStep, "plugin1.go:10"}, diff --git a/pkg/proc/test/support.go b/pkg/proc/test/support.go index 0f814ae7..ca7dd923 100644 --- a/pkg/proc/test/support.go +++ b/pkg/proc/test/support.go @@ -75,6 +75,7 @@ const ( EnableDWZCompression BuildModePIE BuildModePlugin + AllNonOptimized ) // BuildFixture will compile the fixture 'name' using the provided build flags. @@ -121,7 +122,12 @@ func BuildFixture(name string, flags BuildFlags) Fixture { if flags&EnableOptimization == 0 { gcflagsv = append(gcflagsv, "-N") } - gcflags := "-gcflags=" + strings.Join(gcflagsv, " ") + var gcflags string + if flags&AllNonOptimized != 0 { + gcflags = "-gcflags=all=" + strings.Join(gcflagsv, " ") + } else { + gcflags = "-gcflags=" + strings.Join(gcflagsv, " ") + } buildFlags = append(buildFlags, gcflags, "-o", tmpfile) if *EnableRace { buildFlags = append(buildFlags, "-race") @@ -325,7 +331,7 @@ func DefaultTestBackend(testBackend *string) { // The test calling WithPlugins will be skipped if the current combination // of OS, architecture and version of GO doesn't support plugins or // debugging plugins. -func WithPlugins(t *testing.T, plugins ...string) []Fixture { +func WithPlugins(t *testing.T, flags BuildFlags, plugins ...string) []Fixture { if !goversion.VersionAfterOrEqual(runtime.Version(), 1, 12) { t.Skip("versions of Go before 1.12 do not include debug information in packages that import plugin (or they do but it's wrong)") } @@ -335,7 +341,7 @@ func WithPlugins(t *testing.T, plugins ...string) []Fixture { r := make([]Fixture, len(plugins)) for i := range plugins { - r[i] = BuildFixture(plugins[i], BuildModePlugin) + r[i] = BuildFixture(plugins[i], flags|BuildModePlugin) } return r } diff --git a/pkg/terminal/command_test.go b/pkg/terminal/command_test.go index e6ffbf6f..23e79169 100644 --- a/pkg/terminal/command_test.go +++ b/pkg/terminal/command_test.go @@ -733,6 +733,13 @@ func TestConfig(t *testing.T) { func TestDisassembleAutogenerated(t *testing.T) { // Executing the 'disassemble' command on autogenerated code should work correctly + + if goversion.VersionAfterOrEqual(runtime.Version(), 1, 13) { + // CL 161337 in Go 1.13 and later removes the autogenerated init function + // https://go-review.googlesource.com/c/go/+/161337 + t.Skip("no autogenerated init function in Go 1.13 or later") + } + withTestTerminal("math", t, func(term *FakeTerminal) { term.MustExec("break main.init") term.MustExec("continue") diff --git a/service/test/variables_test.go b/service/test/variables_test.go index b2baad17..bb22cb3b 100644 --- a/service/test/variables_test.go +++ b/service/test/variables_test.go @@ -733,8 +733,7 @@ func TestEvalExpression(t *testing.T) { {"i2 + p1", false, "", "", "", fmt.Errorf("mismatched types \"int\" and \"*int\"")}, {"i2 + f1", false, "", "", "", fmt.Errorf("mismatched types \"int\" and \"float64\"")}, {"i2 << f1", false, "", "", "", fmt.Errorf("shift count type float64, must be unsigned integer")}, - {"i2 << -1", false, "", "", "", fmt.Errorf("shift count type int, must be unsigned integer")}, - {"i2 << i3", false, "", "", "int", fmt.Errorf("shift count type int, must be unsigned integer")}, + {"i2 << -1", false, "", "", "", fmt.Errorf("shift count must not be negative")}, {"*(i2 + i3)", false, "", "", "", fmt.Errorf("expression \"(i2 + i3)\" (int) can not be dereferenced")}, {"i2.member", false, "", "", "", fmt.Errorf("i2 (type int) is not a struct")}, {"fmt.Println(\"hello\")", false, "", "", "", fmt.Errorf("function calls not allowed without using 'call'")}, @@ -1356,9 +1355,9 @@ func assertCurrentLocationFunction(p proc.Process, t *testing.T, fnname string) } func TestPluginVariables(t *testing.T) { - pluginFixtures := protest.WithPlugins(t, "plugin1/", "plugin2/") + pluginFixtures := protest.WithPlugins(t, protest.AllNonOptimized, "plugin1/", "plugin2/") - withTestProcessArgs("plugintest2", t, ".", []string{pluginFixtures[0].Path, pluginFixtures[1].Path}, 0, func(p proc.Process, fixture protest.Fixture) { + withTestProcessArgs("plugintest2", t, ".", []string{pluginFixtures[0].Path, pluginFixtures[1].Path}, protest.AllNonOptimized, func(p proc.Process, fixture protest.Fixture) { setFileLineBreakpoint(p, t, fixture.Source, 41) assertNoError(proc.Continue(p), t, "Continue 1")