2
0
Эх сурвалжийг харах

Merge pull request #68 from HurryStarfish/master

Pointer dereferencing in debugger (Windows)
Brucey 7 жил өмнө
parent
commit
662cd9819d

+ 111 - 85
appstub.mod/debugger_mt.stdio.bmx

@@ -155,7 +155,7 @@ Function TypeName$( tag$ Var )
 	Case "w"
 		Return "WString"
 	Case "t"
-		Return "size_t"
+		Return "Size_T"
 	Case "W"
 		Return "WParam"
 	Case "X"
@@ -356,10 +356,12 @@ Function DebugDeclValue$( decl:Int Ptr,inst:Byte Ptr )
 		Local s$=String.FromWString( Short Ptr p )
 		Return DebugEscapeString( s )
 	Case Asc("*"),Asc("?"),Asc("#")
+		Local deref:String
+		If tag = Asc("*") Then deref = DebugDerefPointer(decl, p)
 ?Not ptr64
-		Return "$"+ToHex( (Int Ptr p)[0] )
+		Return "$" + ToHex( (Int Ptr p)[0] ) + deref
 ?ptr64
-		Return "$"+ToHex( (Long Ptr p)[0] )
+		Return "$" + ToHex( (Long Ptr p)[0] ) + deref
 ?
 	Case Asc("(")
 		p=(Byte Ptr Ptr p)[0]
@@ -409,95 +411,119 @@ Function DebugScopeKind$( scope:Int Ptr )
 	DebugError "Invalid scope kind"
 End Function
 
-Rem
-?ptr64
-Function DebugDerefPointer$(decl:Int Ptr, pointer:Long Ptr)
-?Not ptr64
-Function DebugDerefPointer$(decl:Int Ptr, pointer:Int Ptr)
-? 
-	Local tipe$=DebugDeclType( decl )
-	Local datatype$ = tipe[..tipe.Find(" ",0)]
-	Local start:Int
-	Local count:Int
+Function DebugDerefPointer:String(decl:Int Ptr, pointer:Byte Ptr)
+	Const derefFailure:String = "{?}"
+	Const derefSymbol:String = "->"
 	
-	Repeat
-		start = tipe.Find("Ptr",start+1)
-		If start = -1 Exit
-		count :+ 1
-	Forever
-
-	For Local i:Int = 0 Until count
-		' Null
-		If pointer = 0 Then
-			Return " {-}"
+	Local declType:String = DebugDeclType(decl)
+	Local dataType:String = declType
+	Local ptrDepth:Int = 0
+	While dataType.EndsWith(" Ptr")
+		dataType = dataType[..dataType.length - " Ptr".length]
+		ptrDepth :+ 1
+	Wend
+	
+	Local result:String = ""
+	
+	
+	? Win32
+	Extern "Win32"
+		Function GetCurrentProcess:Byte Ptr() = "HANDLE GetCurrentProcess(void)!"
+		Function ReadProcessMemory:Int(hProcess:Byte Ptr, lpBaseAddress:Byte Ptr, lpBuffer:Byte Ptr, nSize:Size_T, lpNumberOfBytesRead:Size_T Ptr) = "BOOL ReadProcessMemory(HANDLE, LPCVOID, LPVOID, SIZE_T, SIZE_T*)!"
+	End Extern
+	
+	Local dataSize:Size_T
+	Select dataType
+ 		Case "Byte"      dataSize = SizeOf(Byte Null)
+		Case "Short"     dataSize = SizeOf(Short Null)
+		Case "Int"       dataSize = SizeOf(Int Null)
+		Case "UInt"      dataSize = SizeOf(UInt Null)
+		Case "Long"      dataSize = SizeOf(Long Null)
+		Case "ULong"     dataSize = SizeOf(ULong Null)
+		Case "Size_T"    dataSize = SizeOf(Size_T Null)
+		Case "Float"     dataSize = SizeOf(Float Null)
+		Case "Double"    dataSize = SizeOf(Double Null)
+	? Win32 And Ptr64
+		Case "Float64"   dataSize = SizeOf(Float64 Null)
+		Case "Float128"  dataSize = SizeOf(Float128 Null)
+		Case "Double128" dataSize = SizeOf(Double128 Null)
+		Case "Int128"    dataSize = SizeOf(Int128 Null)
+	? Win32	
+		Case "WParam"    dataSize = SizeOf(WParam Null)
+		Case "LParam"    dataSize = SizeOf(LParam Null)
+		Default          dataSize = 0 ' cannot dereference this
+	EndSelect
+	
+	Local processHandle:Byte Ptr = GetCurrentProcess()
+	Local buffer:Byte Ptr = MemAlloc(Max(dataSize, SizeOf(Byte Ptr Null)))
+	(Byte Ptr Ptr buffer)[0] = Null
+	
+	pointer = (Byte Ptr Ptr pointer)[0]
+	For Local i:Int = 1 To ptrDepth - 1
+		Local success:Int = ReadProcessMemory(processHandle, pointer, buffer, Size_T SizeOf(Byte Ptr Null), Null)
+		If Not success Then
+			MemFree buffer
+			result :+ derefSymbol + derefFailure
+			Return result
 		End If
-?ptr64
-		pointer = Long Ptr (Varptr pointer)[0]
-?Not ptr64
-		pointer = Int Ptr (Varptr pointer)[0]
-?
+		pointer = (Byte Ptr Ptr buffer)[0]
+	? Win32 And Not Ptr64
+		result :+ derefSymbol + "$" + ToHex(Int pointer)
+	? Win32 And Ptr64
+		result :+ derefSymbol + "$" + ToHex(Long pointer)
+	? Win32
 	Next
-
-	' make sure the final pointer is not null
-	If pointer = 0 
-		Return " {-}"
-	EndIf
-
+	
+	Local success:Int
+	If dataSize > 0 Then
+		success = ReadProcessMemory:Int(processHandle, pointer, buffer, dataSize, Null)
+	Else
+		success = False
+	End If
+	If Not success Then
+		MemFree buffer
+		result :+ derefSymbol + derefFailure
+		Return result
+	End If
 	Local value:String
-	Select datatype
-	Case "Byte"
-		' don't reference a byte ptr in case its an OS handle ( which isn't a memory address! )
-		Return " {-}"
-
-	Case "Short"
-		value = Short (Short  Ptr (Varptr pointer)[0])
-		Return " {"+value+"}"
-
-	Case "Int"
-		value =  Int Ptr (Varptr pointer)[0]
-		Return " {"+value+"}"
-
-	Case "Long"
-		value = Long Ptr (Varptr pointer)[0]
-		Return " {"+value+"}"
-
-	Case "Float"
-		value = Float (Float Ptr (pointer)[0])
-		Return " {"+value+"}"
-		
-	Case "Double"
-		value = Double Ptr (Varptr pointer)[0]
-		Return " {"+value+"}"
-
-	Case "Float64"
-		value = String(Float Ptr (Varptr pointer)[0])
-		value :+ "," + String(Float Ptr (Varptr pointer)[1])
-		Return " {"+value+"}"
-
-	Case "Float128"
-		value = String(Float Ptr (Varptr pointer)[0])
-		value :+ "," + String(Float Ptr (Varptr pointer)[1])
-		value :+ "," + String(Float Ptr (Varptr pointer)[2])
-		value :+ "," + String(Float Ptr (Varptr pointer)[3])
-		Return " {"+value+"}"
-
-	Case "Double128"
-		value = String(Double Ptr (Varptr pointer)[0])
-		value :+ "," + String(Double Ptr (Varptr pointer)[1])
-		Return " {"+value+"}"
-
-	Case "Int128"
-		value = String(Int Ptr (Varptr pointer)[0])
-		value :+ "," + String(Int Ptr (Varptr pointer)[1])
-		value :+ "," + String(Int Ptr (Varptr pointer)[2])
-		value :+ "," + String(Int Ptr (Varptr pointer)[3])
-		Return " {"+value+"}"
-
+	Select dataType
+ 		Case "Byte"      value = String((Byte   Ptr buffer)[0])
+		Case "Short"     value = String((Short  Ptr buffer)[0])
+		Case "Int"       value = String((Int    Ptr buffer)[0])
+		Case "UInt"      value = String((UInt   Ptr buffer)[0])
+		Case "Long"      value = String((Long   Ptr buffer)[0])
+		Case "ULong"     value = String((ULong  Ptr buffer)[0])
+		Case "Size_T"    value = String((Size_T Ptr buffer)[0])
+		Case "Float"     value = String((Float  Ptr buffer)[0])
+		Case "Double"    value = String((Double Ptr buffer)[0])
+	? Win32 And Ptr64
+		Case "Float64"   value = String((Float  Ptr buffer)[0]) + "," + ..
+		                         String((Float  Ptr buffer)[1])
+		Case "Float128"  value = String((Float  Ptr buffer)[0]) + "," + ..
+		                         String((Float  Ptr buffer)[1]) + "," + ..
+		                         String((Float  Ptr buffer)[2]) + "," + ..
+		                         String((Float  Ptr buffer)[3])
+		Case "Double128" value = String((Double Ptr buffer)[0]) + "," + ..
+		                         String((Double Ptr buffer)[1])
+		Case "Int128"    value = String((Int    Ptr buffer)[0]) + "," + ..
+		                         String((Int    Ptr buffer)[1]) + "," + ..
+		                         String((Int    Ptr buffer)[2]) + "," + ..
+		                         String((Int    Ptr buffer)[3])
+	? Win32	
+		Case "WParam"    value = String((WParam Ptr buffer)[0])
+		Case "LParam"    value = String((LParam Ptr buffer)[0])
+		Default
+			MemFree buffer
+			result :+ derefSymbol + derefFailure
+			Return result
 	EndSelect
+	MemFree buffer
+	result :+ derefSymbol + "{" + value + "}"
+	?
+	
 	
-	Return ""
+	Return result
 EndFunction
-End Rem
 
 'Function DebugScopeDecls:Int Ptr[]( scope:Int Ptr )
 '	Local n,p:Int Ptr=scope+DEBUGSCOPE_DECLS