mirror of
https://github.com/go-delve/delve.git
synced 2025-10-30 02:07:58 +08:00
proc/test: miscellaneous test changes for go1.10
This commit is contained in:
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -177,7 +177,7 @@ func TestDwarfExprComposite(t *testing.T) {
|
|||||||
scope := dwarfExprCheck(t, mem, dwarfRegisters(®s), bi, testCases)
|
scope := dwarfExprCheck(t, mem, dwarfRegisters(®s), 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 {
|
||||||
|
|||||||
@ -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")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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")
|
||||||
|
|||||||
Reference in New Issue
Block a user