diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 3419bcdf..586b9add 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -69,18 +69,6 @@ "ImportPath": "github.com/spf13/pflag", "Rev": "b084184666e02084b8ccb9b704bf0d79c466eb1d" }, - { - "ImportPath": "golang.org/x/debug/dwarf", - "Rev": "450bc3a73495e77763c92c336e3bc040b3f34c14" - }, - { - "ImportPath": "golang.org/x/debug/elf", - "Rev": "450bc3a73495e77763c92c336e3bc040b3f34c14" - }, - { - "ImportPath": "golang.org/x/debug/macho", - "Rev": "450bc3a73495e77763c92c336e3bc040b3f34c14" - }, { "ImportPath": "golang.org/x/sys/unix", "Rev": "eb2c74142fd19a79b3f237334c7384d5167b1b46" diff --git a/_fixtures/locationsprog.go b/_fixtures/locationsprog.go index 7aca93fc..8cfd9b7f 100644 --- a/_fixtures/locationsprog.go +++ b/_fixtures/locationsprog.go @@ -30,7 +30,8 @@ func anotherFunction() { func main() { var a SomeType var b OtherType - fmt.Printf("%s %s\n", a.String(), b.String()) + i := 10 + fmt.Printf("%s %s %v\n", a.String(), b.String(), i) a.SomeFunction() anotherFunction() ioutil.ReadFile("nonexistent.file.txt") diff --git a/_fixtures/math.go b/_fixtures/math.go index 3c2f94ac..65c4b01e 100644 --- a/_fixtures/math.go +++ b/_fixtures/math.go @@ -5,6 +5,8 @@ import "math" var f = 1.5 func main() { - _ = math.Floor(f) - _ = float64(int(f)) + floatvar1 := math.Floor(f) + floatvar2 := float64(int(f)) + _ = floatvar1 + _ = floatvar2 } diff --git a/vendor/golang.org/x/debug/LICENSE b/dwarf/debug/LICENSE similarity index 100% rename from vendor/golang.org/x/debug/LICENSE rename to dwarf/debug/LICENSE diff --git a/vendor/golang.org/x/debug/dwarf/buf.go b/dwarf/debug/dwarf/buf.go similarity index 100% rename from vendor/golang.org/x/debug/dwarf/buf.go rename to dwarf/debug/dwarf/buf.go diff --git a/vendor/golang.org/x/debug/dwarf/const.go b/dwarf/debug/dwarf/const.go similarity index 100% rename from vendor/golang.org/x/debug/dwarf/const.go rename to dwarf/debug/dwarf/const.go diff --git a/vendor/golang.org/x/debug/dwarf/entry.go b/dwarf/debug/dwarf/entry.go similarity index 100% rename from vendor/golang.org/x/debug/dwarf/entry.go rename to dwarf/debug/dwarf/entry.go diff --git a/vendor/golang.org/x/debug/dwarf/frame.go b/dwarf/debug/dwarf/frame.go similarity index 100% rename from vendor/golang.org/x/debug/dwarf/frame.go rename to dwarf/debug/dwarf/frame.go diff --git a/vendor/golang.org/x/debug/dwarf/line.go b/dwarf/debug/dwarf/line.go similarity index 100% rename from vendor/golang.org/x/debug/dwarf/line.go rename to dwarf/debug/dwarf/line.go diff --git a/vendor/golang.org/x/debug/dwarf/open.go b/dwarf/debug/dwarf/open.go similarity index 100% rename from vendor/golang.org/x/debug/dwarf/open.go rename to dwarf/debug/dwarf/open.go diff --git a/vendor/golang.org/x/debug/dwarf/symbol.go b/dwarf/debug/dwarf/symbol.go similarity index 100% rename from vendor/golang.org/x/debug/dwarf/symbol.go rename to dwarf/debug/dwarf/symbol.go diff --git a/vendor/golang.org/x/debug/dwarf/type.go b/dwarf/debug/dwarf/type.go similarity index 98% rename from vendor/golang.org/x/debug/dwarf/type.go rename to dwarf/debug/dwarf/type.go index a2471b65..8cf4ac84 100644 --- a/vendor/golang.org/x/debug/dwarf/type.go +++ b/dwarf/debug/dwarf/type.go @@ -138,7 +138,12 @@ type PtrType struct { Type Type } -func (t *PtrType) String() string { return "*" + t.Type.String() } +func (t *PtrType) String() string { + if t.Name != "" { + return t.Name + } + return "*" + t.Type.String() +} // A StructType represents a struct, union, or C++ class type. type StructType struct { @@ -160,6 +165,9 @@ type StructField struct { } func (t *StructType) String() string { + if t.Name != "" { + return t.Name + } if t.StructName != "" { return t.Kind + " " + t.StructName } @@ -591,6 +599,7 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off case TagUnionType: t.Kind = "union" } + t.Name, _ = e.Val(AttrName).(string) t.StructName, _ = e.Val(AttrName).(string) t.Incomplete = e.Val(AttrDeclaration) != nil t.Field = make([]*StructField, 0, 8) @@ -705,6 +714,7 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off // AttrType: subtype [not required! void* has no AttrType] // AttrAddrClass: address class [ignored] t := new(PtrType) + t.Name, _ = e.Val(AttrName).(string) t.ReflectKind = getKind(e) typ = t typeCache[off] = t diff --git a/vendor/golang.org/x/debug/dwarf/typeunit.go b/dwarf/debug/dwarf/typeunit.go similarity index 100% rename from vendor/golang.org/x/debug/dwarf/typeunit.go rename to dwarf/debug/dwarf/typeunit.go diff --git a/vendor/golang.org/x/debug/dwarf/unit.go b/dwarf/debug/dwarf/unit.go similarity index 100% rename from vendor/golang.org/x/debug/dwarf/unit.go rename to dwarf/debug/dwarf/unit.go diff --git a/vendor/golang.org/x/debug/elf/elf.go b/dwarf/debug/elf/elf.go similarity index 100% rename from vendor/golang.org/x/debug/elf/elf.go rename to dwarf/debug/elf/elf.go diff --git a/vendor/golang.org/x/debug/elf/file.go b/dwarf/debug/elf/file.go similarity index 99% rename from vendor/golang.org/x/debug/elf/file.go rename to dwarf/debug/elf/file.go index 69465505..da469f94 100644 --- a/vendor/golang.org/x/debug/elf/file.go +++ b/dwarf/debug/elf/file.go @@ -13,7 +13,7 @@ import ( "io" "os" - "golang.org/x/debug/dwarf" + "github.com/derekparker/delve/dwarf/debug/dwarf" ) // TODO: error reporting detail diff --git a/vendor/golang.org/x/debug/macho/fat.go b/dwarf/debug/macho/fat.go similarity index 100% rename from vendor/golang.org/x/debug/macho/fat.go rename to dwarf/debug/macho/fat.go diff --git a/vendor/golang.org/x/debug/macho/file.go b/dwarf/debug/macho/file.go similarity index 99% rename from vendor/golang.org/x/debug/macho/file.go rename to dwarf/debug/macho/file.go index 7f59901a..ecb8247f 100644 --- a/vendor/golang.org/x/debug/macho/file.go +++ b/dwarf/debug/macho/file.go @@ -14,7 +14,7 @@ import ( "io" "os" - "golang.org/x/debug/dwarf" + "github.com/derekparker/delve/dwarf/debug/dwarf" ) // A File represents an open Mach-O file. diff --git a/vendor/golang.org/x/debug/macho/macho.go b/dwarf/debug/macho/macho.go similarity index 100% rename from vendor/golang.org/x/debug/macho/macho.go rename to dwarf/debug/macho/macho.go diff --git a/dwarf/reader/reader.go b/dwarf/reader/reader.go index 252d1a87..a45a4d83 100755 --- a/dwarf/reader/reader.go +++ b/dwarf/reader/reader.go @@ -3,8 +3,8 @@ package reader import ( "errors" "fmt" - "golang.org/x/debug/dwarf" + "github.com/derekparker/delve/dwarf/debug/dwarf" "github.com/derekparker/delve/dwarf/op" ) diff --git a/proc/breakpoints.go b/proc/breakpoints.go index 1b55e306..7a28ec28 100644 --- a/proc/breakpoints.go +++ b/proc/breakpoints.go @@ -24,10 +24,10 @@ type Breakpoint struct { Temp bool // Whether this is a temp breakpoint (for next'ing). // Breakpoint information - Tracepoint bool // Tracepoint flag - Goroutine bool // Retrieve goroutine information - Stacktrace int // Number of stack frames to retrieve - Variables []string // Variables to evaluate + Tracepoint bool // Tracepoint flag + Goroutine bool // Retrieve goroutine information + Stacktrace int // Number of stack frames to retrieve + Variables []string // Variables to evaluate LoadArgs *LoadConfig LoadLocals *LoadConfig HitCount map[int]uint64 // Number of times a breakpoint has been reached in a certain goroutine diff --git a/proc/eval.go b/proc/eval.go index 7f979400..4c943dfb 100644 --- a/proc/eval.go +++ b/proc/eval.go @@ -11,8 +11,8 @@ import ( "go/token" "reflect" + "github.com/derekparker/delve/dwarf/debug/dwarf" "github.com/derekparker/delve/dwarf/reader" - "golang.org/x/debug/dwarf" ) // EvalExpression returns the value of the given expression. diff --git a/proc/moduledata.go b/proc/moduledata.go new file mode 100644 index 00000000..6579bf69 --- /dev/null +++ b/proc/moduledata.go @@ -0,0 +1,87 @@ +package proc + +import ( + "go/constant" +) + +// delve counterpart to runtime.moduledata +type moduleData struct { + types, etypes uintptr +} + +func (dbp *Process) loadModuleData() (err error) { + dbp.loadModuleDataOnce.Do(func() { + scope := &EvalScope{Thread: dbp.CurrentThread, PC: 0, CFA: 0} + var md *Variable + md, err = scope.packageVarAddr("runtime.firstmoduledata") + if err != nil { + return + } + + for md.Addr != 0 { + var typesVar, etypesVar, nextVar *Variable + var types, etypes uint64 + + if typesVar, err = md.structMember("types"); err != nil { + return + } + if etypesVar, err = md.structMember("etypes"); err != nil { + return + } + if nextVar, err = md.structMember("next"); err != nil { + return + } + if types, err = typesVar.asUint(); err != nil { + return + } + if etypes, err = etypesVar.asUint(); err != nil { + return + } + + dbp.moduleData = append(dbp.moduleData, moduleData{uintptr(types), uintptr(etypes)}) + + md = nextVar.maybeDereference() + if md.Unreadable != nil { + err = md.Unreadable + return + } + } + }) + + return +} + +func (dbp *Process) resolveNameOff(typeAddr uintptr, off uintptr) (uintptr, error) { + // See runtime.resolveNameOff in $GOROOT/src/runtime/type.go + if err := dbp.loadModuleData(); err != nil { + return 0, err + } + for _, md := range dbp.moduleData { + if typeAddr >= md.types && typeAddr < md.etypes { + return md.types + off, nil + } + } + + scope := &EvalScope{Thread: dbp.CurrentThread, PC: 0, CFA: 0} + reflectOffs, err := scope.packageVarAddr("runtime.reflectOffs") + if err != nil { + return 0, err + } + + reflectOffsm, err := reflectOffs.structMember("m") + if err != nil { + return 0, err + } + + v, err := reflectOffsm.mapAccess(newConstant(constant.MakeUint64(uint64(off)), dbp.CurrentThread)) + if err != nil { + return 0, err + } + + resv := v.maybeDereference() + if resv.Unreadable != nil { + return 0, resv.Unreadable + } + + return resv.Addr, nil +} diff --git a/proc/proc.go b/proc/proc.go index c6f113bf..36d9029f 100644 --- a/proc/proc.go +++ b/proc/proc.go @@ -14,8 +14,7 @@ import ( "strings" "sync" - "golang.org/x/debug/dwarf" - + "github.com/derekparker/delve/dwarf/debug/dwarf" "github.com/derekparker/delve/dwarf/frame" "github.com/derekparker/delve/dwarf/line" "github.com/derekparker/delve/dwarf/reader" @@ -59,6 +58,9 @@ type Process struct { ptraceChan chan func() ptraceDoneChan chan interface{} types map[string]dwarf.Offset + + loadModuleDataOnce sync.Once + moduleData []moduleData } // New returns an initialized Process struct. Before returning, diff --git a/proc/proc_darwin.go b/proc/proc_darwin.go index e1eb8a42..a6e6bc05 100644 --- a/proc/proc_darwin.go +++ b/proc/proc_darwin.go @@ -15,7 +15,7 @@ import ( "sync" "unsafe" - "golang.org/x/debug/macho" + "github.com/derekparker/delve/dwarf/debug/macho" "github.com/derekparker/delve/dwarf/frame" "github.com/derekparker/delve/dwarf/line" diff --git a/proc/proc_linux.go b/proc/proc_linux.go index ace43d87..0297d132 100644 --- a/proc/proc_linux.go +++ b/proc/proc_linux.go @@ -14,10 +14,9 @@ import ( "syscall" "time" - "golang.org/x/debug/elf" - sys "golang.org/x/sys/unix" + "github.com/derekparker/delve/dwarf/debug/elf" "github.com/derekparker/delve/dwarf/frame" "github.com/derekparker/delve/dwarf/line" ) diff --git a/proc/proc_windows.go b/proc/proc_windows.go index 41d194b5..07fcbf95 100644 --- a/proc/proc_windows.go +++ b/proc/proc_windows.go @@ -13,10 +13,9 @@ import ( "syscall" "unsafe" - "golang.org/x/debug/dwarf" - sys "golang.org/x/sys/windows" + "github.com/derekparker/delve/dwarf/debug/dwarf" "github.com/derekparker/delve/dwarf/frame" "github.com/derekparker/delve/dwarf/line" ) diff --git a/proc/stack.go b/proc/stack.go index 0971e172..39486a79 100644 --- a/proc/stack.go +++ b/proc/stack.go @@ -118,7 +118,7 @@ func (it *stackIterator) Next() bool { it.frame, it.err = it.dbp.frameInfo(it.pc, it.sp, it.top) if it.err != nil { if _, nofde := it.err.(*frame.NoFDEForPCError); nofde && !it.top { - it.frame = Stackframe{ Current: Location{ PC: it.pc, File: "?", Line: -1 }, Call: Location{ PC: it.pc, File: "?", Line: -1 }, CFA: 0, Ret: 0 } + it.frame = Stackframe{Current: Location{PC: it.pc, File: "?", Line: -1}, Call: Location{PC: it.pc, File: "?", Line: -1}, CFA: 0, Ret: 0} it.atend = true it.err = nil return true diff --git a/proc/threads.go b/proc/threads.go index 0f640e5e..9debb23b 100644 --- a/proc/threads.go +++ b/proc/threads.go @@ -9,8 +9,7 @@ import ( "reflect" "runtime" - "golang.org/x/debug/dwarf" - + "github.com/derekparker/delve/dwarf/debug/dwarf" "github.com/derekparker/delve/dwarf/frame" ) diff --git a/proc/types.go b/proc/types.go index 75fbe9b6..1432aaa7 100644 --- a/proc/types.go +++ b/proc/types.go @@ -4,11 +4,12 @@ import ( "github.com/derekparker/delve/dwarf/reader" "go/ast" "go/token" - "golang.org/x/debug/dwarf" "reflect" "strconv" "strings" "sync" + + "github.com/derekparker/delve/dwarf/debug/dwarf" ) // Do not call this function directly it isn't able to deal correctly with package paths diff --git a/proc/variables.go b/proc/variables.go index 768254e5..03483fdc 100644 --- a/proc/variables.go +++ b/proc/variables.go @@ -12,8 +12,7 @@ import ( "strings" "unsafe" - "golang.org/x/debug/dwarf" - + "github.com/derekparker/delve/dwarf/debug/dwarf" "github.com/derekparker/delve/dwarf/op" "github.com/derekparker/delve/dwarf/reader" ) @@ -368,7 +367,7 @@ func (gvar *Variable) parseG() (*G, error) { if thread, ok := mem.(*Thread); ok { id = thread.ID } - return nil, NoGError{ tid: id } + return nil, NoGError{tid: id} } gvar.loadValue(loadFullValue) if gvar.Unreadable != nil { @@ -627,10 +626,10 @@ func (v *Variable) structMember(memberName string) (*Variable, error) { // not a regular struct member for _, field := range t.Field { isEmbeddedStructMember := - (field.Type.String() == ("struct " + field.Name)) || + (field.Type.String() == field.Name) || (len(field.Name) > 1 && field.Name[0] == '*' && - field.Type.String()[1:] == ("struct "+field.Name[1:])) + field.Type.String()[1:] == field.Name[1:]) if !isEmbeddedStructMember { continue } @@ -1394,9 +1393,38 @@ func mapEvacuated(b *Variable) bool { } func (v *Variable) loadInterface(recurseLevel int, loadData bool, cfg LoadConfig) { - var typestring, data *Variable + var _type, str, typestring, data *Variable + var typename string + var err error isnil := false + // An interface variable is implemented either by a runtime.iface + // struct or a runtime.eface struct. The difference being that empty + // interfaces (i.e. "interface {}") are represented by runtime.eface + // and non-empty interfaces by runtime.iface. + // + // For both runtime.ifaces and runtime.efaces the data is stored in v.data + // + // The concrete type however is stored in v.tab._type for non-empty + // interfaces and in v._type for empty interfaces. + // + // For nil empty interface variables _type will be nil, for nil + // non-empty interface variables tab will be nil + // + // In either case the _type field is a pointer to a runtime._type struct. + // + // Before go1.7 _type used to have a field named 'string' containing + // the name of the type. Since go1.7 the field has been replaced by a + // str field that contains an offset in the module data, the concrete + // type must be calculated using the str address along with the value + // of v.tab._type (v._type for empty interfaces). + // + // The following code works for both runtime.iface and runtime.eface + // and sets the go17 flag when the 'string' field can not be found + // but the str field was found + + go17 := false + v.mem = cacheMemory(v.mem, v.Addr, int(v.RealType.Size())) ityp := resolveTypedef(&v.RealType.(*dwarf.InterfaceType).TypedefType).(*dwarf.StructType) @@ -1405,33 +1433,42 @@ func (v *Variable) loadInterface(recurseLevel int, loadData bool, cfg LoadConfig switch f.Name { case "tab": // for runtime.iface tab, _ := v.toField(f) - _type, err := tab.structMember("_type") - if err != nil { - _, isnil = err.(*IsNilErr) - if !isnil { - v.Unreadable = fmt.Errorf("invalid interface type: %v", err) - return - } - } else { - typestring, err = _type.structMember("_string") + tab = tab.maybeDereference() + isnil = tab.Addr == 0 + if !isnil { + _type, err = tab.structMember("_type") if err != nil { v.Unreadable = fmt.Errorf("invalid interface type: %v", err) return } - typestring = typestring.maybeDereference() + typestring, err = _type.structMember("_string") + if err == nil { + typestring = typestring.maybeDereference() + } else { + go17 = true + str, err = _type.structMember("str") + if err != nil { + v.Unreadable = fmt.Errorf("invalid interface type: %v", err) + return + } + } } case "_type": // for runtime.eface - var err error - _type, _ := v.toField(f) - typestring, err = _type.structMember("_string") - if err != nil { - _, isnil = err.(*IsNilErr) - if !isnil { - v.Unreadable = fmt.Errorf("invalid interface type: %v", err) - return + _type, _ = v.toField(f) + _type = _type.maybeDereference() + isnil = _type.Addr == 0 + if !isnil { + typestring, err = _type.structMember("_string") + if err == nil { + typestring = typestring.maybeDereference() + } else { + go17 = true + str, err = _type.structMember("str") + if err != nil { + v.Unreadable = fmt.Errorf("invalid interface type: %v", err) + return + } } - } else { - typestring = typestring.maybeDereference() } case "data": data, _ = v.toField(f) @@ -1448,17 +1485,56 @@ func (v *Variable) loadInterface(recurseLevel int, loadData bool, cfg LoadConfig return } - if typestring == nil || data == nil || typestring.Addr == 0 || typestring.Kind != reflect.String { + if data == nil { v.Unreadable = fmt.Errorf("invalid interface type") return } - typestring.loadValue(LoadConfig{false, 0, 512, 0, 0}) - if typestring.Unreadable != nil { - v.Unreadable = fmt.Errorf("invalid interface type: %v", typestring.Unreadable) - return + + if go17 { + // No 'string' field use 'str' and 'runtime.firstmoduledata' to + // find out what the concrete type is + + typeAddr := _type.maybeDereference().Addr + strOff, err := str.asInt() + if err != nil { + v.Unreadable = fmt.Errorf("invalid interface type: %v", err) + return + } + + res, err := v.dbp.resolveNameOff(typeAddr, uintptr(strOff)) + if err != nil { + v.Unreadable = fmt.Errorf("could not resolve concrete type (data: %#x): %v", data.Addr, err) + return + } + + // For a description of how memory is organized for type names read + // the comment to 'type name struct' in $GOROOT/src/reflect/type.go + + typdata, err := v.dbp.CurrentThread.readMemory(res, 3+v.dbp.arch.PtrSize()) + if err != nil { + v.Unreadable = fmt.Errorf("could not read concrete type (data: %#v): %v", data.Addr, err) + } + + nl := int(typdata[1]<<8 | typdata[2]) + + rawstr, err := v.dbp.CurrentThread.readMemory(res+3, nl) + + typename = string(rawstr) + } else { + if typestring == nil || typestring.Addr == 0 || typestring.Kind != reflect.String { + v.Unreadable = fmt.Errorf("invalid interface type") + return + } + typestring.loadValue(LoadConfig{false, 0, 512, 0, 0}) + if typestring.Unreadable != nil { + v.Unreadable = fmt.Errorf("invalid interface type: %v", typestring.Unreadable) + return + } + + typename = constant.StringVal(typestring.Value) } - t, err := parser.ParseExpr(constant.StringVal(typestring.Value)) + t, err := parser.ParseExpr(typename) if err != nil { v.Unreadable = fmt.Errorf("invalid interface type, unparsable data type: %v", err) return @@ -1466,7 +1542,7 @@ func (v *Variable) loadInterface(recurseLevel int, loadData bool, cfg LoadConfig typ, err := v.dbp.findTypeExpr(t) if err != nil { - v.Unreadable = fmt.Errorf("interface type \"%s\" not found for 0x%x: %v", constant.StringVal(typestring.Value), data.Addr, err) + v.Unreadable = fmt.Errorf("interface type \"%s\" not found for 0x%x: %v", typename, data.Addr, err) return } diff --git a/service/api/conversions.go b/service/api/conversions.go index bf44f4ef..fb19650d 100644 --- a/service/api/conversions.go +++ b/service/api/conversions.go @@ -6,10 +6,10 @@ import ( "go/constant" "go/printer" "go/token" - "golang.org/x/debug/dwarf" "reflect" "strconv" + "github.com/derekparker/delve/dwarf/debug/dwarf" "github.com/derekparker/delve/proc" ) diff --git a/service/test/integration1_test.go b/service/test/integration1_test.go index 27bea994..7894bc0a 100644 --- a/service/test/integration1_test.go +++ b/service/test/integration1_test.go @@ -581,18 +581,18 @@ func Test1ClientServer_FindLocations(t *testing.T) { t.Fatalf("Wrong locations returned for \"/.*Type.*String/\", got: %v expected: %v and %v\n", stringAddrs, someTypeStringFuncAddr, otherTypeStringFuncAddr) } - _, err := c.CreateBreakpoint(&api.Breakpoint{FunctionName: "main.main", Line: 3, Tracepoint: false}) + _, err := c.CreateBreakpoint(&api.Breakpoint{FunctionName: "main.main", Line: 4, Tracepoint: false}) if err != nil { t.Fatalf("CreateBreakpoint(): %v\n", err) } <-c.Continue() - locationsprog34Addr := findLocationHelper(t, c, "locationsprog.go:34", false, 1, 0)[0] - findLocationHelper(t, c, fmt.Sprintf("%s:34", testProgPath(t, "locationsprog")), false, 1, locationsprog34Addr) - findLocationHelper(t, c, "+1", false, 1, locationsprog34Addr) - findLocationHelper(t, c, "34", false, 1, locationsprog34Addr) - findLocationHelper(t, c, "-1", false, 1, findLocationHelper(t, c, "locationsprog.go:32", false, 1, 0)[0]) + locationsprog35Addr := findLocationHelper(t, c, "locationsprog.go:35", false, 1, 0)[0] + findLocationHelper(t, c, fmt.Sprintf("%s:35", testProgPath(t, "locationsprog")), false, 1, locationsprog35Addr) + findLocationHelper(t, c, "+1", false, 1, locationsprog35Addr) + findLocationHelper(t, c, "35", false, 1, locationsprog35Addr) + findLocationHelper(t, c, "-1", false, 1, findLocationHelper(t, c, "locationsprog.go:33", false, 1, 0)[0]) }) withTestClient1("testnextdefer", t, func(c *rpc1.RPCClient) { diff --git a/service/test/integration2_test.go b/service/test/integration2_test.go index 6f79856f..5d01758d 100644 --- a/service/test/integration2_test.go +++ b/service/test/integration2_test.go @@ -588,18 +588,18 @@ func TestClientServer_FindLocations(t *testing.T) { t.Fatalf("Wrong locations returned for \"/.*Type.*String/\", got: %v expected: %v and %v\n", stringAddrs, someTypeStringFuncAddr, otherTypeStringFuncAddr) } - _, err := c.CreateBreakpoint(&api.Breakpoint{FunctionName: "main.main", Line: 3, Tracepoint: false}) + _, err := c.CreateBreakpoint(&api.Breakpoint{FunctionName: "main.main", Line: 4, Tracepoint: false}) if err != nil { t.Fatalf("CreateBreakpoint(): %v\n", err) } <-c.Continue() - locationsprog34Addr := findLocationHelper(t, c, "locationsprog.go:34", false, 1, 0)[0] - findLocationHelper(t, c, fmt.Sprintf("%s:34", testProgPath(t, "locationsprog")), false, 1, locationsprog34Addr) - findLocationHelper(t, c, "+1", false, 1, locationsprog34Addr) - findLocationHelper(t, c, "34", false, 1, locationsprog34Addr) - findLocationHelper(t, c, "-1", false, 1, findLocationHelper(t, c, "locationsprog.go:32", false, 1, 0)[0]) + locationsprog35Addr := findLocationHelper(t, c, "locationsprog.go:35", false, 1, 0)[0] + findLocationHelper(t, c, fmt.Sprintf("%s:35", testProgPath(t, "locationsprog")), false, 1, locationsprog35Addr) + findLocationHelper(t, c, "+1", false, 1, locationsprog35Addr) + findLocationHelper(t, c, "35", false, 1, locationsprog35Addr) + findLocationHelper(t, c, "-1", false, 1, findLocationHelper(t, c, "locationsprog.go:33", false, 1, 0)[0]) }) withTestClient2("testnextdefer", t, func(c service.Client) { diff --git a/service/test/variables_test.go b/service/test/variables_test.go index b69dfd84..4e90b8b1 100644 --- a/service/test/variables_test.go +++ b/service/test/variables_test.go @@ -374,7 +374,7 @@ func TestEmbeddedStruct(t *testing.T) { {"b.ptr.val", true, "1337", "1337", "int", nil}, {"b.C.s", true, "\"hello\"", "\"hello\"", "string", nil}, {"b.s", true, "\"hello\"", "\"hello\"", "string", nil}, - {"b2", true, "main.B {main.A: struct main.A {val: 42}, *main.C: *struct main.C nil, a: main.A {val: 47}, ptr: *main.A nil}", "main.B {main.A: (*struct main.A)(0x…", "main.B", nil}, + {"b2", true, "main.B {main.A: main.A {val: 42}, *main.C: *main.C nil, a: main.A {val: 47}, ptr: *main.A nil}", "main.B {main.A: (*main.A)(0x…", "main.B", nil}, } assertNoError(p.Continue(), t, "Continue()") @@ -459,7 +459,7 @@ func TestEvalExpression(t *testing.T) { {"ch1+1", false, "", "", "", fmt.Errorf("can not convert 1 constant to chan int")}, // maps - {"m1[\"Malone\"]", false, "struct main.astruct {A: 2, B: 3}", "struct main.astruct {A: 2, B: 3}", "struct main.astruct", nil}, + {"m1[\"Malone\"]", false, "main.astruct {A: 2, B: 3}", "main.astruct {A: 2, B: 3}", "main.astruct", nil}, {"m2[1].B", false, "11", "11", "int", nil}, {"m2[c1.sa[2].B-4].A", false, "10", "10", "int", nil}, {"m2[*p1].B", false, "11", "11", "int", nil}, @@ -468,10 +468,10 @@ func TestEvalExpression(t *testing.T) { {"m1[80:]", false, "", "", "", fmt.Errorf("map index out of bounds")}, // interfaces - {"err1", true, "error(*struct main.astruct) *{A: 1, B: 2}", "error(*struct main.astruct) 0x…", "error", nil}, - {"err2", true, "error(*struct main.bstruct) *{a: main.astruct {A: 1, B: 2}}", "error(*struct main.bstruct) 0x…", "error", nil}, + {"err1", true, "error(*main.astruct) *{A: 1, B: 2}", "error(*main.astruct) 0x…", "error", nil}, + {"err2", true, "error(*main.bstruct) *{a: main.astruct {A: 1, B: 2}}", "error(*main.bstruct) 0x…", "error", nil}, {"errnil", true, "error nil", "error nil", "error", nil}, - {"iface1", true, "interface {}(*struct main.astruct) *{A: 1, B: 2}", "interface {}(*struct main.astruct) 0x…", "interface {}", nil}, + {"iface1", true, "interface {}(*main.astruct) *{A: 1, B: 2}", "interface {}(*main.astruct) 0x…", "interface {}", nil}, {"iface2", true, "interface {}(*string) *\"test\"", "interface {}(*string) 0x…", "interface {}", nil}, {"iface3", true, "interface {}(*map[string]go/constant.Value) *[]", "interface {}(*map[string]go/constant.Value) 0x…", "interface {}", nil}, {"iface4", true, "interface {}(*[]go/constant.Value) *[*4]", "interface {}(*[]go/constant.Value) 0x…", "interface {}", nil}, @@ -480,8 +480,8 @@ func TestEvalExpression(t *testing.T) { {"err1 == iface1", false, "", "", "", fmt.Errorf("mismatched types \"error\" and \"interface {}\"")}, {"errnil == nil", false, "false", "false", "", nil}, {"nil == errnil", false, "false", "false", "", nil}, - {"err1.(*main.astruct)", false, "*struct main.astruct {A: 1, B: 2}", "(*struct main.astruct)(0x…", "*struct main.astruct", nil}, - {"err1.(*main.bstruct)", false, "", "", "", fmt.Errorf("interface conversion: error is *struct main.astruct, not *struct main.bstruct")}, + {"err1.(*main.astruct)", false, "*main.astruct {A: 1, B: 2}", "(*main.astruct)(0x…", "*main.astruct", nil}, + {"err1.(*main.bstruct)", false, "", "", "", fmt.Errorf("interface conversion: error is *main.astruct, not *main.bstruct")}, {"errnil.(*main.astruct)", false, "", "", "", fmt.Errorf("interface conversion: error is nil, not *main.astruct")}, {"const1", true, "go/constant.Value(*go/constant.int64Val) *3", "go/constant.Value(*go/constant.int64Val) 0x…", "go/constant.Value", nil}, @@ -669,7 +669,7 @@ func TestEvalAddrAndCast(t *testing.T) { a, err := evalVariable(p, "*"+aaddrstr, pnormalLoadConfig) assertNoError(err, t, fmt.Sprintf("EvalExpression(*%s)", aaddrstr)) t.Logf("*%s → %s", aaddrstr, api.ConvertVar(a).SinglelineString()) - assertVariable(t, a, varTest{aaddrstr, false, "struct main.astruct {A: 1, B: 2}", "", "struct main.astruct", nil}) + assertVariable(t, a, varTest{aaddrstr, false, "main.astruct {A: 1, B: 2}", "", "main.astruct", nil}) }) }