mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 10:47:27 +08:00 
			
		
		
		
	 9bc6ad4f46
			
		
	
	9bc6ad4f46
	
	
	
		
			
			* tests: update to cope with go1.7 SSA compiler * de-vendored golang.org/x/debug/dwarf We need our own tweaked version * dwarf/debug/dwarf: always use the entry's name attribute Using the name attribute leads to better type names as well as fixes inconsistencies between 1.5, 1.6 and 1.7. * proc: Updated loadInterface to work with go1.7 go1.7 changed the internal representation of types, removing the string field from runtime._type. Updated loadInterface to use the new str field.
		
			
				
	
	
		
			88 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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
 | |
| }
 |