mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 10:47:27 +08:00 
			
		
		
		
	Refactor: replace dwarf.Reader with wrapped reader
This commit is contained in:
		| @ -63,27 +63,21 @@ func (reader *Reader) SeekToFunction(pc uint64) (*dwarf.Entry, error) { | |||||||
| 	return nil, fmt.Errorf("unable to find function context") | 	return nil, fmt.Errorf("unable to find function context") | ||||||
| } | } | ||||||
|  |  | ||||||
| // SeekToTypeNamed moves the reader to the type specified by the name. | // Returns the address for the named entry. | ||||||
| // If the reader is set to a struct type the NextMemberVariable call | func (reader *Reader) AddrFor(name string) (uint64, error) { | ||||||
| // can be used to walk all member data. | 	entry, err := reader.FindEntryNamed(name, false) | ||||||
| func (reader *Reader) SeekToTypeNamed(name string) (*dwarf.Entry, error) { | 	if err != nil { | ||||||
| 	// Walk the types to the base | 		return 0, err | ||||||
| 	for entry, err := reader.Next(); entry != nil; entry, err = reader.Next() { |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		n, ok := entry.Val(dwarf.AttrName).(string) |  | ||||||
| 		if !ok { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if n == name { |  | ||||||
| 			return entry, nil |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
|  | 	instructions, ok := entry.Val(dwarf.AttrLocation).([]byte) | ||||||
| 	return nil, errors.New("no type entry found") | 	if !ok { | ||||||
|  | 		return 0, fmt.Errorf("type assertion failed") | ||||||
|  | 	} | ||||||
|  | 	addr, err := op.ExecuteStackProgram(0, instructions) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return 0, err | ||||||
|  | 	} | ||||||
|  | 	return uint64(addr), nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // Returns the address for the named struct member. | // Returns the address for the named struct member. | ||||||
| @ -143,6 +137,105 @@ func (reader *Reader) SeekToType(entry *dwarf.Entry, resolveTypedefs bool, resol | |||||||
| 	return nil, fmt.Errorf("no type entry found") | 	return nil, fmt.Errorf("no type entry found") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // SeekToTypeNamed moves the reader to the type specified by the name. | ||||||
|  | // If the reader is set to a struct type the NextMemberVariable call | ||||||
|  | // can be used to walk all member data. | ||||||
|  | func (reader *Reader) SeekToTypeNamed(name string) (*dwarf.Entry, error) { | ||||||
|  | 	// Walk the types to the base | ||||||
|  | 	for entry, err := reader.Next(); entry != nil; entry, err = reader.Next() { | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		n, ok := entry.Val(dwarf.AttrName).(string) | ||||||
|  | 		if !ok { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if n == name { | ||||||
|  | 			return entry, nil | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil, errors.New("no type entry found") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Finds the entry for 'name'. | ||||||
|  | func (reader *Reader) FindEntryNamed(name string, member bool) (*dwarf.Entry, error) { | ||||||
|  | 	depth := 1 | ||||||
|  | 	for entry, err := reader.Next(); entry != nil; entry, err = reader.Next() { | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if entry.Children { | ||||||
|  | 			depth++ | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if entry.Tag == 0 { | ||||||
|  | 			depth-- | ||||||
|  | 			if depth <= 0 { | ||||||
|  | 				return nil, fmt.Errorf("could not find symbol value for %s", name) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if member { | ||||||
|  | 			if entry.Tag != dwarf.TagMember { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			if entry.Tag != dwarf.TagVariable && entry.Tag != dwarf.TagFormalParameter && entry.Tag != dwarf.TagStructType { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		n, ok := entry.Val(dwarf.AttrName).(string) | ||||||
|  | 		if !ok || n != name { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		return entry, nil | ||||||
|  | 	} | ||||||
|  | 	return nil, fmt.Errorf("could not find symbol value for %s", name) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (reader *Reader) InstructionsForEntryNamed(name string, member bool) ([]byte, error) { | ||||||
|  | 	entry, err := reader.FindEntryNamed(name, member) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	var attr dwarf.Attr | ||||||
|  | 	if member { | ||||||
|  | 		attr = dwarf.AttrDataMemberLoc | ||||||
|  | 	} else { | ||||||
|  | 		attr = dwarf.AttrLocation | ||||||
|  | 	} | ||||||
|  | 	instr, ok := entry.Val(attr).([]byte) | ||||||
|  | 	if !ok { | ||||||
|  | 		return nil, errors.New("invalid typecast for Dwarf instructions") | ||||||
|  | 	} | ||||||
|  | 	return instr, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (reader *Reader) InstructionsForEntry(entry *dwarf.Entry) ([]byte, error) { | ||||||
|  | 	if entry.Tag == dwarf.TagMember { | ||||||
|  | 		instructions, ok := entry.Val(dwarf.AttrDataMemberLoc).([]byte) | ||||||
|  | 		if !ok { | ||||||
|  | 			return nil, fmt.Errorf("member data has no data member location attribute") | ||||||
|  | 		} | ||||||
|  | 		// clone slice to prevent stomping on the dwarf data | ||||||
|  | 		return append([]byte{}, instructions...), nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// non-member | ||||||
|  | 	instructions, ok := entry.Val(dwarf.AttrLocation).([]byte) | ||||||
|  | 	if !ok { | ||||||
|  | 		return nil, fmt.Errorf("entry has no location attribute") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// clone slice to prevent stomping on the dwarf data | ||||||
|  | 	return append([]byte{}, instructions...), nil | ||||||
|  | } | ||||||
|  |  | ||||||
| // NextScopeVariable moves the reader to the next debug entry that describes a local variable and returns the entry. | // NextScopeVariable moves the reader to the next debug entry that describes a local variable and returns the entry. | ||||||
| func (reader *Reader) NextScopeVariable() (*dwarf.Entry, error) { | func (reader *Reader) NextScopeVariable() (*dwarf.Entry, error) { | ||||||
| 	for entry, err := reader.Next(); entry != nil; entry, err = reader.Next() { | 	for entry, err := reader.Next(); entry != nil; entry, err = reader.Next() { | ||||||
|  | |||||||
| @ -393,16 +393,22 @@ func (dbp *DebuggedProcess) SwitchThread(tid int) error { | |||||||
| // Delve cares about from the internal runtime G structure. | // Delve cares about from the internal runtime G structure. | ||||||
| func (dbp *DebuggedProcess) GoroutinesInfo() ([]*G, error) { | func (dbp *DebuggedProcess) GoroutinesInfo() ([]*G, error) { | ||||||
| 	var ( | 	var ( | ||||||
| 		allg   []*G | 		allg []*G | ||||||
| 		reader = dbp.dwarf.Reader() | 		rdr  = dbp.DwarfReader() | ||||||
| 	) | 	) | ||||||
|  |  | ||||||
| 	allglen, err := allglenval(dbp, reader) | 	addr, err := rdr.AddrFor("runtime.allglen") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	reader.Seek(0) | 	allglenBytes, err := dbp.CurrentThread.readMemory(uintptr(addr), 8) | ||||||
| 	allgentryaddr, err := addressFor(dbp, "runtime.allg", reader) | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	allglen := binary.LittleEndian.Uint64(allglenBytes) | ||||||
|  |  | ||||||
|  | 	rdr.Seek(0) | ||||||
|  | 	allgentryaddr, err := rdr.AddrFor("runtime.allg") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -68,172 +68,6 @@ func (g *G) chanRecvReturnAddr(dbp *DebuggedProcess) (uint64, error) { | |||||||
| 	return topLoc.addr, nil | 	return topLoc.addr, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // Parses and returns select info on the internal M |  | ||||||
| // data structures used by the Go scheduler. |  | ||||||
| func (thread *ThreadContext) AllM() ([]*M, error) { |  | ||||||
| 	reader := thread.Process.dwarf.Reader() |  | ||||||
|  |  | ||||||
| 	allmaddr, err := parseAllMPtr(thread.Process, reader) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	mptr, err := thread.readMemory(uintptr(allmaddr), thread.Process.arch.PtrSize()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	m := binary.LittleEndian.Uint64(mptr) |  | ||||||
| 	if m == 0 { |  | ||||||
| 		return nil, fmt.Errorf("allm contains no M pointers") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	procidInstructions, err := instructionsFor("procid", thread.Process, reader, true) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	spinningInstructions, err := instructionsFor("spinning", thread.Process, reader, true) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	alllinkInstructions, err := instructionsFor("alllink", thread.Process, reader, true) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	blockedInstructions, err := instructionsFor("blocked", thread.Process, reader, true) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	curgInstructions, err := instructionsFor("curg", thread.Process, reader, true) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	var allm []*M |  | ||||||
| 	for { |  | ||||||
| 		// curg |  | ||||||
| 		curgAddr, err := executeMemberStackProgram(mptr, curgInstructions) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		curgBytes, err := thread.readMemory(uintptr(curgAddr), thread.Process.arch.PtrSize()) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, fmt.Errorf("could not read curg %#v %s", curgAddr, err) |  | ||||||
| 		} |  | ||||||
| 		curg := binary.LittleEndian.Uint64(curgBytes) |  | ||||||
|  |  | ||||||
| 		// procid |  | ||||||
| 		procidAddr, err := executeMemberStackProgram(mptr, procidInstructions) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		procidBytes, err := thread.readMemory(uintptr(procidAddr), thread.Process.arch.PtrSize()) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, fmt.Errorf("could not read procid %#v %s", procidAddr, err) |  | ||||||
| 		} |  | ||||||
| 		procid := binary.LittleEndian.Uint64(procidBytes) |  | ||||||
|  |  | ||||||
| 		// spinning |  | ||||||
| 		spinningAddr, err := executeMemberStackProgram(mptr, spinningInstructions) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		spinBytes, err := thread.readMemory(uintptr(spinningAddr), 1) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, fmt.Errorf("could not read spinning %#v %s", spinningAddr, err) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// blocked |  | ||||||
| 		blockedAddr, err := executeMemberStackProgram(mptr, blockedInstructions) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		blockBytes, err := thread.readMemory(uintptr(blockedAddr), 1) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, fmt.Errorf("could not read blocked %#v %s", blockedAddr, err) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		allm = append(allm, &M{ |  | ||||||
| 			procid:   int(procid), |  | ||||||
| 			blocked:  blockBytes[0], |  | ||||||
| 			spinning: spinBytes[0], |  | ||||||
| 			curg:     uintptr(curg), |  | ||||||
| 		}) |  | ||||||
|  |  | ||||||
| 		// Follow the linked list |  | ||||||
| 		alllinkAddr, err := executeMemberStackProgram(mptr, alllinkInstructions) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		mptr, err = thread.readMemory(uintptr(alllinkAddr), thread.Process.arch.PtrSize()) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, fmt.Errorf("could not read alllink %#v %s", alllinkAddr, err) |  | ||||||
| 		} |  | ||||||
| 		m = binary.LittleEndian.Uint64(mptr) |  | ||||||
|  |  | ||||||
| 		if m == 0 { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return allm, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func instructionsFor(name string, dbp *DebuggedProcess, reader *dwarf.Reader, member bool) ([]byte, error) { |  | ||||||
| 	reader.Seek(0) |  | ||||||
| 	entry, err := findDwarfEntry(name, reader, member) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return instructionsForEntry(entry) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func instructionsForEntry(entry *dwarf.Entry) ([]byte, error) { |  | ||||||
| 	if entry.Tag == dwarf.TagMember { |  | ||||||
| 		instructions, ok := entry.Val(dwarf.AttrDataMemberLoc).([]byte) |  | ||||||
| 		if !ok { |  | ||||||
| 			return nil, fmt.Errorf("member data has no data member location attribute") |  | ||||||
| 		} |  | ||||||
| 		// clone slice to prevent stomping on the dwarf data |  | ||||||
| 		return append([]byte{}, instructions...), nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// non-member |  | ||||||
| 	instructions, ok := entry.Val(dwarf.AttrLocation).([]byte) |  | ||||||
| 	if !ok { |  | ||||||
| 		return nil, fmt.Errorf("entry has no location attribute") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// clone slice to prevent stomping on the dwarf data |  | ||||||
| 	return append([]byte{}, instructions...), nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func executeMemberStackProgram(base, instructions []byte) (uint64, error) { |  | ||||||
| 	parentInstructions := append([]byte{op.DW_OP_addr}, base...) |  | ||||||
| 	addr, err := op.ExecuteStackProgram(0, append(parentInstructions, instructions...)) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return uint64(addr), nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func parseAllMPtr(dbp *DebuggedProcess, reader *dwarf.Reader) (uint64, error) { |  | ||||||
| 	entry, err := findDwarfEntry("runtime.allm", reader, false) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	instructions, ok := entry.Val(dwarf.AttrLocation).([]byte) |  | ||||||
| 	if !ok { |  | ||||||
| 		return 0, fmt.Errorf("type assertion failed") |  | ||||||
| 	} |  | ||||||
| 	addr, err := op.ExecuteStackProgram(0, instructions) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return uint64(addr), nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type NoGError struct { | type NoGError struct { | ||||||
| 	tid int | 	tid int | ||||||
| } | } | ||||||
| @ -319,45 +153,6 @@ func parseG(thread *ThreadContext, addr uint64) (*G, error) { | |||||||
| 	return g, nil | 	return g, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func allglenval(dbp *DebuggedProcess, reader *dwarf.Reader) (uint64, error) { |  | ||||||
| 	entry, err := findDwarfEntry("runtime.allglen", reader, false) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	instructions, ok := entry.Val(dwarf.AttrLocation).([]byte) |  | ||||||
| 	if !ok { |  | ||||||
| 		return 0, fmt.Errorf("type assertion failed") |  | ||||||
| 	} |  | ||||||
| 	addr, err := op.ExecuteStackProgram(0, instructions) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
| 	val, err := dbp.CurrentThread.readMemory(uintptr(addr), 8) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
| 	return binary.LittleEndian.Uint64(val), nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func addressFor(dbp *DebuggedProcess, name string, reader *dwarf.Reader) (uint64, error) { |  | ||||||
| 	entry, err := findDwarfEntry(name, reader, false) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	instructions, ok := entry.Val(dwarf.AttrLocation).([]byte) |  | ||||||
| 	if !ok { |  | ||||||
| 		return 0, fmt.Errorf("type assertion failed") |  | ||||||
| 	} |  | ||||||
| 	addr, err := op.ExecuteStackProgram(0, instructions) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return uint64(addr), nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Returns the value of the named symbol. | // Returns the value of the named symbol. | ||||||
| func (thread *ThreadContext) EvalSymbol(name string) (*Variable, error) { | func (thread *ThreadContext) EvalSymbol(name string) (*Variable, error) { | ||||||
| 	pc, err := thread.PC() | 	pc, err := thread.PC() | ||||||
| @ -433,45 +228,8 @@ func (thread *ThreadContext) PackageVariables() ([]*Variable, error) { | |||||||
| 	return vars, nil | 	return vars, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func findDwarfEntry(name string, reader *dwarf.Reader, member bool) (*dwarf.Entry, error) { | func (thread *ThreadContext) evaluateStructMember(parentEntry *dwarf.Entry, rdr *reader.Reader, memberName string) (*Variable, error) { | ||||||
| 	depth := 1 | 	parentAddr, err := thread.extractVariableDataAddress(parentEntry, rdr) | ||||||
| 	for entry, err := reader.Next(); entry != nil; entry, err = reader.Next() { |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if entry.Children { |  | ||||||
| 			depth++ |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if entry.Tag == 0 { |  | ||||||
| 			depth-- |  | ||||||
| 			if depth <= 0 { |  | ||||||
| 				return nil, fmt.Errorf("could not find symbol value for %s", name) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if member { |  | ||||||
| 			if entry.Tag != dwarf.TagMember { |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			if entry.Tag != dwarf.TagVariable && entry.Tag != dwarf.TagFormalParameter && entry.Tag != dwarf.TagStructType { |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		n, ok := entry.Val(dwarf.AttrName).(string) |  | ||||||
| 		if !ok || n != name { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		return entry, nil |  | ||||||
| 	} |  | ||||||
| 	return nil, fmt.Errorf("could not find symbol value for %s", name) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (thread *ThreadContext) evaluateStructMember(parentEntry *dwarf.Entry, reader *reader.Reader, memberName string) (*Variable, error) { |  | ||||||
| 	parentAddr, err := thread.extractVariableDataAddress(parentEntry, reader) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @ -483,13 +241,13 @@ func (thread *ThreadContext) evaluateStructMember(parentEntry *dwarf.Entry, read | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Seek reader to the type information so members can be iterated | 	// Seek reader to the type information so members can be iterated | ||||||
| 	_, err = reader.SeekToType(parentEntry, true, true) | 	_, err = rdr.SeekToType(parentEntry, true, true) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Iterate to find member by name | 	// Iterate to find member by name | ||||||
| 	for memberEntry, err := reader.NextMemberVariable(); memberEntry != nil; memberEntry, err = reader.NextMemberVariable() { | 	for memberEntry, err := rdr.NextMemberVariable(); memberEntry != nil; memberEntry, err = rdr.NextMemberVariable() { | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| @ -505,7 +263,7 @@ func (thread *ThreadContext) evaluateStructMember(parentEntry *dwarf.Entry, read | |||||||
| 				return nil, fmt.Errorf("%s is nil", parentName) | 				return nil, fmt.Errorf("%s is nil", parentName) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			memberInstr, err := instructionsForEntry(memberEntry) | 			memberInstr, err := rdr.InstructionsForEntry(memberEntry) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, err | 				return nil, err | ||||||
| 			} | 			} | ||||||
| @ -597,8 +355,8 @@ func (thread *ThreadContext) executeStackProgram(instructions []byte) (int64, er | |||||||
| } | } | ||||||
|  |  | ||||||
| // Extracts the address of a variable, dereferencing any pointers | // Extracts the address of a variable, dereferencing any pointers | ||||||
| func (thread *ThreadContext) extractVariableDataAddress(entry *dwarf.Entry, reader *reader.Reader) (int64, error) { | func (thread *ThreadContext) extractVariableDataAddress(entry *dwarf.Entry, rdr *reader.Reader) (int64, error) { | ||||||
| 	instructions, err := instructionsForEntry(entry) | 	instructions, err := rdr.InstructionsForEntry(entry) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return 0, err | 		return 0, err | ||||||
| 	} | 	} | ||||||
| @ -609,7 +367,7 @@ func (thread *ThreadContext) extractVariableDataAddress(entry *dwarf.Entry, read | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Dereference pointers to get down the concrete type | 	// Dereference pointers to get down the concrete type | ||||||
| 	for typeEntry, err := reader.SeekToType(entry, true, false); typeEntry != nil; typeEntry, err = reader.SeekToType(typeEntry, true, false) { | 	for typeEntry, err := rdr.SeekToType(entry, true, false); typeEntry != nil; typeEntry, err = rdr.SeekToType(typeEntry, true, false) { | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return 0, err | 			return 0, err | ||||||
| 		} | 		} | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Derek Parker
					Derek Parker