summaryrefslogtreecommitdiff
path: root/src/debug/di
diff options
context:
space:
mode:
authorOded Hanson <odhanson@microsoft.com>2018-12-12 02:42:17 +0200
committerJan Vorlicek <janvorli@microsoft.com>2018-12-12 01:42:17 +0100
commit5b687cf51745790ff02c2de3f9f992ddc94bfae1 (patch)
tree0e6b24b35e3482f6e0244cf2f724331c807faef6 /src/debug/di
parentfc90b973bf806410b836541a3d0af2293152c787 (diff)
downloadcoreclr-5b687cf51745790ff02c2de3f9f992ddc94bfae1.tar.gz
coreclr-5b687cf51745790ff02c2de3f9f992ddc94bfae1.tar.bz2
coreclr-5b687cf51745790ff02c2de3f9f992ddc94bfae1.zip
Added support for debugging a sandboxed app on Mac (#21068)
* Fixed bug in StackString where the size is not initialized correctly to STACK_COUNT * Added CharString and WCharString template classes and a generic CharStringFromLPCWSTR method * Added support for debugging a sandboxed app on Mac This change fixes the usage of IPC while debugging while running in a sandbox. When running in a sandbox, the temporary folder for each process will be different. Thus the pipes being created in TwoWayPipe right now would be created in different directories in the debugger process and the process being debugged. This change configures the folder to be used based on the application group ID that the sandboxed app belongs to. For the same reasons, the names sempahores being used to synchronize the debugger attach need to be prefixed with the application group ID. This change was abit more involved since the name of the semaphore is limited to 31 characters, so we had to encode the semaphore names differently to make them shorter. Last, new APIs to the debugger shim were added to support this new feature. This change only handles the runtime side and the dbgshim. An additional change to vsdbg needs to be done to use the new APIs. fixes #21066 * Fixed build breaks on non Mac Unix platforms * Fixed usage of gApplicationGroupId in non apple environments * Fixed bug in semaphore names * Got rid of usage of StackString * Made PAL_GetApplicationGroupId Apple specific * Added comment about pragma pack * Fixed comment * Added exported symbols * Duplicated applicationGroupId so it can be used from another thread during register complete callback * Renamed BitNum2ByteNum to GetExtraEncodedAreaSize to make intent clearer * Fixed nit comments * Removed redundant changes in StackString * Fixed windows build break * Fixed compilation switch from __APPLE to __APPLE__ * Added missing exports
Diffstat (limited to 'src/debug/di')
-rw-r--r--src/debug/di/cordb.cpp38
-rw-r--r--src/debug/di/dbgtransportmanager.cpp9
-rw-r--r--src/debug/di/dbgtransportmanager.h11
-rw-r--r--src/debug/di/dbgtransportpipeline.cpp12
-rw-r--r--src/debug/di/eventchannel.h2
-rw-r--r--src/debug/di/eventredirectionpipeline.cpp6
-rw-r--r--src/debug/di/eventredirectionpipeline.h2
-rw-r--r--src/debug/di/localeventchannel.cpp2
-rw-r--r--src/debug/di/nativepipeline.h2
-rw-r--r--src/debug/di/process.cpp50
-rw-r--r--src/debug/di/remoteeventchannel.cpp4
-rw-r--r--src/debug/di/rsmain.cpp61
-rw-r--r--src/debug/di/rspriv.h38
-rw-r--r--src/debug/di/shimdatatarget.h2
-rw-r--r--src/debug/di/shimlocaldatatarget.cpp6
-rw-r--r--src/debug/di/shimpriv.h4
-rw-r--r--src/debug/di/shimprocess.cpp6
-rw-r--r--src/debug/di/shimremotedatatarget.cpp6
-rw-r--r--src/debug/di/windowspipeline.cpp10
19 files changed, 176 insertions, 95 deletions
diff --git a/src/debug/di/cordb.cpp b/src/debug/di/cordb.cpp
index ae74c34b54..4febb5125a 100644
--- a/src/debug/di/cordb.cpp
+++ b/src/debug/di/cordb.cpp
@@ -87,9 +87,6 @@ HINSTANCE g_hInst; // Instance handle to this piece of code
// This was used by the Mix07 release of Silverlight, but it didn't properly support versioning
// and we no longer support it's debugger protocol so we require callers to use
// code:CoreCLRCreateCordbObject instead.
-//
-// This is also still used on Mac - multi-instance debugging and debugger
-// versioning isn't really implemented there yet. This probably needs to change.
//*****************************************************************************
STDAPI CreateCordbObject(int iDebuggerVersion, IUnknown ** ppCordb)
{
@@ -112,24 +109,28 @@ STDAPI CreateCordbObject(int iDebuggerVersion, IUnknown ** ppCordb)
return E_INVALIDARG;
}
- return Cordb::CreateObject((CorDebugInterfaceVersion)iDebuggerVersion, IID_ICorDebug, (void **) ppCordb);
+ return Cordb::CreateObject(
+ (CorDebugInterfaceVersion)iDebuggerVersion, ProcessDescriptor::UNINITIALIZED_PID, /*lpApplicationGroupId*/ NULL, IID_ICorDebug, (void **) ppCordb);
}
//
// Public API.
-// Telesto Creation path - only way to debug multi-instance.
-// This supercedes code:CreateCordbObject
+// Telesto Creation path with Mac sandbox support - only way to debug a sandboxed application on Mac.
+// This supercedes code:CoreCLRCreateCordbObject
//
// Arguments:
// iDebuggerVersion - version of ICorDebug interfaces that the debugger is requesting
// pid - pid of debuggee that we're attaching to.
+// lpApplicationGroupId - A string representing the application group ID of a sandboxed
+// process running in Mac. Pass NULL if the process is not
+// running in a sandbox and other platforms.
// hmodTargetCLR - module handle to clr in target pid that we're attaching to.
// ppCordb - (out) the resulting ICorDebug object.
//
// Notes:
// It's inconsistent that this takes a (handle, pid) but hands back an ICorDebug instead of an ICorDebugProcess.
// Callers will need to call *ppCordb->DebugActiveProcess(pid).
-STDAPI CoreCLRCreateCordbObject(int iDebuggerVersion, DWORD pid, HMODULE hmodTargetCLR, IUnknown ** ppCordb)
+STDAPI CoreCLRCreateCordbObjectEx(int iDebuggerVersion, DWORD pid, LPCWSTR lpApplicationGroupId, HMODULE hmodTargetCLR, IUnknown ** ppCordb)
{
if (ppCordb == NULL)
{
@@ -145,10 +146,8 @@ STDAPI CoreCLRCreateCordbObject(int iDebuggerVersion, DWORD pid, HMODULE hmodTar
// Create the ICorDebug object
//
RSExtSmartPtr<ICorDebug> pCordb;
- Cordb::CreateObject((CorDebugInterfaceVersion)iDebuggerVersion, IID_ICorDebug, (void **) &pCordb);
+ Cordb::CreateObject((CorDebugInterfaceVersion)iDebuggerVersion, pid, lpApplicationGroupId, IID_ICorDebug, (void **) &pCordb);
- // @dbgtodo - we should stash the pid and validate that it's the same pid we're attaching to in ICorDebug::DebugActiveProcess.
-
//
// Associate it with the target instance
//
@@ -167,6 +166,25 @@ STDAPI CoreCLRCreateCordbObject(int iDebuggerVersion, DWORD pid, HMODULE hmodTar
return hr;
}
+//
+// Public API.
+// Telesto Creation path - only way to debug multi-instance.
+// This supercedes code:CreateCordbObject
+//
+// Arguments:
+// iDebuggerVersion - version of ICorDebug interfaces that the debugger is requesting
+// pid - pid of debuggee that we're attaching to.
+// hmodTargetCLR - module handle to clr in target pid that we're attaching to.
+// ppCordb - (out) the resulting ICorDebug object.
+//
+// Notes:
+// It's inconsistent that this takes a (handle, pid) but hands back an ICorDebug instead of an ICorDebugProcess.
+// Callers will need to call *ppCordb->DebugActiveProcess(pid).
+STDAPI CoreCLRCreateCordbObject(int iDebuggerVersion, DWORD pid, HMODULE hmodTargetCLR, IUnknown ** ppCordb)
+{
+ return CoreCLRCreateCordbObjectEx(iDebuggerVersion, pid, NULL, hmodTargetCLR, ppCordb);
+}
+
diff --git a/src/debug/di/dbgtransportmanager.cpp b/src/debug/di/dbgtransportmanager.cpp
index 8c1079dc33..b897547057 100644
--- a/src/debug/di/dbgtransportmanager.cpp
+++ b/src/debug/di/dbgtransportmanager.cpp
@@ -47,12 +47,13 @@ void DbgTransportTarget::Shutdown()
// Given a PID attempt to find or create a DbgTransportSession instance to manage a connection to a runtime in
// that process. Returns E_UNEXPECTED if the process can't be found. Also returns a handle that can be waited
// on for process termination.
-HRESULT DbgTransportTarget::GetTransportForProcess(DWORD dwPID,
- DbgTransportSession **ppTransport,
- HANDLE *phProcessHandle)
+HRESULT DbgTransportTarget::GetTransportForProcess(const ProcessDescriptor *pProcessDescriptor,
+ DbgTransportSession **ppTransport,
+ HANDLE *phProcessHandle)
{
RSLockHolder lock(&m_sLock);
HRESULT hr = S_OK;
+ DWORD dwPID = pProcessDescriptor->m_Pid;
ProcessEntry *entry = LocateProcessByPID(dwPID);
@@ -78,7 +79,7 @@ HRESULT DbgTransportTarget::GetTransportForProcess(DWORD dwPID
}
// Initialize it (this immediately starts the remote connection process).
- hr = transport->Init(dwPID, hProcess);
+ hr = transport->Init(*pProcessDescriptor, hProcess);
if (FAILED(hr))
{
transport->Shutdown();
diff --git a/src/debug/di/dbgtransportmanager.h b/src/debug/di/dbgtransportmanager.h
index 3a8013eae8..e1aeaa4623 100644
--- a/src/debug/di/dbgtransportmanager.h
+++ b/src/debug/di/dbgtransportmanager.h
@@ -20,13 +20,16 @@
// Usual lifecycle looks like this:
// Debug a new process:
// * CreateProcess(&pid)
-// * GetTransportForProcess(pid, &transport)
+// * On Mac, Optionally obtain an application group ID from a user
+// * Create a ProcessDescriptor pd
+// * GetTransportForProcess(&pd, &transport)
// * ReleaseTransport(transport)
// * KillProcess(pid)
// Attach to an existing process:
-// * Obtain pid from a user
-// * GetTransportForProcess(pid, &transport)
+// * Obtain pid (and optionally application group ID on Mac) from a user
+// * Create a ProcessDescriptor pd
+// * GetTransportForProcess(&pd, &transport)
// * ReleaseTransport(transport)
class DbgTransportTarget
@@ -37,7 +40,7 @@ public:
// Given a PID attempt to find or create a DbgTransportSession instance to manage a connection to a
// runtime in that process. Returns E_UNEXPECTED if the process can't be found. Also returns a handle that
// can be waited on for process termination.
- HRESULT GetTransportForProcess(DWORD dwPID, DbgTransportSession **ppTransport, HANDLE *phProcessHandle);
+ HRESULT GetTransportForProcess(const ProcessDescriptor *pProcessDescriptor, DbgTransportSession **ppTransport, HANDLE *phProcessHandle);
// Give back a previously acquired transport (if nobody else is using the transport it will close down the
// connection at this point).
diff --git a/src/debug/di/dbgtransportpipeline.cpp b/src/debug/di/dbgtransportpipeline.cpp
index 88f6220c8e..645cf41987 100644
--- a/src/debug/di/dbgtransportpipeline.cpp
+++ b/src/debug/di/dbgtransportpipeline.cpp
@@ -91,7 +91,7 @@ public:
LPPROCESS_INFORMATION lpProcessInformation);
// Attach
- virtual HRESULT DebugActiveProcess(MachineInfo machineInfo, DWORD processId);
+ virtual HRESULT DebugActiveProcess(MachineInfo machineInfo, const ProcessDescriptor& processDescriptor);
// Detach
virtual HRESULT DebugActiveProcessStop(DWORD processId);
@@ -224,8 +224,10 @@ HRESULT DbgTransportPipeline::CreateProcessUnderDebugger(
if (SUCCEEDED(hr))
{
+ ProcessDescriptor processDescriptor = ProcessDescriptor::Create(lpProcessInformation->dwProcessId, NULL);
+
// Establish a connection to the actual runtime to be debugged.
- hr = m_pProxy->GetTransportForProcess(lpProcessInformation->dwProcessId,
+ hr = m_pProxy->GetTransportForProcess(&processDescriptor,
&m_pTransport,
&m_hProcess);
if (SUCCEEDED(hr))
@@ -283,7 +285,7 @@ HRESULT DbgTransportPipeline::CreateProcessUnderDebugger(
}
// Attach the debugger to this process.
-HRESULT DbgTransportPipeline::DebugActiveProcess(MachineInfo machineInfo, DWORD processId)
+HRESULT DbgTransportPipeline::DebugActiveProcess(MachineInfo machineInfo, const ProcessDescriptor& processDescriptor)
{
// INativeEventPipeline has a 1:1 relationship with CordbProcess.
_ASSERTE(!IsTransportRunning());
@@ -293,7 +295,7 @@ HRESULT DbgTransportPipeline::DebugActiveProcess(MachineInfo machineInfo, DWORD
m_pProxy = g_pDbgTransportTarget;
// Establish a connection to the actual runtime to be debugged.
- hr = m_pProxy->GetTransportForProcess(processId, &m_pTransport, &m_hProcess);
+ hr = m_pProxy->GetTransportForProcess(&processDescriptor, &m_pTransport, &m_hProcess);
if (SUCCEEDED(hr))
{
// TODO: Pass this timeout as a parameter all the way from debugger
@@ -313,7 +315,7 @@ HRESULT DbgTransportPipeline::DebugActiveProcess(MachineInfo machineInfo, DWORD
if (SUCCEEDED(hr))
{
- m_dwProcessId = processId;
+ m_dwProcessId = processDescriptor.m_Pid;
m_fRunning = TRUE;
}
else
diff --git a/src/debug/di/eventchannel.h b/src/debug/di/eventchannel.h
index 5a4ff23ea8..1739d7568e 100644
--- a/src/debug/di/eventchannel.h
+++ b/src/debug/di/eventchannel.h
@@ -257,7 +257,7 @@ public:
HRESULT NewEventChannelForThisPlatform(CORDB_ADDRESS pLeftSideDCB,
ICorDebugMutableDataTarget * pMutableDataTarget,
- DWORD dwProcessId,
+ const ProcessDescriptor * pProcessDescriptor,
MachineInfo machineInfo,
IEventChannel ** ppEventChannel);
diff --git a/src/debug/di/eventredirectionpipeline.cpp b/src/debug/di/eventredirectionpipeline.cpp
index 23405d643a..46c4997530 100644
--- a/src/debug/di/eventredirectionpipeline.cpp
+++ b/src/debug/di/eventredirectionpipeline.cpp
@@ -293,13 +293,13 @@ HRESULT EventRedirectionPipeline::CreateProcessUnderDebugger(
// Attach
-HRESULT EventRedirectionPipeline::DebugActiveProcess(MachineInfo machineInfo, DWORD processId)
+HRESULT EventRedirectionPipeline::DebugActiveProcess(MachineInfo machineInfo, const ProcessDescriptor& processDescriptor)
{
- m_dwProcessId = processId;
+ m_dwProcessId = processDescriptor.m_Pid;
// Use redirected pipeline
// Spin up debugger to attach to target.
- return AttachDebuggerToTarget(m_AttachParams.Value(), processId);
+ return AttachDebuggerToTarget(m_AttachParams.Value(), processDescriptor.m_Pid);
}
// Detach
diff --git a/src/debug/di/eventredirectionpipeline.h b/src/debug/di/eventredirectionpipeline.h
index 87549c1150..0da16175ca 100644
--- a/src/debug/di/eventredirectionpipeline.h
+++ b/src/debug/di/eventredirectionpipeline.h
@@ -59,7 +59,7 @@ public:
LPPROCESS_INFORMATION lpProcessInformation);
// Attach
- virtual HRESULT DebugActiveProcess(MachineInfo machineInfo, DWORD processId);
+ virtual HRESULT DebugActiveProcess(MachineInfo machineInfo, const ProcessDescriptor& processDescriptor);
// Detach
virtual HRESULT DebugActiveProcessStop(DWORD processId);
diff --git a/src/debug/di/localeventchannel.cpp b/src/debug/di/localeventchannel.cpp
index f31c46f7bb..e89affaf57 100644
--- a/src/debug/di/localeventchannel.cpp
+++ b/src/debug/di/localeventchannel.cpp
@@ -115,7 +115,7 @@ private:
// Allocate and return an old-style event channel object for this target platform.
HRESULT NewEventChannelForThisPlatform(CORDB_ADDRESS pLeftSideDCB,
ICorDebugMutableDataTarget * pMutableDataTarget,
- DWORD dwProcessId,
+ const ProcessDescriptor * pProcessDescriptor,
MachineInfo machineInfo,
IEventChannel ** ppEventChannel)
{
diff --git a/src/debug/di/nativepipeline.h b/src/debug/di/nativepipeline.h
index 9611d84404..5d22de9ed8 100644
--- a/src/debug/di/nativepipeline.h
+++ b/src/debug/di/nativepipeline.h
@@ -67,7 +67,7 @@ public:
LPPROCESS_INFORMATION lpProcessInformation) = 0;
// Attach
- virtual HRESULT DebugActiveProcess(MachineInfo machineInfo, DWORD processId) = 0;
+ virtual HRESULT DebugActiveProcess(MachineInfo machineInfo, const ProcessDescriptor& processDescriptor) = 0;
// Detach
virtual HRESULT DebugActiveProcessStop(DWORD processId) =0;
diff --git a/src/debug/di/process.cpp b/src/debug/di/process.cpp
index 01b474bde6..2343122317 100644
--- a/src/debug/di/process.cpp
+++ b/src/debug/di/process.cpp
@@ -100,12 +100,13 @@ STDAPI OpenVirtualProcessImpl(
// - there is no w32et thread (all threads are effectively an event thread)
// - the stop state is 'live', which corresponds to CordbProcess not knowing what
// its stop state really is (because that is now controlled by the shim).
+ ProcessDescriptor pd = ProcessDescriptor::CreateUninitialized();
IfFailThrow(CordbProcess::OpenVirtualProcess(
clrInstanceId,
pDataTarget, // takes a reference
hDacModule,
NULL, // Cordb
- (DWORD) 0, // 0 for V3 cases (pShim == NULL).
+ &pd, // 0 for V3 cases (pShim == NULL).
NULL, // no Shim in V3 cases
&pProcess));
@@ -820,7 +821,7 @@ HRESULT CordbProcess::OpenVirtualProcess(
IUnknown * pDataTarget,
HMODULE hDacModule,
Cordb* pCordb,
- DWORD dwProcessID,
+ const ProcessDescriptor * pProcessDescriptor,
ShimProcess * pShim,
CordbProcess ** ppProcess)
{
@@ -849,7 +850,7 @@ HRESULT CordbProcess::OpenVirtualProcess(
HRESULT hr = S_OK;
RSUnsafeExternalSmartPtr<CordbProcess> pProcess;
- pProcess.Assign(new (nothrow) CordbProcess(clrInstanceId, pDataTarget, hDacModule, pCordb, dwProcessID, pShim));
+ pProcess.Assign(new (nothrow) CordbProcess(clrInstanceId, pDataTarget, hDacModule, pCordb, pProcessDescriptor, pShim));
if (pProcess == NULL)
{
@@ -916,12 +917,13 @@ CordbProcess::CordbProcess(ULONG64 clrInstanceId,
IUnknown * pDataTarget,
HMODULE hDacModule,
Cordb * pCordb,
- DWORD dwProcessID,
+ const ProcessDescriptor * pProcessDescriptor,
ShimProcess * pShim)
- : CordbBase(NULL, dwProcessID, enumCordbProcess),
+ : CordbBase(NULL, pProcessDescriptor->m_Pid, enumCordbProcess),
m_fDoDelayedManagedAttached(false),
m_cordb(pCordb),
m_handle(NULL),
+ m_processDescriptor(*pProcessDescriptor),
m_detached(false),
m_uninitializedStop(false),
m_exiting(false),
@@ -1194,7 +1196,7 @@ HRESULT ShimProcess::CreateProcess(
HRESULT ShimProcess::DebugActiveProcess(
Cordb * pCordb,
ICorDebugRemoteTarget * pRemoteTarget,
- DWORD dwProcessID,
+ const ProcessDescriptor * pProcessDescriptor,
BOOL fWin32Attach
)
{
@@ -1216,7 +1218,7 @@ HRESULT ShimProcess::DebugActiveProcess(
// If this succeeds, new CordbProcess will add a ref to the ShimProcess
hr = pShim->GetWin32EventThread()->SendDebugActiveProcessEvent(pShim->GetMachineInfo(),
- dwProcessID,
+ pProcessDescriptor,
fWin32Attach == TRUE,
NULL);
IfFailThrow(hr);
@@ -3318,22 +3320,22 @@ HRESULT CordbProcess::GetID(DWORD *pdwProcessId)
*pdwProcessId = 0;
ThrowHR(E_NOTIMPL);
}
- *pdwProcessId = GetPid();
+ *pdwProcessId = GetProcessDescriptor()->m_Pid;
}
EX_CATCH_HRESULT(hr);
return hr;
}
-// Helper to get PID internally. We know we'll always succeed.
+// Helper to get process descriptor internally. We know we'll always succeed.
// This is more convient for internal callers since they can just use it as an expression
// without having to check HRESULTS.
-DWORD CordbProcess::GetPid()
+const ProcessDescriptor* CordbProcess::GetProcessDescriptor()
{
// This shouldn't be used in V3 paths, in which case it's set to 0. Only the shim should be
// calling this. Assert to catch anybody else.
- _ASSERTE(m_id != 0);
+ _ASSERTE(m_processDescriptor.IsInitialized());
- return (DWORD) m_id;
+ return &m_processDescriptor;
}
@@ -7517,7 +7519,7 @@ void CordbProcess::GetEventBlock(BOOL * pfBlockExists)
IfFailThrow(NewEventChannelForThisPlatform(pLeftSideDCB,
m_pMutableDataTarget,
- GetPid(),
+ GetProcessDescriptor(),
m_pShim->GetMachineInfo(),
&m_pEventChannel));
_ASSERTE(m_pEventChannel != NULL);
@@ -13809,9 +13811,10 @@ void CordbWin32EventThread::CreateProcess()
{
// Process ID is filled in after process is succesfully created.
DWORD dwProcessId = m_actionData.createData.lpProcessInformation->dwProcessId;
+ ProcessDescriptor pd = ProcessDescriptor::FromPid(dwProcessId);
RSUnsafeExternalSmartPtr<CordbProcess> pProcess;
- hr = m_pShim->InitializeDataTarget(dwProcessId);
+ hr = m_pShim->InitializeDataTarget(&pd);
if (SUCCEEDED(hr))
{
@@ -13819,7 +13822,7 @@ void CordbWin32EventThread::CreateProcess()
// OpenVirtualProcess. This will then connect to the first CLR
// loaded.
const ULONG64 cFirstClrLoaded = 0;
- hr = CordbProcess::OpenVirtualProcess(cFirstClrLoaded, m_pShim->GetDataTarget(), NULL, m_cordb, dwProcessId, m_pShim, &pProcess);
+ hr = CordbProcess::OpenVirtualProcess(cFirstClrLoaded, m_pShim->GetDataTarget(), NULL, m_cordb, &pd, m_pShim, &pProcess);
}
// Shouldn't happen on a create, only an attach
@@ -13866,7 +13869,7 @@ void CordbWin32EventThread::CreateProcess()
//
HRESULT CordbWin32EventThread::SendDebugActiveProcessEvent(
MachineInfo machineInfo,
- DWORD pid,
+ const ProcessDescriptor *pProcessDescriptor,
bool fWin32Attach,
CordbProcess *pProcess)
{
@@ -13875,7 +13878,7 @@ HRESULT CordbWin32EventThread::SendDebugActiveProcessEvent(
LockSendToWin32EventThreadMutex();
m_actionData.attachData.machineInfo = machineInfo;
- m_actionData.attachData.processId = pid;
+ m_actionData.attachData.processDescriptor = *pProcessDescriptor;
#if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
m_actionData.attachData.fWin32Attach = fWin32Attach;
#endif
@@ -14004,17 +14007,16 @@ void CordbWin32EventThread::AttachProcess()
HRESULT hr = S_OK;
- DWORD dwProcessId = m_actionData.attachData.processId;
+ ProcessDescriptor processDescriptor = m_actionData.attachData.processDescriptor;
bool fNativeAttachSucceeded = false;
-
// Always do OS attach to the target.
// By this point, the pid should be valid (because OpenProcess above), pending some race where the process just exited.
// The OS will enforce that only 1 debugger is attached.
// Common failure paths here would be: access denied, double-attach
{
hr = m_pNativePipeline->DebugActiveProcess(m_actionData.attachData.machineInfo,
- dwProcessId);
+ processDescriptor);
if (FAILED(hr))
{
goto LExit;
@@ -14023,7 +14025,7 @@ void CordbWin32EventThread::AttachProcess()
}
- hr = m_pShim->InitializeDataTarget(m_actionData.attachData.processId);
+ hr = m_pShim->InitializeDataTarget(&processDescriptor);
if (FAILED(hr))
{
goto LExit;
@@ -14034,7 +14036,7 @@ void CordbWin32EventThread::AttachProcess()
// loaded.
{
const ULONG64 cFirstClrLoaded = 0;
- hr = CordbProcess::OpenVirtualProcess(cFirstClrLoaded, m_pShim->GetDataTarget(), NULL, m_cordb, dwProcessId, m_pShim, &pProcess);
+ hr = CordbProcess::OpenVirtualProcess(cFirstClrLoaded, m_pShim->GetDataTarget(), NULL, m_cordb, &processDescriptor, m_pShim, &pProcess);
if (FAILED(hr))
{
goto LExit;
@@ -14081,7 +14083,7 @@ LExit:
// If we succeed to do a native-attach, but then failed elsewhere, try to native-detach.
if (fNativeAttachSucceeded)
{
- m_pNativePipeline->DebugActiveProcessStop(dwProcessId);
+ m_pNativePipeline->DebugActiveProcessStop(processDescriptor.m_Pid);
}
if (pProcess != NULL)
@@ -14509,7 +14511,7 @@ void CordbWin32EventThread::ExitProcess(bool fDetach)
// Eventually, the Debugger owns the detach pipeline, so this won't be necessary.
if (fDetach && (m_pProcess != NULL))
{
- HRESULT hr = m_pNativePipeline->DebugActiveProcessStop(m_pProcess->GetPid());
+ HRESULT hr = m_pNativePipeline->DebugActiveProcessStop(m_pProcess->GetProcessDescriptor()->m_Pid);
// We don't expect detach to fail (we check earlier for common conditions that
// may cause it to fail)
diff --git a/src/debug/di/remoteeventchannel.cpp b/src/debug/di/remoteeventchannel.cpp
index fc1d57a60f..ab810008a3 100644
--- a/src/debug/di/remoteeventchannel.cpp
+++ b/src/debug/di/remoteeventchannel.cpp
@@ -90,7 +90,7 @@ private:
// Allocate and return an old-style event channel object for this target platform.
HRESULT NewEventChannelForThisPlatform(CORDB_ADDRESS pLeftSideDCB,
ICorDebugMutableDataTarget * pMutableDataTarget,
- DWORD dwProcessId,
+ const ProcessDescriptor * pProcessDescriptor,
MachineInfo machineInfo,
IEventChannel ** ppEventChannel)
{
@@ -105,7 +105,7 @@ HRESULT NewEventChannelForThisPlatform(CORDB_ADDRESS pLeftSideDCB,
DbgTransportTarget * pProxy = g_pDbgTransportTarget;
DbgTransportSession * pTransport = NULL;
- hr = pProxy->GetTransportForProcess(dwProcessId, &pTransport, &hDummy);
+ hr = pProxy->GetTransportForProcess(pProcessDescriptor, &pTransport, &hDummy);
if (FAILED(hr))
{
goto Label_Exit;
diff --git a/src/debug/di/rsmain.cpp b/src/debug/di/rsmain.cpp
index 750cb1d8ee..f2f9b794c1 100644
--- a/src/debug/di/rsmain.cpp
+++ b/src/debug/di/rsmain.cpp
@@ -957,13 +957,17 @@ namespace
/* ------------------------------------------------------------------------- *
* Cordb class
* ------------------------------------------------------------------------- */
-
-
Cordb::Cordb(CorDebugInterfaceVersion iDebuggerVersion)
+ : Cordb(iDebuggerVersion, ProcessDescriptor::CreateUninitialized())
+{
+}
+
+Cordb::Cordb(CorDebugInterfaceVersion iDebuggerVersion, const ProcessDescriptor& pd)
: CordbBase(NULL, 0, enumCordb),
m_processes(11),
m_initialized(false),
- m_debuggerSpecifiedVersion(iDebuggerVersion)
+ m_debuggerSpecifiedVersion(iDebuggerVersion),
+ m_pd(pd)
#ifdef FEATURE_CORESYSTEM
,
m_targetCLR(0)
@@ -980,6 +984,10 @@ Cordb::Cordb(CorDebugInterfaceVersion iDebuggerVersion)
Cordb::~Cordb()
{
LOG((LF_CORDB, LL_INFO10, "C::~C Terminating Cordb object.\n"));
+ if (m_pd.m_ApplicationGroupId != NULL)
+ {
+ delete [] m_pd.m_ApplicationGroupId;
+ }
g_pRSDebuggingInfo->m_Cordb = NULL;
}
@@ -1819,6 +1827,12 @@ HRESULT Cordb::DebugActiveProcessCommon(ICorDebugRemoteTarget * pRemoteTarget,
ThrowHR(E_FAIL);
}
+ // Verify that given process ID, matches the process ID for which the object was created
+ if (m_pd.IsInitialized() && m_pd.m_Pid != dwProcessId)
+ {
+ ThrowHR(E_INVALIDARG);
+ }
+
// See the comment in Cordb::CreateProcess
_ASSERTE(CorDebugInvalidVersion != m_debuggerSpecifiedVersion);
@@ -1845,7 +1859,7 @@ HRESULT Cordb::DebugActiveProcessCommon(ICorDebugRemoteTarget * pRemoteTarget,
hr = ShimProcess::DebugActiveProcess(
this,
pRemoteTarget,
- dwProcessId,
+ &m_pd,
fWin32Attach == TRUE);
// If that worked, then there will be a process object...
@@ -2065,7 +2079,7 @@ void Cordb::EnsureCanLaunchOrAttach(BOOL fWin32DebuggingEnabled)
HRESULT Cordb::CreateObjectV1(REFIID id, void **object)
{
- return CreateObject(CorDebugVersion_1_0, id, object);
+ return CreateObject(CorDebugVersion_1_0, ProcessDescriptor::UNINITIALIZED_PID, NULL, id, object);
}
#if defined(FEATURE_DBGIPC_TRANSPORT_DI)
@@ -2073,21 +2087,52 @@ HRESULT Cordb::CreateObjectV1(REFIID id, void **object)
// same debug engine version as V2, though this may change in the future.
HRESULT Cordb::CreateObjectTelesto(REFIID id, void ** pObject)
{
- return CreateObject(CorDebugVersion_2_0, id, pObject);
+ return CreateObject(CorDebugVersion_2_0, ProcessDescriptor::UNINITIALIZED_PID, NULL, id, pObject);
}
#endif // FEATURE_DBGIPC_TRANSPORT_DI
// Static
// Used to create an instance for a ClassFactory (thus an external ref).
-HRESULT Cordb::CreateObject(CorDebugInterfaceVersion iDebuggerVersion, REFIID id, void **object)
+HRESULT Cordb::CreateObject(CorDebugInterfaceVersion iDebuggerVersion, DWORD pid, LPCWSTR lpApplicationGroupId, REFIID id, void **object)
{
if (id != IID_IUnknown && id != IID_ICorDebug)
return (E_NOINTERFACE);
- Cordb *db = new (nothrow) Cordb(iDebuggerVersion);
+ LPSTR applicationGroupId = NULL;
+ if (lpApplicationGroupId != NULL)
+ {
+ // Get length of target string
+ int cbMultiByte = WideCharToMultiByte(CP_ACP, 0, lpApplicationGroupId, -1, NULL, 0, NULL, NULL);
+ if (cbMultiByte == 0)
+ {
+ return E_FAIL;
+ }
+
+ applicationGroupId = new (nothrow) CHAR[cbMultiByte];
+ if (applicationGroupId == NULL)
+ {
+ return (E_OUTOFMEMORY);
+ }
+
+ /* Convert to ASCII */
+ cbMultiByte = WideCharToMultiByte(CP_ACP, 0, lpApplicationGroupId, -1, applicationGroupId, cbMultiByte, NULL, NULL);
+ if (cbMultiByte == 0)
+ {
+ return E_FAIL;
+ }
+ }
+
+ ProcessDescriptor pd = ProcessDescriptor::Create(pid, applicationGroupId);
+
+ Cordb *db = new (nothrow) Cordb(iDebuggerVersion, pd);
if (db == NULL)
+ {
+ if (applicationGroupId != NULL)
+ delete [] applicationGroupId;
+
return (E_OUTOFMEMORY);
+ }
*object = static_cast<ICorDebug*> (db);
db->ExternalAddRef();
diff --git a/src/debug/di/rspriv.h b/src/debug/di/rspriv.h
index 8b388ee684..fef79d80ca 100644
--- a/src/debug/di/rspriv.h
+++ b/src/debug/di/rspriv.h
@@ -44,6 +44,7 @@
struct MachineInfo;
+#include "processdescriptor.h"
#include "nativepipeline.h"
#include "stringcopyholder.h"
@@ -2226,7 +2227,7 @@ public:
#if defined(FEATURE_DBGIPC_TRANSPORT_DI)
static COM_METHOD CreateObjectTelesto(REFIID id, void ** pObject);
#endif // FEATURE_DBGIPC_TRANSPORT_DI
- static COM_METHOD CreateObject(CorDebugInterfaceVersion iDebuggerVersion, REFIID id, void **object);
+ static COM_METHOD CreateObject(CorDebugInterfaceVersion iDebuggerVersion, DWORD pid, LPCWSTR lpApplicationGroupId, REFIID id, void **object);
//-----------------------------------------------------------
// ICorDebugRemote
@@ -2297,6 +2298,9 @@ public:
CordbAppDomain *appDomain,
DebuggerIPCEvent* event);
+private:
+ Cordb(CorDebugInterfaceVersion iDebuggerVersion, const ProcessDescriptor& pd);
+
//-----------------------------------------------------------
// Data members
//-----------------------------------------------------------
@@ -2332,6 +2336,9 @@ private:
// This is the version of the ICorDebug APIs that the debugger believes it's consuming.
CorDebugInterfaceVersion m_debuggerSpecifiedVersion;
+ // Store information about the process to be debugged
+ ProcessDescriptor m_pd;
+
//Note - this code could be useful outside coresystem, but keeping the change localized
// because we are late in the win8 release
#ifdef FEATURE_CORESYSTEM
@@ -2804,8 +2811,8 @@ void DeleteIPCEventHelper(DebuggerIPCEvent *pDel);
class IProcessShimHooks
{
public:
- // Get the OS Process ID of the target.
- virtual DWORD GetPid() = 0;
+ // Get the OS Process descriptor of the target.
+ virtual const ProcessDescriptor* GetProcessDescriptor() = 0;
// Request a synchronization for attach.
// This essentially just sends an AsyncBreak to the left-side. Once the target is
@@ -2932,7 +2939,7 @@ class CordbProcess :
#endif
{
// Ctor is private. Use OpenVirtualProcess instead.
- CordbProcess(ULONG64 clrInstanceId, IUnknown * pDataTarget, HMODULE hDacModule, Cordb * pCordb, DWORD dwProcessID, ShimProcess * pShim);
+ CordbProcess(ULONG64 clrInstanceId, IUnknown * pDataTarget, HMODULE hDacModule, Cordb * pCordb, const ProcessDescriptor * pProcessDescriptor, ShimProcess * pShim);
public:
@@ -2952,7 +2959,7 @@ public:
IUnknown * pDataTarget,
HMODULE hDacModule,
Cordb * pCordb,
- DWORD dwProcessID,
+ const ProcessDescriptor * pProcessDescriptor,
ShimProcess * pShim,
CordbProcess ** ppProcess);
@@ -3266,8 +3273,8 @@ public:
bool IsThreadSuspendedOrHijacked(ICorDebugThread * pICorDebugThread);
- // Helper to get PID internally.
- DWORD GetPid();
+ // Helper to get ProcessDescriptor internally.
+ const ProcessDescriptor* GetProcessDescriptor();
HRESULT GetRuntimeOffsets();
@@ -3708,6 +3715,9 @@ private:
// wait on for process termination.
HANDLE m_handle;
+ // Process descriptor - holds PID and App group ID for Mac debugging
+ ProcessDescriptor m_processDescriptor;
+
public:
// Wrapper to get the OS process handle. This is unsafe because it breaks the data-target abstraction.
// The only things that need this should be calls to DuplicateHandle, and some shimming work.
@@ -10084,7 +10094,7 @@ public:
CorDebugCreateProcessFlags corDebugFlags);
HRESULT SendDebugActiveProcessEvent(MachineInfo machineInfo,
- DWORD pid,
+ const ProcessDescriptor *pProcessDescriptor,
bool fWin32Attach,
CordbProcess *pProcess);
@@ -10183,12 +10193,12 @@ private:
struct
{
- MachineInfo machineInfo;
- DWORD processId;
+ MachineInfo machineInfo;
+ ProcessDescriptor processDescriptor;
#if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
- bool fWin32Attach;
+ bool fWin32Attach;
#endif
- CordbProcess *pProcess;
+ CordbProcess *pProcess;
// Wrapper to determine if we're interop-debugging.
bool IsInteropDebugging()
@@ -10715,7 +10725,7 @@ private:
class CorpubProcess : public CordbCommonBase, public ICorPublishProcess
{
public:
- CorpubProcess(DWORD dwProcessId,
+ CorpubProcess(const ProcessDescriptor * pProcessDescriptor,
bool fManaged,
HANDLE hProcess,
HANDLE hMutex,
@@ -10774,7 +10784,7 @@ public:
bool IsExited();
public:
- DWORD m_dwProcessId;
+ ProcessDescriptor m_processDescriptor;
private:
bool m_fIsManaged;
diff --git a/src/debug/di/shimdatatarget.h b/src/debug/di/shimdatatarget.h
index adcbae8056..09e199d98e 100644
--- a/src/debug/di/shimdatatarget.h
+++ b/src/debug/di/shimdatatarget.h
@@ -126,7 +126,7 @@ protected:
//
HRESULT BuildPlatformSpecificDataTarget(MachineInfo machineInfo,
- DWORD processId,
+ const ProcessDescriptor * pProcessDescriptor,
ShimDataTarget ** ppDataTarget);
#endif // SHIMDATATARGET_H_
diff --git a/src/debug/di/shimlocaldatatarget.cpp b/src/debug/di/shimlocaldatatarget.cpp
index 36ea611af2..5057f46291 100644
--- a/src/debug/di/shimlocaldatatarget.cpp
+++ b/src/debug/di/shimlocaldatatarget.cpp
@@ -208,7 +208,7 @@ void ShimLocalDataTarget::Dispose()
//
HRESULT BuildPlatformSpecificDataTarget(MachineInfo machineInfo,
- DWORD processId,
+ const ProcessDescriptor * pProcessDescriptor,
ShimDataTarget ** ppDataTarget)
{
HRESULT hr = S_OK;
@@ -226,7 +226,7 @@ HRESULT BuildPlatformSpecificDataTarget(MachineInfo machineInfo,
PROCESS_VM_WRITE |
SYNCHRONIZE,
FALSE,
- processId);
+ pProcessDescriptor->m_Pid);
if (hProcess == NULL)
{
@@ -247,7 +247,7 @@ HRESULT BuildPlatformSpecificDataTarget(MachineInfo machineInfo,
{
goto Label_Exit;
}
- pLocalDataTarget = new (nothrow) ShimLocalDataTarget(processId, hProcess);
+ pLocalDataTarget = new (nothrow) ShimLocalDataTarget(pProcessDescriptor->m_Pid, hProcess);
if (pLocalDataTarget == NULL)
{
hr = E_OUTOFMEMORY;
diff --git a/src/debug/di/shimpriv.h b/src/debug/di/shimpriv.h
index 4c9eb7ab86..279feb978d 100644
--- a/src/debug/di/shimpriv.h
+++ b/src/debug/di/shimpriv.h
@@ -358,7 +358,7 @@ public:
// 3. Create OS-debugging pipeline. This establishes the physical OS process and gets us a pid/handle
// 4. pShim->InitializeDataTarget - this creates a reader/writer abstraction around the OS process.
// 5. pShim->SetProcess() - this connects the Shim to the ICDProcess object.
- HRESULT InitializeDataTarget(DWORD processId);
+ HRESULT InitializeDataTarget(const ProcessDescriptor * pProcessDescriptor);
void SetProcess(ICorDebugProcess * pProcess);
//-----------------------------------------------------------
@@ -384,7 +384,7 @@ public:
static HRESULT DebugActiveProcess(
Cordb * pCordb,
ICorDebugRemoteTarget * pRemoteTarget,
- DWORD pid,
+ const ProcessDescriptor * pProcessDescriptor,
BOOL win32Attach
);
diff --git a/src/debug/di/shimprocess.cpp b/src/debug/di/shimprocess.cpp
index 684173abca..b45bbe4ff4 100644
--- a/src/debug/di/shimprocess.cpp
+++ b/src/debug/di/shimprocess.cpp
@@ -132,7 +132,7 @@ void ShimProcess::SetProcess(ICorDebugProcess * pProcess)
if (pProcess != NULL)
{
// Verify that DataTarget + new process have the same pid?
- _ASSERTE(m_pProcess->GetPid() == m_pLiveDataTarget->GetPid());
+ _ASSERTE(m_pProcess->GetProcessDescriptor()->m_Pid == m_pLiveDataTarget->GetPid());
}
}
@@ -152,12 +152,12 @@ void ShimProcess::SetProcess(ICorDebugProcess * pProcess)
// Notes:
// Only call this once, during the initialization dance.
//
-HRESULT ShimProcess::InitializeDataTarget(DWORD processId)
+HRESULT ShimProcess::InitializeDataTarget(const ProcessDescriptor * pProcessDescriptor)
{
_ASSERTE(m_pLiveDataTarget == NULL);
- HRESULT hr = BuildPlatformSpecificDataTarget(GetMachineInfo(), processId, &m_pLiveDataTarget);
+ HRESULT hr = BuildPlatformSpecificDataTarget(GetMachineInfo(), pProcessDescriptor, &m_pLiveDataTarget);
if (FAILED(hr))
{
_ASSERTE(m_pLiveDataTarget == NULL);
diff --git a/src/debug/di/shimremotedatatarget.cpp b/src/debug/di/shimremotedatatarget.cpp
index f971b0d65a..7e6b8375ee 100644
--- a/src/debug/di/shimremotedatatarget.cpp
+++ b/src/debug/di/shimremotedatatarget.cpp
@@ -154,7 +154,7 @@ void ShimRemoteDataTarget::Dispose()
//
HRESULT BuildPlatformSpecificDataTarget(MachineInfo machineInfo,
- DWORD processId,
+ const ProcessDescriptor * pProcessDescriptor,
ShimDataTarget ** ppDataTarget)
{
HandleHolder hDummy;
@@ -164,7 +164,7 @@ HRESULT BuildPlatformSpecificDataTarget(MachineInfo machineInfo,
DbgTransportTarget * pProxy = g_pDbgTransportTarget;
DbgTransportSession * pTransport = NULL;
- hr = pProxy->GetTransportForProcess(processId, &pTransport, &hDummy);
+ hr = pProxy->GetTransportForProcess(pProcessDescriptor, &pTransport, &hDummy);
if (FAILED(hr))
{
goto Label_Exit;
@@ -176,7 +176,7 @@ HRESULT BuildPlatformSpecificDataTarget(MachineInfo machineInfo,
goto Label_Exit;
}
- pRemoteDataTarget = new (nothrow) ShimRemoteDataTarget(processId, pProxy, pTransport);
+ pRemoteDataTarget = new (nothrow) ShimRemoteDataTarget(pProcessDescriptor->m_Pid, pProxy, pTransport);
if (pRemoteDataTarget == NULL)
{
hr = E_OUTOFMEMORY;
diff --git a/src/debug/di/windowspipeline.cpp b/src/debug/di/windowspipeline.cpp
index c3050e3290..6e58f0be15 100644
--- a/src/debug/di/windowspipeline.cpp
+++ b/src/debug/di/windowspipeline.cpp
@@ -74,7 +74,7 @@ public:
LPPROCESS_INFORMATION lpProcessInformation);
// Attach
- virtual HRESULT DebugActiveProcess(MachineInfo machineInfo, DWORD processId);
+ virtual HRESULT DebugActiveProcess(MachineInfo machineInfo, const ProcessDescriptor& processDescriptor);
// Detach
virtual HRESULT DebugActiveProcessStop(DWORD processId);
@@ -205,15 +205,15 @@ HRESULT WindowsNativePipeline::CreateProcessUnderDebugger(
}
// Attach the debugger to this process.
-HRESULT WindowsNativePipeline::DebugActiveProcess(MachineInfo machineInfo, DWORD processId)
+HRESULT WindowsNativePipeline::DebugActiveProcess(MachineInfo machineInfo, const ProcessDescriptor& processDescriptor)
{
HRESULT hr = E_FAIL;
- BOOL ret = ::DebugActiveProcess(processId);
+ BOOL ret = ::DebugActiveProcess(processDescriptor.m_Pid);
if (ret)
{
hr = S_OK;
- m_dwProcessId = processId;
+ m_dwProcessId = processDescriptor.m_Pid;
UpdateDebugSetProcessKillOnExit();
}
else
@@ -233,7 +233,7 @@ HRESULT WindowsNativePipeline::DebugActiveProcess(MachineInfo machineInfo, DWORD
// attached. But I think it's better to only return the specific error code if we know for sure
// the case is true.
BOOL fIsDebuggerPresent = FALSE;
- if (SUCCEEDED(IsRemoteDebuggerPresent(processId, &fIsDebuggerPresent)))
+ if (SUCCEEDED(IsRemoteDebuggerPresent(processDescriptor.m_Pid, &fIsDebuggerPresent)))
{
if (fIsDebuggerPresent)
{