mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 18:57:18 +08:00 
			
		
		
		
	terminal,service: add raw examinemem dump (#3721)
Change the examinemem command to have a new format 'raw' that just prints the raw memory bytes. Change the transcript command to add a new flag that disables prompt echo to the output file. Fixes #3706
This commit is contained in:
		 Alessandro Arzilli
					Alessandro Arzilli
				
			
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			 GitHub
						GitHub
					
				
			
						parent
						
							4a5350fd1f
						
					
				
				
					commit
					52405ba86b
				
			| @ -354,7 +354,7 @@ Examine memory: | ||||
| 	examinemem [-fmt <format>] [-count|-len <count>] [-size <size>] <address> | ||||
| 	examinemem [-fmt <format>] [-count|-len <count>] [-size <size>] -x <expression> | ||||
|  | ||||
| Format represents the data format and the value is one of this list (default hex): bin(binary), oct(octal), dec(decimal), hex(hexadecimal). | ||||
| Format represents the data format and the value is one of this list (default hex): bin(binary), oct(octal), dec(decimal), hex(hexadecimal) and raw. | ||||
| Length is the number of bytes (default 1) and must be less than or equal to 1000. | ||||
| Address is the memory location of the target to examine. Please note '-len' is deprecated by '-count and -size'. | ||||
| Expression can be an integer expression or pointer value of the memory location to examine. | ||||
|  | ||||
| @ -586,7 +586,7 @@ Examine memory: | ||||
| 	examinemem [-fmt <format>] [-count|-len <count>] [-size <size>] <address> | ||||
| 	examinemem [-fmt <format>] [-count|-len <count>] [-size <size>] -x <expression> | ||||
|  | ||||
| Format represents the data format and the value is one of this list (default hex): bin(binary), oct(octal), dec(decimal), hex(hexadecimal). | ||||
| Format represents the data format and the value is one of this list (default hex): bin(binary), oct(octal), dec(decimal), hex(hexadecimal) and raw. | ||||
| Length is the number of bytes (default 1) and must be less than or equal to 1000. | ||||
| Address is the memory location of the target to examine. Please note '-len' is deprecated by '-count and -size'. | ||||
| Expression can be an integer expression or pointer value of the memory location to examine. | ||||
| @ -2057,9 +2057,10 @@ func examineMemoryCmd(t *Term, ctx callContext, argstr string) error { | ||||
|  | ||||
| 	// Default value | ||||
| 	priFmt := byte('x') | ||||
| 	count := 1 | ||||
| 	size := 1 | ||||
| 	count := int64(1) | ||||
| 	size := int64(1) | ||||
| 	isExpr := false | ||||
| 	rawout := false | ||||
|  | ||||
| 	// nextArg returns the next argument that is not an empty string, if any, and | ||||
| 	// advances the args slice to the position after that. | ||||
| @ -2085,6 +2086,9 @@ loop: | ||||
| 			if arg == "" { | ||||
| 				return errors.New("expected argument after -fmt") | ||||
| 			} | ||||
| 			if arg == "raw" { | ||||
| 				rawout = true | ||||
| 			} else { | ||||
| 				fmtMapToPriFmt := map[string]byte{ | ||||
| 					"oct":         'o', | ||||
| 					"octal":       'o', | ||||
| @ -2099,13 +2103,14 @@ loop: | ||||
| 				if !ok { | ||||
| 					return fmt.Errorf("%q is not a valid format", arg) | ||||
| 				} | ||||
| 			} | ||||
| 		case "-count", "-len": | ||||
| 			arg := nextArg() | ||||
| 			if arg == "" { | ||||
| 				return errors.New("expected argument after -count/-len") | ||||
| 			} | ||||
| 			var err error | ||||
| 			count, err = strconv.Atoi(arg) | ||||
| 			count, err = strconv.ParseInt(arg, 0, 64) | ||||
| 			if err != nil || count <= 0 { | ||||
| 				return errors.New("count/len must be a positive integer") | ||||
| 			} | ||||
| @ -2115,7 +2120,7 @@ loop: | ||||
| 				return errors.New("expected argument after -size") | ||||
| 			} | ||||
| 			var err error | ||||
| 			size, err = strconv.Atoi(arg) | ||||
| 			size, err = strconv.ParseInt(arg, 0, 64) | ||||
| 			if err != nil || size <= 0 || size > 8 { | ||||
| 				return errors.New("size must be a positive integer (<=8)") | ||||
| 			} | ||||
| @ -2131,11 +2136,6 @@ loop: | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// TODO, maybe configured by user. | ||||
| 	if count*size > 1000 { | ||||
| 		return errors.New("read memory range (count*size) must be less than or equal to 1000 bytes") | ||||
| 	} | ||||
|  | ||||
| 	if len(args) == 0 { | ||||
| 		return errors.New("no address specified") | ||||
| 	} | ||||
| @ -2169,12 +2169,28 @@ loop: | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	memArea, isLittleEndian, err := t.client.ExamineMemory(address, count*size) | ||||
| 	t.stdout.pw.PageMaybe(nil) | ||||
|  | ||||
| 	start := address | ||||
| 	remsz := int(count * size) | ||||
|  | ||||
| 	for remsz > 0 { | ||||
| 		reqsz := rpc2.ExamineMemoryLengthLimit | ||||
| 		if reqsz > remsz { | ||||
| 			reqsz = remsz | ||||
| 		} | ||||
| 		memArea, isLittleEndian, err := t.client.ExamineMemory(start, reqsz) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	t.stdout.pw.PageMaybe(nil) | ||||
| 	fmt.Fprint(t.stdout, api.PrettyExamineMemory(uintptr(address), memArea, isLittleEndian, priFmt, size)) | ||||
| 		if rawout { | ||||
| 			t.stdout.Write(memArea) | ||||
| 		} else { | ||||
| 			fmt.Fprint(t.stdout, api.PrettyExamineMemory(uintptr(start), memArea, isLittleEndian, priFmt, int(size))) | ||||
| 		} | ||||
| 		start += uint64(reqsz) | ||||
| 		remsz -= reqsz | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -97,6 +97,9 @@ func (v sliceAsStarlarkValue) Hash() (uint32, error) { | ||||
| } | ||||
|  | ||||
| func (v sliceAsStarlarkValue) String() string { | ||||
| 	if x, ok := v.v.Interface().([]byte); ok { | ||||
| 		return string(x) | ||||
| 	} | ||||
| 	return fmt.Sprintf("%#v", v.v) | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -977,8 +977,10 @@ type ExaminedMemoryOut struct { | ||||
| 	IsLittleEndian bool | ||||
| } | ||||
|  | ||||
| const ExamineMemoryLengthLimit = 1 << 16 | ||||
|  | ||||
| func (s *RPCServer) ExamineMemory(arg ExamineMemoryIn, out *ExaminedMemoryOut) error { | ||||
| 	if arg.Length > 1000 { | ||||
| 	if arg.Length > ExamineMemoryLengthLimit { | ||||
| 		return errors.New("len must be less than or equal to 1000") | ||||
| 	} | ||||
| 	Mem, err := s.debugger.ExamineMemory(arg.Address, arg.Length) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user