mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 02:36:18 +08:00 
			
		
		
		
	proc: disable caching for variables with an extended location
Our current frame caching strategy doesn't handle extended locations expressions correctly, disable it on variables that don't have a simple address.
This commit is contained in:
		| @ -128,6 +128,7 @@ func TestDwarfExprComposite(t *testing.T) { | |||||||
| 	testCases := map[string]uint16{ | 	testCases := map[string]uint16{ | ||||||
| 		"pair.k": 0x8765, | 		"pair.k": 0x8765, | ||||||
| 		"pair.v": 0x5678, | 		"pair.v": 0x5678, | ||||||
|  | 		"n":      42, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	const stringVal = "this is a string" | 	const stringVal = "this is a string" | ||||||
| @ -163,6 +164,7 @@ func TestDwarfExprComposite(t *testing.T) { | |||||||
| 	dwb.AddVariable("s", stringoff, dwarfbuilder.LocationBlock( | 	dwb.AddVariable("s", stringoff, dwarfbuilder.LocationBlock( | ||||||
| 		op.DW_OP_reg1, op.DW_OP_piece, uint(8), | 		op.DW_OP_reg1, op.DW_OP_piece, uint(8), | ||||||
| 		op.DW_OP_reg0, op.DW_OP_piece, uint(8))) | 		op.DW_OP_reg0, op.DW_OP_piece, uint(8))) | ||||||
|  | 	dwb.AddVariable("n", intoff, dwarfbuilder.LocationBlock(op.DW_OP_reg3)) | ||||||
| 	dwb.TagClose() | 	dwb.TagClose() | ||||||
|  |  | ||||||
| 	bi := fakeBinaryInfo(t, dwb) | 	bi := fakeBinaryInfo(t, dwb) | ||||||
| @ -173,6 +175,7 @@ func TestDwarfExprComposite(t *testing.T) { | |||||||
| 	regs.Rax = uint64(len(stringVal)) | 	regs.Rax = uint64(len(stringVal)) | ||||||
| 	regs.Rdx = defaultCFA + 18 | 	regs.Rdx = defaultCFA + 18 | ||||||
| 	regs.Rcx = uint64(testCases["pair.k"]) | 	regs.Rcx = uint64(testCases["pair.k"]) | ||||||
|  | 	regs.Rbx = uint64(testCases["n"]) | ||||||
|  |  | ||||||
| 	scope := dwarfExprCheck(t, mem, dwarfRegisters(®s), bi, testCases) | 	scope := dwarfExprCheck(t, mem, dwarfRegisters(®s), bi, testCases) | ||||||
|  |  | ||||||
|  | |||||||
| @ -80,6 +80,13 @@ func cacheMemory(mem MemoryReadWriter, addr uintptr, size int) MemoryReadWriter | |||||||
| // including client code) assumes that addr == 0 is nil | // including client code) assumes that addr == 0 is nil | ||||||
| const fakeAddress = 0xbeef0000 | const fakeAddress = 0xbeef0000 | ||||||
|  |  | ||||||
|  | // compositeMemory represents a chunk of memory that is stored in CPU | ||||||
|  | // registers or non-contiguously. | ||||||
|  | // | ||||||
|  | // When optimizations are enabled the compiler will store some variables | ||||||
|  | // into registers and sometimes it will also store structs non-contiguously | ||||||
|  | // with some fields stored into CPU registers and other fields stored in | ||||||
|  | // memory. | ||||||
| type compositeMemory struct { | type compositeMemory struct { | ||||||
| 	realmem MemoryReadWriter | 	realmem MemoryReadWriter | ||||||
| 	regs    op.DwarfRegisters | 	regs    op.DwarfRegisters | ||||||
|  | |||||||
| @ -1897,13 +1897,19 @@ func (scope *EvalScope) variablesByTag(tag dwarf.Tag, cfg *LoadConfig) ([]*Varia | |||||||
| 		sort.Stable(&variablesByDepth{vars, depths}) | 		sort.Stable(&variablesByDepth{vars, depths}) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// prefetch the whole chunk of memory relative to these variables | 	// Prefetch the whole chunk of memory relative to these variables. | ||||||
|  | 	// Variables that are not stored contiguously in memory (i.e. the ones that | ||||||
|  | 	// read from a compositeMemory) will be ignored. | ||||||
|  |  | ||||||
| 	minaddr := vars[0].Addr | 	minaddr := vars[0].Addr | ||||||
| 	var maxaddr uintptr | 	var maxaddr uintptr | ||||||
| 	var size int64 | 	var size int64 | ||||||
|  |  | ||||||
| 	for _, v := range vars { | 	for _, v := range vars { | ||||||
|  | 		if _, extloc := v.mem.(*compositeMemory); extloc { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		if v.Addr < minaddr { | 		if v.Addr < minaddr { | ||||||
| 			minaddr = v.Addr | 			minaddr = v.Addr | ||||||
| 		} | 		} | ||||||
| @ -1923,9 +1929,11 @@ func (scope *EvalScope) variablesByTag(tag dwarf.Tag, cfg *LoadConfig) ([]*Varia | |||||||
| 		mem := cacheMemory(vars[0].mem, minaddr, int(maxaddr-minaddr)) | 		mem := cacheMemory(vars[0].mem, minaddr, int(maxaddr-minaddr)) | ||||||
|  |  | ||||||
| 		for _, v := range vars { | 		for _, v := range vars { | ||||||
|  | 			if _, extloc := v.mem.(*compositeMemory); !extloc { | ||||||
| 				v.mem = mem | 				v.mem = mem | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	lvn := map[string]*Variable{} // lvn[n] is the last variable we saw named n | 	lvn := map[string]*Variable{} // lvn[n] is the last variable we saw named n | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 aarzilli
					aarzilli