mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 02:36:18 +08:00 
			
		
		
		
	Support for uint and boolean types
This commit is contained in:
		| @ -30,14 +30,21 @@ func foobar(baz string, bar FooBar) { | |||||||
| 		a8  = FooBar2{Bur: 10, Baz: "feh"} | 		a8  = FooBar2{Bur: 10, Baz: "feh"} | ||||||
| 		a9  = (*FooBar)(nil) | 		a9  = (*FooBar)(nil) | ||||||
| 		a10 = a1[2:5] | 		a10 = a1[2:5] | ||||||
|  | 		b1  = true | ||||||
|  | 		b2  = false | ||||||
| 		neg = -1 | 		neg = -1 | ||||||
| 		i8  = int8(1) | 		i8  = int8(1) | ||||||
|  | 		u8  = uint8(255) | ||||||
|  | 		u16 = uint16(65535) | ||||||
|  | 		u32 = uint32(4294967295) | ||||||
|  | 		u64 = uint64(18446744073709551615) | ||||||
|  | 		up  = uintptr(5) | ||||||
| 		f32 = float32(1.2) | 		f32 = float32(1.2) | ||||||
| 		i32 = [2]int32{1, 2} | 		i32 = [2]int32{1, 2} | ||||||
| 	) | 	) | ||||||
|  |  | ||||||
| 	barfoo() | 	barfoo() | ||||||
| 	fmt.Println(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, baz, neg, i8, f32, i32, bar) | 	fmt.Println(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, b1, b2, baz, neg, i8, u8, u16, u32, u64, up, f32, i32, bar) | ||||||
| } | } | ||||||
|  |  | ||||||
| func main() { | func main() { | ||||||
|  | |||||||
| @ -616,8 +616,12 @@ func (thread *ThreadContext) extractValue(instructions []byte, addr int64, typ i | |||||||
| 		return thread.readIntArray(ptraddress, t) | 		return thread.readIntArray(ptraddress, t) | ||||||
| 	case *dwarf.IntType: | 	case *dwarf.IntType: | ||||||
| 		return thread.readInt(ptraddress, t.ByteSize) | 		return thread.readInt(ptraddress, t.ByteSize) | ||||||
|  | 	case *dwarf.UintType: | ||||||
|  | 		return thread.readUint(ptraddress, t.ByteSize) | ||||||
| 	case *dwarf.FloatType: | 	case *dwarf.FloatType: | ||||||
| 		return thread.readFloat(ptraddress, t.ByteSize) | 		return thread.readFloat(ptraddress, t.ByteSize) | ||||||
|  | 	case *dwarf.BoolType: | ||||||
|  | 		return thread.readBool(ptraddress) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return "", fmt.Errorf("could not find value for type %s", typ) | 	return "", fmt.Errorf("could not find value for type %s", typ) | ||||||
| @ -693,7 +697,7 @@ func (thread *ThreadContext) readIntArray(addr uintptr, t *dwarf.ArrayType) (str | |||||||
| } | } | ||||||
|  |  | ||||||
| func (thread *ThreadContext) readInt(addr uintptr, size int64) (string, error) { | func (thread *ThreadContext) readInt(addr uintptr, size int64) (string, error) { | ||||||
| 	var n int | 	var n int64 | ||||||
|  |  | ||||||
| 	val, err := thread.readMemory(addr, uintptr(size)) | 	val, err := thread.readMemory(addr, uintptr(size)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @ -702,16 +706,38 @@ func (thread *ThreadContext) readInt(addr uintptr, size int64) (string, error) { | |||||||
|  |  | ||||||
| 	switch size { | 	switch size { | ||||||
| 	case 1: | 	case 1: | ||||||
| 		n = int(val[0]) | 		n = int64(val[0]) | ||||||
| 	case 2: | 	case 2: | ||||||
| 		n = int(binary.LittleEndian.Uint16(val)) | 		n = int64(binary.LittleEndian.Uint16(val)) | ||||||
| 	case 4: | 	case 4: | ||||||
| 		n = int(binary.LittleEndian.Uint32(val)) | 		n = int64(binary.LittleEndian.Uint32(val)) | ||||||
| 	case 8: | 	case 8: | ||||||
| 		n = int(binary.LittleEndian.Uint64(val)) | 		n = int64(binary.LittleEndian.Uint64(val)) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return strconv.Itoa(n), nil | 	return strconv.FormatInt(n, 10), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (thread *ThreadContext) readUint(addr uintptr, size int64) (string, error) { | ||||||
|  | 	var n uint64 | ||||||
|  |  | ||||||
|  | 	val, err := thread.readMemory(addr, uintptr(size)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	switch size { | ||||||
|  | 	case 1: | ||||||
|  | 		n = uint64(val[0]) | ||||||
|  | 	case 2: | ||||||
|  | 		n = uint64(binary.LittleEndian.Uint16(val)) | ||||||
|  | 	case 4: | ||||||
|  | 		n = uint64(binary.LittleEndian.Uint32(val)) | ||||||
|  | 	case 8: | ||||||
|  | 		n = uint64(binary.LittleEndian.Uint64(val)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return strconv.FormatUint(n, 10), nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (thread *ThreadContext) readFloat(addr uintptr, size int64) (string, error) { | func (thread *ThreadContext) readFloat(addr uintptr, size int64) (string, error) { | ||||||
| @ -735,6 +761,19 @@ func (thread *ThreadContext) readFloat(addr uintptr, size int64) (string, error) | |||||||
| 	return "", fmt.Errorf("could not read float") | 	return "", fmt.Errorf("could not read float") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (thread *ThreadContext) readBool(addr uintptr) (string, error) { | ||||||
|  | 	val, err := thread.readMemory(addr, uintptr(1)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if val[0] == 0 { | ||||||
|  | 		return "false", nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return "true", nil | ||||||
|  | } | ||||||
|  |  | ||||||
| func (thread *ThreadContext) readMemory(addr uintptr, size uintptr) ([]byte, error) { | func (thread *ThreadContext) readMemory(addr uintptr, size uintptr) ([]byte, error) { | ||||||
| 	buf := make([]byte, size) | 	buf := make([]byte, size) | ||||||
|  |  | ||||||
| @ -770,7 +809,8 @@ func (thread *ThreadContext) variablesByTag(tag dwarf.Tag) ([]*Variable, error) | |||||||
| 		if entry.Tag == tag { | 		if entry.Tag == tag { | ||||||
| 			val, err := thread.extractVariableFromEntry(entry) | 			val, err := thread.extractVariableFromEntry(entry) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, err | 				// skip variables that we can't parse yet | ||||||
|  | 				continue | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			vars = append(vars, val) | 			vars = append(vars, val) | ||||||
|  | |||||||
| @ -49,7 +49,6 @@ func TestVariableEvaluation(t *testing.T) { | |||||||
| 		{"a9", "*main.FooBar nil", "*main.FooBar", nil}, | 		{"a9", "*main.FooBar nil", "*main.FooBar", nil}, | ||||||
| 		{"baz", "bazburzum", "struct string", nil}, | 		{"baz", "bazburzum", "struct string", nil}, | ||||||
| 		{"neg", "-1", "int", nil}, | 		{"neg", "-1", "int", nil}, | ||||||
| 		{"i8", "1", "int8", nil}, |  | ||||||
| 		{"f32", "1.2", "float32", nil}, | 		{"f32", "1.2", "float32", nil}, | ||||||
| 		{"a6.Baz", "8", "int", nil}, | 		{"a6.Baz", "8", "int", nil}, | ||||||
| 		{"a7.Baz", "5", "int", nil}, | 		{"a7.Baz", "5", "int", nil}, | ||||||
| @ -58,11 +57,18 @@ func TestVariableEvaluation(t *testing.T) { | |||||||
| 		{"a9.NonExistent", "nil", "int", errors.New("a9 has no member NonExistent")}, | 		{"a9.NonExistent", "nil", "int", errors.New("a9 has no member NonExistent")}, | ||||||
| 		{"a8", "main.FooBar2 {Bur: 10, Baz: feh}", "main.FooBar2", nil}, // reread variable after member | 		{"a8", "main.FooBar2 {Bur: 10, Baz: feh}", "main.FooBar2", nil}, // reread variable after member | ||||||
| 		{"i32", "[2]int32 [1 2]", "[2]int32", nil}, | 		{"i32", "[2]int32 [1 2]", "[2]int32", nil}, | ||||||
|  | 		{"b1", "true", "bool", nil}, | ||||||
|  | 		{"b2", "false", "bool", nil}, {"i8", "1", "int8", nil}, | ||||||
|  | 		{"u16", "65535", "uint16", nil}, | ||||||
|  | 		{"u32", "4294967295", "uint32", nil}, | ||||||
|  | 		{"u64", "18446744073709551615", "uint64", nil}, | ||||||
|  | 		{"u8", "255", "uint8", nil}, | ||||||
|  | 		{"up", "5", "uintptr", nil}, | ||||||
| 		{"NonExistent", "", "", errors.New("could not find symbol value for NonExistent")}, | 		{"NonExistent", "", "", errors.New("could not find symbol value for NonExistent")}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	withTestProcess(executablePath, t, func(p *DebuggedProcess) { | 	withTestProcess(executablePath, t, func(p *DebuggedProcess) { | ||||||
| 		pc, _, _ := p.GoSymTable.LineToPC(fp, 39) | 		pc, _, _ := p.GoSymTable.LineToPC(fp, 46) | ||||||
|  |  | ||||||
| 		_, err := p.Break(pc) | 		_, err := p.Break(pc) | ||||||
| 		assertNoError(err, t, "Break() returned an error") | 		assertNoError(err, t, "Break() returned an error") | ||||||
| @ -93,7 +99,7 @@ func TestVariableFunctionScoping(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	withTestProcess(executablePath, t, func(p *DebuggedProcess) { | 	withTestProcess(executablePath, t, func(p *DebuggedProcess) { | ||||||
| 		pc, _, _ := p.GoSymTable.LineToPC(fp, 39) | 		pc, _, _ := p.GoSymTable.LineToPC(fp, 46) | ||||||
|  |  | ||||||
| 		_, err := p.Break(pc) | 		_, err := p.Break(pc) | ||||||
| 		assertNoError(err, t, "Break() returned an error") | 		assertNoError(err, t, "Break() returned an error") | ||||||
| @ -167,10 +173,17 @@ func TestLocalVariables(t *testing.T) { | |||||||
| 				{"a7", "*main.FooBar {Baz: 5, Bur: strum}", "*main.FooBar", nil}, | 				{"a7", "*main.FooBar {Baz: 5, Bur: strum}", "*main.FooBar", nil}, | ||||||
| 				{"a8", "main.FooBar2 {Bur: 10, Baz: feh}", "main.FooBar2", nil}, | 				{"a8", "main.FooBar2 {Bur: 10, Baz: feh}", "main.FooBar2", nil}, | ||||||
| 				{"a9", "*main.FooBar nil", "*main.FooBar", nil}, | 				{"a9", "*main.FooBar nil", "*main.FooBar", nil}, | ||||||
|  | 				{"b1", "true", "bool", nil}, | ||||||
|  | 				{"b2", "false", "bool", nil}, | ||||||
| 				{"f32", "1.2", "float32", nil}, | 				{"f32", "1.2", "float32", nil}, | ||||||
| 				{"i32", "[2]int32 [1 2]", "[2]int32", nil}, | 				{"i32", "[2]int32 [1 2]", "[2]int32", nil}, | ||||||
| 				{"i8", "1", "int8", nil}, | 				{"i8", "1", "int8", nil}, | ||||||
| 				{"neg", "-1", "int", nil}}}, | 				{"neg", "-1", "int", nil}, | ||||||
|  | 				{"u16", "65535", "uint16", nil}, | ||||||
|  | 				{"u32", "4294967295", "uint32", nil}, | ||||||
|  | 				{"u64", "18446744073709551615", "uint64", nil}, | ||||||
|  | 				{"u8", "255", "uint8", nil}, | ||||||
|  | 				{"up", "5", "uintptr", nil}}}, | ||||||
| 		{(*ThreadContext).FunctionArguments, | 		{(*ThreadContext).FunctionArguments, | ||||||
| 			[]varTest{ | 			[]varTest{ | ||||||
| 				{"bar", "main.FooBar {Baz: 10, Bur: lorem}", "main.FooBar", nil}, | 				{"bar", "main.FooBar {Baz: 10, Bur: lorem}", "main.FooBar", nil}, | ||||||
| @ -178,7 +191,7 @@ func TestLocalVariables(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	withTestProcess(executablePath, t, func(p *DebuggedProcess) { | 	withTestProcess(executablePath, t, func(p *DebuggedProcess) { | ||||||
| 		pc, _, _ := p.GoSymTable.LineToPC(fp, 39) | 		pc, _, _ := p.GoSymTable.LineToPC(fp, 46) | ||||||
|  |  | ||||||
| 		_, err := p.Break(pc) | 		_, err := p.Break(pc) | ||||||
| 		assertNoError(err, t, "Break() returned an error") | 		assertNoError(err, t, "Break() returned an error") | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 epipho
					epipho