// Block and wait for the next debug event from the debuggee process. BOOL DbgTransportPipeline::WaitForDebugEvent(DEBUG_EVENT * pEvent, DWORD dwTimeout, CordbProcess * pProcess) { if (!IsTransportRunning()) { return FALSE; } // We need to wait for a debug event from the transport and the process termination event. // On Windows, process termination is communicated via a debug event as well, but that's not true for // the Mac debugging transport. DWORD cWaitSet = 2; HANDLE rghWaitSet[2]; rghWaitSet[0] = m_pTransport->GetDebugEventReadyEvent(); rghWaitSet[1] = m_hProcess; DWORD dwRet = ::WaitForMultipleObjectsEx(cWaitSet, rghWaitSet, FALSE, dwTimeout, FALSE); if (dwRet == WAIT_OBJECT_0) { // The Mac debugging transport actually transmits IPC events and not debug events. // We need to convert the IPC event to a debug event and pass it back to the caller. m_pTransport->GetNextEvent(m_pIPCEvent, CorDBIPC_BUFFER_SIZE); pEvent->dwProcessId = m_pIPCEvent->processId; _ASSERTE(m_dwProcessId == m_pIPCEvent->processId); // We are supposed to return a thread ID in the DEBUG_EVENT back to our caller. // However, we don't actually store the thread ID in the DebuggerIPCEvent anymore. Instead, // we just get a VMPTR_Thread, and so we need to find the thread ID associated with the VMPTR_Thread. pEvent->dwThreadId = 0; HRESULT hr = S_OK; EX_TRY { if (!m_pIPCEvent->vmThread.IsNull()) { pEvent->dwThreadId = pProcess->GetDAC()->TryGetVolatileOSThreadID(m_pIPCEvent->vmThread); } } EX_CATCH_HRESULT(hr); if (FAILED(hr)) { return FALSE; } // The Windows implementation stores the target address of the IPC event in the debug event. // We can do that for Mac debugging, but that would require the caller to do another cross-machine // ReadProcessMemory(). Since we have all the data in-proc already, we just store a local address. // // @dbgtodo Mac - We are using -1 as a dummy base address right now. // Currently Mac remote debugging doesn't really support multi-instance. InitEventForDebuggerNotification(pEvent, PTR_TO_CORDB_ADDRESS(reinterpret_cast<LPVOID>(-1)), m_pIPCEvent); return TRUE; }
// Get the reply from the LS for a previously sent IPC event. // // virtual HRESULT RemoteEventChannel::GetReplyFromLeftSide(DebuggerIPCEvent * pReplyEvent, SIZE_T eventSize) { // Delegate to the transport. m_pTransport->GetNextEvent(pReplyEvent, (DWORD)eventSize); return S_OK; }