From 24d973001c1a9938d57b380b4fcfb4f7bb65e0ea Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 15 May 2015 15:04:11 +0000 Subject: [PATCH] fpdebug: fix pause on win32 git-svn-id: trunk@49029 - --- components/fpdebug/fpdbgwinclasses.pas | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/components/fpdebug/fpdbgwinclasses.pas b/components/fpdebug/fpdbgwinclasses.pas index 613d2265d5..c3173c2b8c 100644 --- a/components/fpdebug/fpdbgwinclasses.pas +++ b/components/fpdebug/fpdbgwinclasses.pas @@ -904,14 +904,48 @@ begin end; function DebugBreakProcess(Process:HANDLE): WINBOOL; external 'kernel32' name 'DebugBreakProcess'; +var + DebugBreakAddr: Pointer = nil; + _CreateRemoteThread: function(hProcess: THandle; lpThreadAttributes: Pointer; dwStackSize: DWORD; lpStartAddress: TFNThreadStartRoutine; lpParameter: Pointer; dwCreationFlags: DWORD; var lpThreadId: DWORD): THandle; stdcall = nil; + +procedure InitWin32; +var + hMod: THandle; +begin + // Check if we already are initialized + if DebugBreakAddr <> nil then Exit; + + // normally you would load a lib, but since kernel32 is + // always loaded we can use this (and we don't have to free it + hMod := GetModuleHandle(kernel32); + if hMod = 0 then Exit; //???? + + DebugBreakAddr := GetProcAddress(hMod, 'DebugBreak'); + Pointer(_CreateRemoteThread) := GetProcAddress(hMod, 'CreateRemoteThread'); +end; function TDbgWinProcess.Pause: boolean; var hndl: Handle; + hThread: THandle; + NewThreadId: Cardinal; begin + //hndl := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ, False, TargetPID); hndl := OpenProcess(PROCESS_ALL_ACCESS, false, ProcessID); FPauseRequested:=true; result := DebugBreakProcess(hndl); + if not Result then begin + DebugLn(['pause failed(1) ', GetLastError]); + InitWin32; + hThread := _CreateRemoteThread(hndl, nil, 0, DebugBreakAddr, nil, 0, NewThreadId); + if hThread = 0 then begin + DebugLn(['pause failed(2) ', GetLastError]); + end + else begin + Result := True; + CloseHandle(hThread); + end; + end; CloseHandle(hndl); end;