mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 09:22:58 +00:00
- Fix a major bug while closing a process that was debugging another process, which would cause a bugcheck because it tried to kill itself while it was being killed -- instead, it should try killing the debuggee! fixes the bug that arty and I fought about when he said "process killing seems broken" and tried to add delayed-object-closing. Patch by Alex Ionescu.
- Remove a leftover from kernel32 which assumed that if "BeingDebugged" was TRUE, the library was being tested on an XP machine. svn path=/trunk/; revision=33870
This commit is contained in:
parent
edc9924731
commit
3eb4e85097
2 changed files with 9 additions and 57 deletions
|
@ -257,42 +257,6 @@ DllMain(HANDLE hDll,
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
|
|
||||||
#ifdef _M_IX86
|
|
||||||
/* OK, yes, this is really retarded but it works for now */
|
|
||||||
InWindows = NtCurrentPeb()->BeingDebugged;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* CreateProcess will run in the real kernel32 and it will write
|
|
||||||
* its own BaseProcessStartThunk EIP in the CONTEXT that ZwContinue
|
|
||||||
* will get. We'll be first called by Ldr while initializing, and we'll
|
|
||||||
* be wrapped in 3 layers of SEH, followed by two frames, finally
|
|
||||||
* followed by our CONTEXT on the stack. We'll modify the EIP in it
|
|
||||||
* to match the correct one (our own) and then everything works.
|
|
||||||
* Tested on XP and 2K3, probably doesn't work in 2K.
|
|
||||||
*/
|
|
||||||
if (InWindows)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Due to yet another bug in how Windows handles .local, LDR will
|
|
||||||
* actually end up loading us twice. The second time will be the
|
|
||||||
* "official" load, at a totally different address. It will be,
|
|
||||||
* it will be at -that- address that all the APIs will be called.
|
|
||||||
* However, that address is dynamic while this one will be static,
|
|
||||||
* so we'll do initilization with this one. Plus, at this one,
|
|
||||||
* we know exactly that we're within 3 SEH layers.
|
|
||||||
*/
|
|
||||||
if (hDll == (HANDLE)0x7c800000)
|
|
||||||
{
|
|
||||||
PULONG Eip;
|
|
||||||
__debugbreak();
|
|
||||||
Eip = (PULONG)*(PULONG)*(PULONG)NtCurrentTeb()->Tib.ExceptionList +
|
|
||||||
0x9 +
|
|
||||||
FIELD_OFFSET(CONTEXT, Eip) / sizeof(ULONG);
|
|
||||||
*Eip = (ULONG)BaseProcessStartThunk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Don't bother us for each thread */
|
/* Don't bother us for each thread */
|
||||||
LdrDisableThreadCalloutsForDll((PVOID)hDll);
|
LdrDisableThreadCalloutsForDll((PVOID)hDll);
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ DbgkpQueueMessage(IN PEPROCESS Process,
|
||||||
KeInitializeEvent(&DebugEvent->ContinueEvent, SynchronizationEvent, FALSE);
|
KeInitializeEvent(&DebugEvent->ContinueEvent, SynchronizationEvent, FALSE);
|
||||||
DebugEvent->Process = Process;
|
DebugEvent->Process = Process;
|
||||||
DebugEvent->Thread = Thread;
|
DebugEvent->Thread = Thread;
|
||||||
RtlCopyMemory(&DebugEvent->ApiMsg, Message, sizeof(DBGKM_MSG));
|
DebugEvent->ApiMsg = *Message;
|
||||||
DebugEvent->ClientId = Thread->Cid;
|
DebugEvent->ClientId = Thread->Cid;
|
||||||
|
|
||||||
/* Check if we have a port object */
|
/* Check if we have a port object */
|
||||||
|
@ -176,7 +176,7 @@ DbgkpQueueMessage(IN PEPROCESS Process,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
/* Copy API Message back */
|
/* Copy API Message back */
|
||||||
RtlCopyMemory(Message, &DebugEvent->ApiMsg, sizeof(DBGKM_MSG));
|
*Message = DebugEvent->ApiMsg;
|
||||||
|
|
||||||
/* Set return status */
|
/* Set return status */
|
||||||
Status = DebugEvent->Status;
|
Status = DebugEvent->Status;
|
||||||
|
@ -1079,8 +1079,6 @@ DbgkpCloseObject(IN PEPROCESS OwnerProcess OPTIONAL,
|
||||||
DBGKTRACE(DBGK_OBJECT_DEBUG, "OwnerProcess: %p DebugObject: %p\n",
|
DBGKTRACE(DBGK_OBJECT_DEBUG, "OwnerProcess: %p DebugObject: %p\n",
|
||||||
OwnerProcess, DebugObject);
|
OwnerProcess, DebugObject);
|
||||||
|
|
||||||
DPRINT("APC DISABLE: %d\n", ((PETHREAD)KeGetCurrentThread())->Tcb.CombinedApcDisable);
|
|
||||||
|
|
||||||
/* If this isn't the last handle, do nothing */
|
/* If this isn't the last handle, do nothing */
|
||||||
if (SystemHandleCount > 1) return;
|
if (SystemHandleCount > 1) return;
|
||||||
|
|
||||||
|
@ -1124,13 +1122,13 @@ DbgkpCloseObject(IN PEPROCESS OwnerProcess OPTIONAL,
|
||||||
if (DebugPortCleared)
|
if (DebugPortCleared)
|
||||||
{
|
{
|
||||||
/* Mark this in the PEB */
|
/* Mark this in the PEB */
|
||||||
DbgkpMarkProcessPeb(OwnerProcess);
|
DbgkpMarkProcessPeb(Process);
|
||||||
|
|
||||||
/* Check if we terminate on exit */
|
/* Check if we terminate on exit */
|
||||||
if (DebugObject->KillProcessOnExit)
|
if (DebugObject->KillProcessOnExit)
|
||||||
{
|
{
|
||||||
/* Terminate the process */
|
/* Terminate the process */
|
||||||
PsTerminateProcess(OwnerProcess, STATUS_DEBUGGER_INACTIVE);
|
PsTerminateProcess(Process, STATUS_DEBUGGER_INACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dereference the debug object */
|
/* Dereference the debug object */
|
||||||
|
@ -1192,6 +1190,7 @@ DbgkpSetProcessDebugObject(IN PEPROCESS Process,
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Acquire the global lock */
|
/* Acquire the global lock */
|
||||||
|
ThreadScan:
|
||||||
GlobalHeld = TRUE;
|
GlobalHeld = TRUE;
|
||||||
ExAcquireFastMutex(&DbgkpProcessDebugPortMutex);
|
ExAcquireFastMutex(&DbgkpProcessDebugPortMutex);
|
||||||
|
|
||||||
|
@ -1203,7 +1202,6 @@ DbgkpSetProcessDebugObject(IN PEPROCESS Process,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadScan:
|
|
||||||
/* Otherwise, set the port and reference the thread */
|
/* Otherwise, set the port and reference the thread */
|
||||||
Process->DebugPort = DebugObject;
|
Process->DebugPort = DebugObject;
|
||||||
ObReferenceObject(LastThread);
|
ObReferenceObject(LastThread);
|
||||||
|
@ -1235,14 +1233,7 @@ ThreadScan:
|
||||||
{
|
{
|
||||||
/* Dereference the first thread and re-acquire the lock */
|
/* Dereference the first thread and re-acquire the lock */
|
||||||
ObDereferenceObject(FirstThread);
|
ObDereferenceObject(FirstThread);
|
||||||
GlobalHeld = TRUE;
|
goto ThreadScan;
|
||||||
ExAcquireFastMutex(&DbgkpProcessDebugPortMutex);
|
|
||||||
|
|
||||||
/* Check if we should loop again */
|
|
||||||
if (!Process->DebugPort) goto ThreadScan;
|
|
||||||
|
|
||||||
/* Otherwise, we already have a port */
|
|
||||||
Status = STATUS_PORT_ALREADY_SET;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1265,8 +1256,7 @@ ThreadScan:
|
||||||
{
|
{
|
||||||
/* Set the process flags */
|
/* Set the process flags */
|
||||||
InterlockedOr((PLONG)&Process->Flags,
|
InterlockedOr((PLONG)&Process->Flags,
|
||||||
PSF_NO_DEBUG_INHERIT_BIT |
|
PSF_NO_DEBUG_INHERIT_BIT | PSF_CREATE_REPORTED_BIT);
|
||||||
PSF_CREATE_REPORTED_BIT);
|
|
||||||
|
|
||||||
/* Reference the debug object */
|
/* Reference the debug object */
|
||||||
ObDereferenceObject(DebugObject);
|
ObDereferenceObject(DebugObject);
|
||||||
|
@ -2012,7 +2002,7 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle,
|
||||||
StartTime = NewTime;
|
StartTime = NewTime;
|
||||||
|
|
||||||
/* Check if we've timed out */
|
/* Check if we've timed out */
|
||||||
if (SafeTimeOut.QuadPart > 0)
|
if (SafeTimeOut.QuadPart >= 0)
|
||||||
{
|
{
|
||||||
/* We have, break out of the loop */
|
/* We have, break out of the loop */
|
||||||
Status = STATUS_TIMEOUT;
|
Status = STATUS_TIMEOUT;
|
||||||
|
@ -2037,9 +2027,7 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle,
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
/* Return our wait state change structure */
|
/* Return our wait state change structure */
|
||||||
RtlCopyMemory(StateChange,
|
*StateChange = WaitStateChange;
|
||||||
&WaitStateChange,
|
|
||||||
sizeof(DBGUI_WAIT_STATE_CHANGE));
|
|
||||||
}
|
}
|
||||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue