1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | |
6 | #ifndef __DBG_TRANSPORT_MANAGER_INCLUDED |
7 | #define __DBG_TRANSPORT_MANAGER_INCLUDED |
8 | |
9 | #ifdef FEATURE_DBGIPC_TRANSPORT_DI |
10 | |
11 | #include "coreclrremotedebugginginterfaces.h" |
12 | |
13 | |
14 | // TODO: Ideally we'd like to remove this class and don't do any process related book keeping in DBI. |
15 | |
16 | // This is a registry of all the processes a debugger knows about, different components call it in order to |
17 | // obtain right instance of DbgTransportSession for a given PID. It keeps list of processes and transports for them. |
18 | // It also handles things like creating and killing a process. |
19 | |
20 | // Usual lifecycle looks like this: |
21 | // Debug a new process: |
22 | // * CreateProcess(&pid) |
23 | // * On Mac, Optionally obtain an application group ID from a user |
24 | // * Create a ProcessDescriptor pd |
25 | // * GetTransportForProcess(&pd, &transport) |
26 | // * ReleaseTransport(transport) |
27 | // * KillProcess(pid) |
28 | |
29 | // Attach to an existing process: |
30 | // * Obtain pid (and optionally application group ID on Mac) from a user |
31 | // * Create a ProcessDescriptor pd |
32 | // * GetTransportForProcess(&pd, &transport) |
33 | // * ReleaseTransport(transport) |
34 | |
35 | class DbgTransportTarget |
36 | { |
37 | public: |
38 | DbgTransportTarget(); |
39 | |
40 | // Given a PID attempt to find or create a DbgTransportSession instance to manage a connection to a |
41 | // runtime in that process. Returns E_UNEXPECTED if the process can't be found. Also returns a handle that |
42 | // can be waited on for process termination. |
43 | HRESULT GetTransportForProcess(const ProcessDescriptor *pProcessDescriptor, DbgTransportSession **ppTransport, HANDLE *phProcessHandle); |
44 | |
45 | // Give back a previously acquired transport (if nobody else is using the transport it will close down the |
46 | // connection at this point). |
47 | void ReleaseTransport(DbgTransportSession *pTransport); |
48 | |
49 | // When and if the process starts the runtime will be told to halt and wait for a debugger attach. |
50 | HRESULT CreateProcess(LPCWSTR lpApplicationName, |
51 | LPCWSTR lpCommandLine, |
52 | LPSECURITY_ATTRIBUTES lpProcessAttributes, |
53 | LPSECURITY_ATTRIBUTES lpThreadAttributes, |
54 | BOOL bInheritHandles, |
55 | DWORD dwCreationFlags, |
56 | LPVOID lpEnvironment, |
57 | LPCWSTR lpCurrentDirectory, |
58 | LPSTARTUPINFOW lpStartupInfo, |
59 | LPPROCESS_INFORMATION lpProcessInformation); |
60 | |
61 | // Kill the process identified by PID. |
62 | void KillProcess(DWORD dwPID); |
63 | |
64 | HRESULT Init(); |
65 | void Shutdown(); |
66 | |
67 | private: |
68 | struct ProcessEntry |
69 | { |
70 | ProcessEntry *m_pNext; // Next entry in the list |
71 | DWORD m_dwPID; // Process ID for this entry |
72 | HANDLE m_hProcess; // Process handle |
73 | DbgTransportSession *m_transport; // Debugger's connection to the process |
74 | DWORD m_cProcessRef; // Ref count |
75 | |
76 | ~ProcessEntry(); |
77 | }; |
78 | |
79 | ProcessEntry *m_pProcessList; // Head of list of currently alive processes (unsorted) |
80 | RSLock m_sLock; // Lock protecting read and write access to the target list |
81 | |
82 | // Locate a process entry by PID. Assumes the lock is already held. |
83 | ProcessEntry *LocateProcessByPID(DWORD dwPID); |
84 | }; |
85 | |
86 | extern DbgTransportTarget *g_pDbgTransportTarget; |
87 | |
88 | #endif // FEATURE_DBGIPC_TRANSPORT_DI |
89 | |
90 | #endif // __DBG_TRANSPORT_MANAGER_INCLUDED |
91 | |