proc/test: miscellaneous test changes for go1.10

This commit is contained in:
aarzilli
2017-10-13 22:13:43 +02:00
committed by Derek Parker
parent 8b4392dc46
commit 07c716818e
6 changed files with 81 additions and 55 deletions

View File

@ -64,56 +64,59 @@ const (
func testDebugLinePrologueParser(p string, t *testing.T) { func testDebugLinePrologueParser(p string, t *testing.T) {
data := grabDebugLineSection(p, t) data := grabDebugLineSection(p, t)
debugLines := ParseAll(data) debugLines := ParseAll(data)
dbl := debugLines[0]
prologue := dbl.Prologue
if prologue.Version != uint16(2) { mainFileFound := false
t.Fatal("Version not parsed correctly", prologue.Version)
}
if prologue.MinInstrLength != uint8(1) { for _, dbl := range debugLines {
t.Fatal("Minimun Instruction Length not parsed correctly", prologue.MinInstrLength) prologue := dbl.Prologue
}
if prologue.InitialIsStmt != uint8(1) { if prologue.Version != uint16(2) {
t.Fatal("Initial value of 'is_stmt' not parsed correctly", prologue.InitialIsStmt) t.Fatal("Version not parsed correctly", prologue.Version)
} }
if prologue.LineBase != lineBaseGo14 && prologue.LineBase != lineBaseGo18 { if prologue.MinInstrLength != uint8(1) {
// go < 1.8 uses -1 t.Fatal("Minimun Instruction Length not parsed correctly", prologue.MinInstrLength)
// go >= 1.8 uses -4 }
t.Fatal("Line base not parsed correctly", prologue.LineBase)
}
if prologue.LineRange != lineRangeGo14 && prologue.LineRange != lineRangeGo18 { if prologue.InitialIsStmt != uint8(1) {
// go < 1.8 uses 4 t.Fatal("Initial value of 'is_stmt' not parsed correctly", prologue.InitialIsStmt)
// go >= 1.8 uses 10 }
t.Fatal("Line Range not parsed correctly", prologue.LineRange)
}
if prologue.OpcodeBase != uint8(10) { if prologue.LineBase != lineBaseGo14 && prologue.LineBase != lineBaseGo18 {
t.Fatal("Opcode Base not parsed correctly", prologue.OpcodeBase) // go < 1.8 uses -1
} // go >= 1.8 uses -4
t.Fatal("Line base not parsed correctly", prologue.LineBase)
}
lengths := []uint8{0, 1, 1, 1, 1, 0, 0, 0, 1} if prologue.LineRange != lineRangeGo14 && prologue.LineRange != lineRangeGo18 {
for i, l := range prologue.StdOpLengths { // go < 1.8 uses 4
if l != lengths[i] { // go >= 1.8 uses 10
t.Fatal("Length not parsed correctly", l) t.Fatal("Line Range not parsed correctly", prologue.LineRange)
}
if prologue.OpcodeBase != uint8(10) {
t.Fatal("Opcode Base not parsed correctly", prologue.OpcodeBase)
}
lengths := []uint8{0, 1, 1, 1, 1, 0, 0, 0, 1}
for i, l := range prologue.StdOpLengths {
if l != lengths[i] {
t.Fatal("Length not parsed correctly", l)
}
}
if len(dbl.IncludeDirs) != 0 {
t.Fatal("Include dirs not parsed correctly")
}
for _, n := range dbl.FileNames {
if strings.Contains(n.Path, "/delve/_fixtures/testnextprog.go") {
mainFileFound = true
break
}
} }
} }
if !mainFileFound {
if len(dbl.IncludeDirs) != 0 {
t.Fatal("Include dirs not parsed correctly")
}
ok := false
for _, n := range dbl.FileNames {
if strings.Contains(n.Path, "/delve/_fixtures/testnextprog.go") {
ok = true
break
}
}
if !ok {
t.Fatal("File names table not parsed correctly") t.Fatal("File names table not parsed correctly")
} }
} }

View File

@ -13,6 +13,7 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/derekparker/delve/pkg/goversion"
"github.com/derekparker/delve/pkg/proc" "github.com/derekparker/delve/pkg/proc"
"github.com/derekparker/delve/pkg/proc/test" "github.com/derekparker/delve/pkg/proc/test"
) )
@ -175,7 +176,7 @@ func TestCore(t *testing.T) {
t.Errorf("Stacktrace() on goroutine %v = %v", g, err) t.Errorf("Stacktrace() on goroutine %v = %v", g, err)
} }
for _, frame := range stack { for _, frame := range stack {
if strings.Contains(frame.Current.Fn.Name, "panic") { if frame.Current.Fn != nil && strings.Contains(frame.Current.Fn.Name, "panic") {
panicking = g panicking = g
panickingStack = stack panickingStack = stack
} }
@ -218,6 +219,12 @@ func TestCoreFpRegisters(t *testing.T) {
if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
return return
} }
// in go1.10 the crash is executed on a different thread and registers are
// no longer available in the core dump.
if ver, _ := goversion.Parse(runtime.Version()); ver.Major < 0 || ver.AfterOrEqual(goversion.GoVersion{1, 10, -1, 0, 0, ""}) {
t.Skip("not supported in go1.10 and later")
}
p := withCoreFile(t, "fputest/", "panic") p := withCoreFile(t, "fputest/", "panic")
gs, err := proc.GoroutinesInfo(p) gs, err := proc.GoroutinesInfo(p)

View File

@ -177,7 +177,7 @@ func TestDwarfExprComposite(t *testing.T) {
scope := dwarfExprCheck(t, mem, dwarfRegisters(&regs), bi, testCases) scope := dwarfExprCheck(t, mem, dwarfRegisters(&regs), bi, testCases)
thevar, err := scope.EvalExpression("s", normalLoadConfig) thevar, err := scope.EvalExpression("s", normalLoadConfig)
assertNoError(err, t, fmt.Sprintf("EvalExpression(s)", "s")) assertNoError(err, t, fmt.Sprintf("EvalExpression(%s)", "s"))
if thevar.Unreadable != nil { if thevar.Unreadable != nil {
t.Errorf("variable \"s\" unreadable: %v", thevar.Unreadable) t.Errorf("variable \"s\" unreadable: %v", thevar.Unreadable)
} else { } else {

View File

@ -1686,7 +1686,7 @@ func TestIssue384(t *testing.T) {
if ver.Major < 0 || ver.AfterOrEqual(goversion.GoVersion{1, 10, -1, 0, 0, ""}) { if ver.Major < 0 || ver.AfterOrEqual(goversion.GoVersion{1, 10, -1, 0, 0, ""}) {
// go 1.10 emits DW_AT_decl_line and we won't be able to evaluate 'st' // go 1.10 emits DW_AT_decl_line and we won't be able to evaluate 'st'
// which is declared after line 13. // which is declared after line 13.
return t.Skip("can not evaluate not-yet-declared variables with go 1.10")
} }
protest.AllowRecording(t) protest.AllowRecording(t)
@ -2140,7 +2140,7 @@ func TestStepReturnAndPanic(t *testing.T) {
// Tests that Step works correctly when returning from functions // Tests that Step works correctly when returning from functions
// and when a deferred function is called when panic'ing. // and when a deferred function is called when panic'ing.
ver, _ := goversion.Parse(runtime.Version()) ver, _ := goversion.Parse(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(goversion.GoVersion{1, 9, -1, 0, 0, ""}) { if ver.Major > 0 && ver.AfterOrEqual(goversion.GoVersion{1, 9, -1, 0, 0, ""}) && !ver.AfterOrEqual(goversion.GoVersion{1, 10, -1, 0, 0, ""}) {
testseq("defercall", contStep, []nextTest{ testseq("defercall", contStep, []nextTest{
{17, 5}, {17, 5},
{5, 6}, {5, 6},
@ -2184,7 +2184,7 @@ func TestStepIgnorePrivateRuntime(t *testing.T) {
// (such as runtime.convT2E in this case) // (such as runtime.convT2E in this case)
ver, _ := goversion.Parse(runtime.Version()) ver, _ := goversion.Parse(runtime.Version())
if ver.Major < 0 || ver.AfterOrEqual(goversion.GoVersion{1, 7, -1, 0, 0, ""}) { if ver.Major > 0 && ver.AfterOrEqual(goversion.GoVersion{1, 7, -1, 0, 0, ""}) && !ver.AfterOrEqual(goversion.GoVersion{1, 10, -1, 0, 0, ""}) {
testseq("teststepprog", contStep, []nextTest{ testseq("teststepprog", contStep, []nextTest{
{21, 13}, {21, 13},
{13, 14}, {13, 14},
@ -2192,6 +2192,12 @@ func TestStepIgnorePrivateRuntime(t *testing.T) {
{15, 14}, {15, 14},
{14, 17}, {14, 17},
{17, 22}}, "", t) {17, 22}}, "", t)
} else if ver.Major < 0 || ver.AfterOrEqual(goversion.GoVersion{1, 10, -1, 0, 0, ""}) {
testseq("teststepprog", contStep, []nextTest{
{21, 13},
{13, 14},
{14, 15},
{15, 22}}, "", t)
} else { } else {
testseq("teststepprog", contStep, []nextTest{ testseq("teststepprog", contStep, []nextTest{
{21, 13}, {21, 13},
@ -2933,7 +2939,7 @@ func TestIssue877(t *testing.T) {
func TestIssue893(t *testing.T) { func TestIssue893(t *testing.T) {
// Test what happens when next is called immediately after launching the // Test what happens when next is called immediately after launching the
// executable, acceptable behaviors are: (a) no error, (b) no source at PC // executable, acceptable behaviors are: (a) no error, (b) no source at PC
// error. // error, (c) program runs to completion
protest.AllowRecording(t) protest.AllowRecording(t)
withTestProcess("increment", t, func(p proc.Process, fixture protest.Fixture) { withTestProcess("increment", t, func(p proc.Process, fixture protest.Fixture) {
err := proc.Next(p) err := proc.Next(p)
@ -2949,6 +2955,9 @@ func TestIssue893(t *testing.T) {
if _, ok := err.(*proc.NoSourceForPCError); ok { if _, ok := err.(*proc.NoSourceForPCError); ok {
return return
} }
if _, ok := err.(proc.ProcessExitedError); ok {
return
}
assertNoError(err, t, "Next") assertNoError(err, t, "Next")
}) })
} }

View File

@ -182,11 +182,6 @@ func (it *stackIterator) Next() bool {
callFrameRegs, ret, retaddr := it.advanceRegs() callFrameRegs, ret, retaddr := it.advanceRegs()
it.frame = it.newStackframe(ret, retaddr) it.frame = it.newStackframe(ret, retaddr)
if it.frame.Ret <= 0 {
it.atend = true
return true
}
if it.stkbar != nil && it.frame.Ret == it.stackBarrierPC && it.frame.addrret == it.stkbar[0].ptr { if it.stkbar != nil && it.frame.Ret == it.stackBarrierPC && it.frame.addrret == it.stkbar[0].ptr {
// Skip stack barrier frames // Skip stack barrier frames
it.frame.Ret = it.stkbar[0].val it.frame.Ret = it.stkbar[0].val
@ -197,6 +192,11 @@ func (it *stackIterator) Next() bool {
return true return true
} }
if it.frame.Ret <= 0 {
it.atend = true
return true
}
it.top = false it.top = false
it.pc = it.frame.Ret it.pc = it.frame.Ret
it.regs = callFrameRegs it.regs = callFrameRegs
@ -221,7 +221,10 @@ func (it *stackIterator) switchStack() bool {
return false return false
} }
// switch from system stack to goroutine stack // This function is called by a goroutine to execute a C function and
// switches from the goroutine stack to the system stack.
// Since we are unwinding the stack from callee to caller we have switch
// from the system stack to the goroutine stack.
off, _ := readIntRaw(it.mem, uintptr(it.regs.SP()+asmcgocallSPOffsetSaveSlot), int64(it.bi.Arch.PtrSize())) // reads "offset of SP from StackHi" from where runtime.asmcgocall saved it off, _ := readIntRaw(it.mem, uintptr(it.regs.SP()+asmcgocallSPOffsetSaveSlot), int64(it.bi.Arch.PtrSize())) // reads "offset of SP from StackHi" from where runtime.asmcgocall saved it
oldsp := it.regs.SP() oldsp := it.regs.SP()
@ -242,7 +245,7 @@ func (it *stackIterator) switchStack() bool {
it.top = false it.top = false
return true return true
case "runtime.mstart": case "runtime.mstart", "runtime.sigtramp":
if it.top || !it.systemstack || it.g == nil { if it.top || !it.systemstack || it.g == nil {
return false return false
} }
@ -255,6 +258,10 @@ func (it *stackIterator) switchStack() bool {
// If we find a runtime.mstart frame on the system stack of a goroutine // If we find a runtime.mstart frame on the system stack of a goroutine
// parked on runtime.systemstack_switch we assume runtime.systemstack was // parked on runtime.systemstack_switch we assume runtime.systemstack was
// called and continue tracing from the parked position. // called and continue tracing from the parked position.
//
// OS Signals are processed on a special signal handling stack that works
// similarly to the system stack, runtime.sigtramp is at the bottom of
// this stack.
if fn := it.bi.PCToFunc(it.g.PC); fn == nil || fn.Name != "runtime.systemstack_switch" { if fn := it.bi.PCToFunc(it.g.PC); fn == nil || fn.Name != "runtime.systemstack_switch" {
return false return false

View File

@ -965,7 +965,7 @@ func TestConstants(t *testing.T) {
ver, _ := goversion.Parse(runtime.Version()) ver, _ := goversion.Parse(runtime.Version())
if ver.Major > 0 && !ver.AfterOrEqual(goversion.GoVersion{1, 10, -1, 0, 0, ""}) { if ver.Major > 0 && !ver.AfterOrEqual(goversion.GoVersion{1, 10, -1, 0, 0, ""}) {
// Not supported on 1.9 or earlier // Not supported on 1.9 or earlier
return t.Skip("constants added in go 1.10")
} }
withTestProcess("consts", t, func(p proc.Process, fixture protest.Fixture) { withTestProcess("consts", t, func(p proc.Process, fixture protest.Fixture) {
assertNoError(proc.Continue(p), t, "Continue") assertNoError(proc.Continue(p), t, "Continue")