Merge pull request #12092 from wtgodbe/CoreDisTools
[platform/upstream/coreclr.git] / src / debug / di / process.cpp
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 // File: process.cpp
6 // 
7
8 //
9 //*****************************************************************************
10 #include "stdafx.h"
11 #include "primitives.h"
12 #include "safewrap.h"
13
14 #include "check.h" 
15
16 #ifndef SM_REMOTESESSION
17 #define SM_REMOTESESSION 0x1000
18 #endif
19
20 #include "corpriv.h"
21 #include "corexcep.h"
22 #include "../../dlls/mscorrc/resource.h"
23 #include <limits.h>
24
25 #include <sstring.h>
26
27 // @dbgtodo shim: process has some private hooks into the shim.
28 #include "shimpriv.h"
29
30 #include "metadataexports.h"
31 #include "readonlydatatargetfacade.h"
32 #include "metahost.h"
33
34 // Keep this around for retail debugging. It's very very useful because
35 // it's global state that we can always find, regardless of how many locals the compiler
36 // optimizes away ;)
37 struct RSDebuggingInfo; 
38 extern RSDebuggingInfo * g_pRSDebuggingInfo;
39
40 //---------------------------------------------------------------------------------------
41 //
42 // OpenVirtualProcessImpl method called by the shim to get an ICorDebugProcess4 instance
43 //
44 // Arguments:
45 //    clrInstanceId - target pointer identifying which CLR in the Target to debug.
46 //    pDataTarget - data target abstraction.
47 //    hDacModule - the handle of the appropriate DAC dll for this runtime
48 //    riid - interface ID to query for.
49 //    ppProcessOut - new object for target, interface ID matches riid.
50 //    ppFlagsOut - currently only has 1 bit to indicate whether or not this runtime
51 //                 instance will send a managed event after attach
52 //
53 // Return Value:
54 //    S_OK on success. Else failure
55 //
56 // Assumptions:
57 //
58 // Notes:
59 //    The outgoing process object can be cleaned up by calling Detach (which 
60 //    will reset the Attach bit.) 
61 //    @dbgtodo attach-bit: need to determine fate of attach bit.
62 //
63 //---------------------------------------------------------------------------------------
64 STDAPI OpenVirtualProcessImpl(
65     ULONG64 clrInstanceId, 
66     IUnknown * pDataTarget,
67     HMODULE hDacModule,
68     CLR_DEBUGGING_VERSION * pMaxDebuggerSupportedVersion,
69     REFIID riid,
70     IUnknown ** ppInstance,
71     CLR_DEBUGGING_PROCESS_FLAGS* pFlagsOut)
72 {    
73     HRESULT hr = S_OK;
74     RSExtSmartPtr<CordbProcess> pProcess;
75     PUBLIC_API_ENTRY(NULL);
76     EX_TRY
77     {
78
79         if ( (pDataTarget == NULL) || (clrInstanceId == 0) || (pMaxDebuggerSupportedVersion == NULL) ||
80             ((pFlagsOut == NULL) && (ppInstance == NULL))
81             )
82         {
83             ThrowHR(E_INVALIDARG);
84         }
85
86         // We consider the top 8 bits of the struct version to be the only part that represents
87         // a breaking change.  This gives us some freedom in the future to have the debugger
88         // opt into getting more data.
89         const WORD kMajorMask = 0xff00;
90         const WORD kMaxStructMajor = 0;
91         if ((pMaxDebuggerSupportedVersion->wStructVersion & kMajorMask) > kMaxStructMajor)
92         {
93             // Don't know how to interpret the version structure
94             ThrowHR(CORDBG_E_UNSUPPORTED_VERSION_STRUCT);
95         }
96
97         // This process object is intended to be used for the V3 pipeline, and so
98         // much of the process from V2 is not being used. For example, 
99         // - there is no ShimProcess object
100         // - there is no w32et thread (all threads are effectively an event thread)
101         // - the stop state is 'live', which corresponds to CordbProcess not knowing what
102         // its stop state really is (because that is now controlled by the shim).
103         IfFailThrow(CordbProcess::OpenVirtualProcess(
104             clrInstanceId,
105             pDataTarget,  // takes a reference
106             hDacModule,
107             NULL, // Cordb        
108             (DWORD) 0, // 0 for V3 cases (pShim == NULL). 
109             NULL, // no Shim in V3 cases
110             &pProcess));
111
112         // CordbProcess::OpenVirtualProcess already did the external addref to pProcess.
113         // Since pProcess is a smart ptr, it will external release in this function.
114         // Living reference will be the one from the QI.
115
116         // get the managed debug event pending flag
117         if(pFlagsOut != NULL)
118         {
119             hr = pProcess->GetAttachStateFlags(pFlagsOut);
120             if(FAILED(hr))
121             {
122                 ThrowHR(hr);
123             }
124         }
125
126         // 
127         // Check to make sure the debugger supports debugging this version
128         // Note that it's important that we still store the flags (above) in this case
129         //
130         if (!CordbProcess::IsCompatibleWith(pMaxDebuggerSupportedVersion->wMajor))
131         {
132             // Not compatible - don't keep the process instance, and return this specific error-code
133             ThrowHR(CORDBG_E_UNSUPPORTED_FORWARD_COMPAT);
134         }
135
136         //
137         // Now Query for the requested interface
138         //
139         if(ppInstance != NULL)
140         {
141             IfFailThrow(pProcess->QueryInterface(riid, reinterpret_cast<void**> (ppInstance)));
142         }
143
144         // if you have to add code here that could fail make sure ppInstance gets released and NULL'ed at exit
145     }
146     EX_CATCH_HRESULT(hr);
147
148     if((FAILED(hr) || ppInstance == NULL) && pProcess != NULL)
149     {
150         // The process has a strong reference to itself which is only released by neutering it.
151         // Since we aren't handing out the ref then we need to clean it up
152         _ASSERTE(ppInstance == NULL || *ppInstance == NULL);
153         pProcess->Neuter();
154     }
155     return hr;
156 };
157
158 //---------------------------------------------------------------------------------------
159 // DEPRECATED - use OpenVirtualProcessImpl
160 // OpenVirtualProcess method used by the shim in CLR v4 Beta1
161 // We'd like a beta1 shim/VS to still be able to open dumps using a CLR v4 Beta2+ mscordbi.dll, 
162 // so we'll leave this in place (at least until after Beta2 is in wide use).
163 //---------------------------------------------------------------------------------------
164 STDAPI OpenVirtualProcess2(
165     ULONG64 clrInstanceId, 
166     IUnknown * pDataTarget,
167     HMODULE hDacModule,
168     REFIID riid,
169     IUnknown ** ppInstance,
170     CLR_DEBUGGING_PROCESS_FLAGS* pFlagsOut)
171 {    
172     CLR_DEBUGGING_VERSION maxVersion = {0};
173     maxVersion.wMajor = 4;
174     return OpenVirtualProcessImpl(clrInstanceId, pDataTarget, hDacModule, &maxVersion, riid, ppInstance, pFlagsOut);
175 }
176
177 //---------------------------------------------------------------------------------------
178 // DEPRECATED - use OpenVirtualProcessImpl
179 // Public OpenVirtualProcess method to get an ICorDebugProcess4 instance
180 // Used directly in CLR v4 pre Beta1 - can probably be safely removed now
181 //---------------------------------------------------------------------------------------
182 STDAPI OpenVirtualProcess(
183     ULONG64 clrInstanceId, 
184     IUnknown * pDataTarget,
185     REFIID riid,
186     IUnknown ** ppInstance)
187 {    
188     return OpenVirtualProcess2(clrInstanceId, pDataTarget, NULL, riid, ppInstance, NULL);
189 };
190
191 //-----------------------------------------------------------------------------
192 // Most Hresults to Unrecoverable error indicate an internal error
193 // in the Right-Side.
194 // However, a few are legal (eg, "could actually happen in a retail scenario and
195 // not indicate an issue in mscorbi"). Track that here.
196 //-----------------------------------------------------------------------------
197
198 bool IsLegalFatalError(HRESULT hr)
199 {
200     return
201         (hr == CORDBG_E_INCOMPATIBLE_PROTOCOL) ||
202         (hr == CORDBG_E_CANNOT_DEBUG_FIBER_PROCESS) ||
203         (hr == CORDBG_E_UNCOMPATIBLE_PLATFORMS) ||
204         (hr == CORDBG_E_MISMATCHED_CORWKS_AND_DACWKS_DLLS) ||
205         // This should only happen in the case of a security attack on us.
206         (hr == E_ACCESSDENIED) ||
207         (hr == E_FAIL);
208 }
209
210 //-----------------------------------------------------------------------------
211 // Safe wait. Use this anytime we're waiting on:
212 // - an event signaled by the helper thread.
213 // - something signaled by a thread that holds the process lock.
214 // Note that we must preserve GetLastError() semantics.
215 //-----------------------------------------------------------------------------
216 inline DWORD SafeWaitForSingleObject(CordbProcess * p, HANDLE h, DWORD dwTimeout)
217 {
218     // Can't hold process lock while blocking
219     _ASSERTE(!p->ThreadHoldsProcessLock());
220
221     return ::WaitForSingleObject(h, dwTimeout);
222 }
223
224 #define CORDB_WAIT_TIMEOUT 360000 // milliseconds
225
226 //---------------------------------------------------------------------------------------
227 //
228 // Get the timeout value used in waits.
229 //
230 // Return Value:
231 //    Number of milliseconds to waite or possible INFINITE (-1).
232 //
233 //
234 // Notes:
235 //    Uses registry values for fine tuning.
236 //
237
238 // static
239 static inline DWORD CordbGetWaitTimeout()
240 {
241 #ifdef _DEBUG
242     // 0 = Wait forever
243     // 1 = Wait for CORDB_WAIT_TIMEOUT
244     // n = Wait for n milliseconds
245     static ConfigDWORD cordbWaitTimeout;
246     DWORD dwTimeoutVal = cordbWaitTimeout.val(CLRConfig::INTERNAL_DbgWaitTimeout);
247     if (dwTimeoutVal == 0)
248         return DWORD(-1);
249     else if (dwTimeoutVal != 1)
250         return dwTimeoutVal;
251     else
252 #endif
253     {
254         return CORDB_WAIT_TIMEOUT;
255     }
256 }
257
258 //----------------------------------------------------------------------------
259 // Implementation of IDacDbiInterface::IMetaDataLookup.
260 // lookup Internal Metadata Importer keyed by PEFile
261 // isILMetaDataForNGENImage is true iff the IMDInternalImport returned represents a pointer to
262 // metadata from an IL image when the module was an ngen'ed image.
263 IMDInternalImport * CordbProcess::LookupMetaData(VMPTR_PEFile vmPEFile, bool &isILMetaDataForNGENImage)
264 {
265     INTERNAL_DAC_CALLBACK(this);
266
267     HASHFIND hashFindAppDomain;
268     HASHFIND hashFindModule;
269     IMDInternalImport * pMDII = NULL;
270     isILMetaDataForNGENImage = false;
271
272     // Check to see if one of the cached modules has the metadata we need
273     // If not we will do a more exhaustive search below
274     for (CordbAppDomain * pAppDomain = m_appDomains.FindFirst(&hashFindAppDomain);
275          pAppDomain != NULL;
276          pAppDomain = m_appDomains.FindNext(&hashFindAppDomain))
277     {
278         for (CordbModule * pModule = pAppDomain->m_modules.FindFirst(&hashFindModule);
279              pModule != NULL;
280              pModule = pAppDomain->m_modules.FindNext(&hashFindModule))
281         {
282             if (pModule->GetPEFile() == vmPEFile)
283             {
284                 pMDII = NULL;
285                 ALLOW_DATATARGET_MISSING_MEMORY(
286                     pMDII = pModule->GetInternalMD();
287                 );
288                 if(pMDII != NULL)
289                     return pMDII;
290             }
291         }
292     }
293
294     // Cache didn't have it... time to search harder
295     PrepopulateAppDomainsOrThrow();
296
297     // There may be perf issues here. The DAC may make a lot of metadata requests, and so
298     // this may be an area for potential perf optimizations if we find things running slow.
299     
300     // enumerate through all Modules
301     for (CordbAppDomain * pAppDomain = m_appDomains.FindFirst(&hashFindAppDomain);
302          pAppDomain != NULL;
303          pAppDomain = m_appDomains.FindNext(&hashFindAppDomain))
304     {
305         pAppDomain->PrepopulateModules();
306
307         for (CordbModule * pModule = pAppDomain->m_modules.FindFirst(&hashFindModule);
308              pModule != NULL;
309              pModule = pAppDomain->m_modules.FindNext(&hashFindModule))
310         {
311             if (pModule->GetPEFile() == vmPEFile)
312             {
313                 pMDII = NULL;
314                 ALLOW_DATATARGET_MISSING_MEMORY(
315                     pMDII = pModule->GetInternalMD();
316                 );
317
318                 if ( pMDII == NULL)
319                 {
320                     // If we couldn't get metadata from the CordbModule, then we need to ask the
321                     // debugger if it can find the metadata elsewhere.
322                     // If this was live debugging, we should have just gotten the memory contents.
323                     // Thus this code is for dump debugging, when you don't have the metadata in the dump.
324                     pMDII = LookupMetaDataFromDebugger(vmPEFile, isILMetaDataForNGENImage, pModule);
325                 }
326                 return pMDII;
327             }
328         }
329     }
330
331     return NULL;
332 }
333
334
335 IMDInternalImport * CordbProcess::LookupMetaDataFromDebugger(
336     VMPTR_PEFile vmPEFile,
337     bool &isILMetaDataForNGENImage,
338     CordbModule * pModule)
339 {
340     DWORD dwImageTimeStamp = 0;
341     DWORD dwImageSize = 0;
342     bool isNGEN = false;
343     StringCopyHolder filePath;
344     IMDInternalImport * pMDII = NULL;
345
346     // First, see if the debugger can locate the exact metadata we want.
347     if (this->GetDAC()->GetMetaDataFileInfoFromPEFile(vmPEFile, dwImageTimeStamp, dwImageSize, isNGEN, &filePath))
348     {
349         _ASSERTE(filePath.IsSet());
350
351         // Since we track modules by their IL images, that presents a little bit of oddness here.  The correct
352         // thing to do is preferentially load the NI content.
353         // We don't discriminate between timestamps & sizes becuase CLRv4 deterministic NGEN guarantees that the
354         // IL image and NGEN image have the same timestamp and size.  Should that guarantee change, this code
355         // will be horribly broken.
356
357         // If we happen to have an NI file path, use it instead.
358         const WCHAR * pwszFilePath = pModule->GetNGenImagePath();
359         if (pwszFilePath)
360         {
361             // Force the issue, regardless of the older codepath's opinion.
362             isNGEN = true;
363         }
364         else
365         {
366             pwszFilePath = (WCHAR *)filePath;
367         }
368
369         ALLOW_DATATARGET_MISSING_MEMORY(
370             pMDII = LookupMetaDataFromDebuggerForSingleFile(pModule, pwszFilePath, dwImageTimeStamp, dwImageSize);
371         );
372
373         // If it's an ngen'ed image and the debugger couldn't find it, we can use the metadata from
374         // the corresponding IL image if the debugger can locate it.
375         filePath.Clear();
376         if ((pMDII == NULL) &&
377             (isNGEN) &&
378             (this->GetDAC()->GetILImageInfoFromNgenPEFile(vmPEFile, dwImageTimeStamp, dwImageSize, &filePath)))
379         {
380             _ASSERTE(filePath.IsSet());
381
382             WCHAR *mutableFilePath = (WCHAR *)filePath;
383
384 #if defined(FEATURE_CORESYSTEM)
385             size_t pathLen = wcslen(mutableFilePath);
386
387             const wchar_t *nidll = W(".ni.dll");
388             const wchar_t *niexe = W(".ni.exe");
389             const size_t dllLen = wcslen(nidll);  // used for ni.exe as well
390
391             const wchar_t *niwinmd = W(".ni.winmd");
392             const size_t winmdLen = wcslen(niwinmd);
393
394             if (pathLen > dllLen && _wcsicmp(mutableFilePath+pathLen-dllLen, nidll) == 0)
395             {
396                 wcscpy_s(mutableFilePath+pathLen-dllLen, dllLen, W(".dll"));
397             }
398             else if (pathLen > dllLen && _wcsicmp(mutableFilePath+pathLen-dllLen, niexe) == 0)
399             {
400                 wcscpy_s(mutableFilePath+pathLen-dllLen, dllLen, W(".exe"));
401             }
402             else if (pathLen > winmdLen && _wcsicmp(mutableFilePath+pathLen-winmdLen, niwinmd) == 0)
403             {
404                 wcscpy_s(mutableFilePath+pathLen-winmdLen, winmdLen, W(".winmd"));
405             }
406 #endif//FEATURE_CORESYSTEM
407
408             ALLOW_DATATARGET_MISSING_MEMORY(
409                 pMDII = LookupMetaDataFromDebuggerForSingleFile(pModule, mutableFilePath, dwImageTimeStamp, dwImageSize);
410             );
411
412             if (pMDII != NULL)
413             {
414                 isILMetaDataForNGENImage = true;
415             }
416         }
417     }
418     return pMDII;
419 }
420
421 // We do not know if the image being sent to us is an IL image or ngen image.
422 // CordbProcess::LookupMetaDataFromDebugger() has this knowledge when it looks up the file to hand off
423 // to this function.
424 // DacDbiInterfaceImpl::GetMDImport() has this knowledge in the isNGEN flag.
425 // The CLR v2 code that windbg used made a distinction whether the metadata came from
426 // the exact binary or not (i.e. were we getting metadata from the IL image and using
427 // it against the ngen image?) but that information was never used and so not brought forward.
428 // It would probably be more interesting generally to track whether the debugger gives us back
429 // a file that bears some relationship to the file we asked for, which would catch the NI/IL case
430 // as well.
431 IMDInternalImport * CordbProcess::LookupMetaDataFromDebuggerForSingleFile(
432     CordbModule * pModule,
433     LPCWSTR pwszFilePath,
434     DWORD dwTimeStamp,
435     DWORD dwSize)
436 {
437     INTERNAL_DAC_CALLBACK(this);
438
439     ULONG32 cchLocalImagePath = MAX_LONGPATH;
440     ULONG32 cchLocalImagePathRequired;
441     NewArrayHolder<WCHAR> pwszLocalFilePath = NULL;
442     IMDInternalImport * pMDII = NULL;
443
444     const HRESULT E_NSF_BUFFER = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
445     HRESULT hr = E_NSF_BUFFER;
446     for(unsigned i=0; i<2 && hr == E_NSF_BUFFER; i++)
447     {
448         if (pwszLocalFilePath != NULL)
449             pwszLocalFilePath.Release();
450
451         if (NULL == (pwszLocalFilePath = new (nothrow) WCHAR[cchLocalImagePath+1]))
452             ThrowHR(E_OUTOFMEMORY);
453
454         cchLocalImagePathRequired = 0;
455
456         hr = m_pMetaDataLocator->GetMetaData(pwszFilePath,
457                                              dwTimeStamp,
458                                              dwSize,
459                                              cchLocalImagePath,
460                                              &cchLocalImagePathRequired,
461                                              pwszLocalFilePath);
462
463         pwszLocalFilePath[cchLocalImagePath] = W('\0');
464         cchLocalImagePath = cchLocalImagePathRequired;
465     }
466
467     if (SUCCEEDED(hr))
468     {
469         hr = pModule->InitPublicMetaDataFromFile(pwszLocalFilePath, ofReadOnly, false);
470         if (SUCCEEDED(hr))
471         {
472             // While we're successfully returning a metadata reader, remember that there's
473             // absolutely no guarantee this metadata is an exact match for the vmPEFile.
474             // The debugger could literally send us back a path to any managed file with
475             // metadata content that is readable and we'll 'succeed'.
476             // For now, this is by-design.  A debugger should be allowed to decide if it wants
477             // to take a risk by returning 'mostly matching' metadata to see if debugging is
478             // possible in the absense of a true match.
479             pMDII = pModule->GetInternalMD();
480         }
481     }
482
483     return pMDII;
484 }
485
486
487 //---------------------------------------------------------------------------------------
488 //
489 // Implement IDacDbiInterface::IAllocator::Alloc
490 // Expected to throws on error.
491 //
492 // Arguments:
493 //    lenBytes - size of the byte array to allocate
494 //
495 // Return Value:
496 //    Return the newly allocated byte array, or throw on OOM
497 //
498 // Notes:
499 //    Since this function is a callback from DAC, it must not take the process lock.
500 //    If it does, we may deadlock between the DD lock and the process lock.  
501 //    If we really need to take the process lock for whatever reason, we must take it in the DBI functions
502 //    which call the DAC API that ends up calling this function.
503 //    See code:InternalDacCallbackHolder for more information.
504 //
505  
506 void * CordbProcess::Alloc(SIZE_T lenBytes)
507 {
508     return new BYTE[lenBytes]; // throws
509 }
510
511 //---------------------------------------------------------------------------------------
512 //
513 // Implements IDacDbiInterface::IAllocator::Free
514 //
515 // Arguments:
516 //    p - pointer to the memory to be released
517 //
518 // Notes:
519 //    Since this function is a callback from DAC, it must not take the process lock.
520 //    If it does, we may deadlock between the DD lock and the process lock.  
521 //    If we really need to take the process lock for whatever reason, we must take it in the DBI functions
522 //    which call the DAC API that ends up calling this function.
523 //    See code:InternalDacCallbackHolder for more information.
524 //
525  
526 void CordbProcess::Free(void * p)
527 {
528     // This shouldn't throw. 
529     delete [] ((BYTE *) p);
530 }
531
532
533 //---------------------------------------------------------------------------------------
534 //
535 // #DBIVersionChecking
536 // 
537 // There are a few checks we need to do to make sure we are using the matching DBI and DAC for a particular
538 // version of the runtime.
539 // 
540 // 1. Runtime vs. DBI
541 //     - Desktop
542 //         This is done by making sure that the CorDebugInterfaceVersion passed to code:CreateCordbObject is
543 //         compatible with the version of the DBI.
544 //         
545 //     - Windows CoreCLR
546 //         This is done by dbgshim.dll.  It checks whether the runtime DLL and the DBI DLL have the same
547 //         product version.  See CreateDebuggingInterfaceForVersion() in dbgshim.cpp.
548 //         
549 //     - Remote transport (Mac CoreCLR + CoreSystem CoreCLR)
550 //         Since there is no dbgshim.dll for a remote CoreCLR, we have to do this check in some other place.
551 //         We do this in code:CordbProcess::CreateDacDbiInterface, by calling 
552 //         code:DacDbiInterfaceImpl::CheckDbiVersion right after we have created the DDMarshal.  
553 //         The IDacDbiInterface implementation on remote device checks the product version of the device
554 //         coreclr by:
555 //             mac - looking at the Info.plist file in the CoreCLR bundle.
556 //             CoreSystem - this check is skipped at the moment, but should be implemented if we release it
557 //         
558 //         The one twist here is that the DBI needs to communicate with the IDacDbiInterface
559 //         implementation on the device BEFORE it can verify the product versions.  This means that we need to
560 //         have one IDacDbiInterface API which is consistent across all versions of the IDacDbiInterface.  
561 //         This puts two constraints on CheckDbiVersion():
562 //         
563 //             1.  It has to be the first API on the IDacDbiInterface.
564 //             - Otherwise, a wrong version of the DBI may end up calling a different API on the 
565 //               IDacDbiInterface and getting random results. (Really what matters is that it is
566 //               protocol message id 0, at present the source code position implies the message id)
567 //               
568 //             2.  Its parameters cannot change.
569 //             - Otherwise, we may run into random errors when we marshal/unmarshal the arguments for the
570 //               call to CheckDbiVersion().  Debugging will still fail, but we won't get the
571 //               version mismatch error. (Again, the protocol is what ultimately matters)
572 //             - To mitigate the impact of this constraint, we use the code:DbiVersion structure.
573 //               In addition to the DBI version, it also contains a format number (in case we decide to
574 //               check something else in the future), a breaking change number so that we can force
575 //               breaking changes between a DBI and a DAC, and space reserved for future use.
576 //
577 // 2. DBI vs. DAC
578 //     - Desktop and Windows CoreCLR (old architecture)
579 //          No verification is done. There is a transitive implication that if DBI matches runtime and DAC matches
580 //          runtime then DBI matches DAC. Technically because the DBI only matches runtime on major version number
581 //          runtime and DAC could be from different builds. However because we service all three binaries together
582 //          and DBI always loads the DAC that is sitting in the same directory DAC and DBI generally get tight
583 //          version coupling. A user with admin privleges could put different builds together and no version check
584 //          would ever fail though.
585 //
586 //      - Desktop and Windows CoreCLR (new architecture)
587 //          No verification is done. Similar to above its implied that if DBI matches runtime and runtime matches
588 //          DAC then DBI matches DAC. The only difference is that here both the DBI and DAC are provided by the
589 //          debugger. We provide timestamp and filesize for both binaries which are relatively strongly bound hints,
590 //          but there is no enforcement on the returned binaries beyond the runtime compat checking.
591 //
592 //      - Remote transport (Mac CoreCLR and CoreSystem CoreCLR)
593 //          Because the transport exists between DBI and DAC it becomes much more important to do a versioning check
594 //         
595 //          Mac - currently does a tightly bound version check between DBI and the runtime (CheckDbiVersion() above),
596 //             which transitively gives a tightly bound check to DAC. In same function there is also a check that is
597 //             logically a DAC DBI protocol check, verifying that the m_dwProtocolBreakingChangeCounter of DbiVersion
598 //             matches. However this check should be weaker than the build version check and doesn't add anything here.
599 //
600 //          CoreSystem - currently skips the tightly bound version check to make internal deployment and usage easier.
601 //             We want to use old desktop side debugger components to target newer CoreCLR builds, only forcing a desktop
602 //             upgrade when the protocol actually does change. To do this we use two checks:
603 //             1. The breaking change counter in CheckDbiVersion() whenever a dev knows they are breaking back
604 //                compat and wants to be explicit about it. This is the same as mac above.
605 //             2. During the auto-generation of the DDMarshal classes we take an MD5 hash of IDacDbiInterface source
606 //                code and embed it in two DDMarshal functions, one which runs locally and one that runs remotely.
607 //                If both DBI and DAC were built from the same source then the local and remote hashes will match. If the
608 //                hashes don't match then we assume there has been a been a breaking change in the protocol. Note
609 //                this hash could have both false-positives and false-negatives. False positives could occur when
610 //                IDacDbiInterface is changed in a trivial way, such as changing a comment. False negatives could
611 //                occur when the semantics of the protocol are changed even though the interface is not. Another
612 //                case would be changing the DDMarshal proxy generation code. In addition to the hashes we also
613 //                embed timestamps when the auto-generated code was produced. However this isn't used for version
614 //                matching, only as a hint to indicate which of two mismatched versions is newer.
615 //                
616 //         
617 // 3. Runtime vs. DAC
618 //     - Desktop, Windows CoreCLR, CoreSystem CoreCLR
619 //         In both cases we check this by matching the timestamp in the debug directory of the runtime image
620 //         and the timestamp we store in the DAC table when we generate the DAC dll.  This is done in 
621 //         code:ClrDataAccess::VerifyDlls.
622 //         
623 //     - Mac CoreCLR
624 //         On Mac, we don't have a timestamp in the runtime image.  Instead, we rely on checking the 16-byte 
625 //         UUID in the image.  This UUID is used to check whether a symbol file matches the image, so 
626 //         conceptually it's the same as the timestamp we use on Windows.  This is also done in 
627 //         code:ClrDataAccess::VerifyDlls.
628 // 
629 //---------------------------------------------------------------------------------------
630 //
631 // Instantiates a DacDbi Interface object in a live-debugging scenario that matches
632 // the current instance of mscorwks in this process.
633 //
634 // Return Value:
635 //    Returns on success. Else throws.
636 //
637 // Assumptions:
638 //    Client will code:CordbProcess::FreeDac when its done with the DacDbi interface.
639 //    Caller has initialized clrInstanceId.
640 //
641 // Notes:
642 //    This looks for the DAC next to this current DBI. This assumes that Dac and Dbi are both on
643 //    the local file system. That assumption will break in zero-copy deployment scenarios.
644 //
645 //---------------------------------------------------------------------------------------
646 void
647 CordbProcess::CreateDacDbiInterface()
648 {
649     _ASSERTE(m_pDACDataTarget != NULL);
650     _ASSERTE(m_pDacPrimitives == NULL); // don't double-init
651     
652     // Caller has already determined which CLR in the target is being debugged.
653     _ASSERTE(m_clrInstanceId != 0);
654
655     m_pDacPrimitives = NULL;
656
657     HRESULT hrStatus = S_OK;
658
659     // Non-marshalling path for live local dac.
660     // in the new arch we can get the module from OpenVirtualProcess2 but in the shim case
661     // and the deprecated OpenVirtualProcess case we must assume it comes from DAC in the
662     // same directory as DBI
663     if(m_hDacModule == NULL)
664     {
665         m_hDacModule.Assign(ShimProcess::GetDacModule());
666     }
667
668     //
669     // Get the access interface, passing our callback interfaces (data target, allocator and metadata lookup) 
670     //
671
672     IDacDbiInterface::IAllocator * pAllocator = this;
673     IDacDbiInterface::IMetaDataLookup * pMetaDataLookup = this;
674
675
676     typedef HRESULT (STDAPICALLTYPE * PFN_DacDbiInterfaceInstance)(
677         ICorDebugDataTarget *, 
678         CORDB_ADDRESS,
679         IDacDbiInterface::IAllocator *, 
680         IDacDbiInterface::IMetaDataLookup *, 
681         IDacDbiInterface **);
682
683     IDacDbiInterface* pInterfacePtr = NULL;
684     PFN_DacDbiInterfaceInstance pfnEntry = (PFN_DacDbiInterfaceInstance)GetProcAddress(m_hDacModule, "DacDbiInterfaceInstance");
685     if (!pfnEntry)
686     {
687         ThrowLastError();
688     }
689
690     hrStatus = pfnEntry(m_pDACDataTarget, m_clrInstanceId, pAllocator, pMetaDataLookup, &pInterfacePtr);
691     IfFailThrow(hrStatus);
692
693     // We now have a resource, pInterfacePtr, that needs to be freed.
694     m_pDacPrimitives = pInterfacePtr;   
695
696     // Setup DAC target consistency checking based on what we're using for DBI
697     m_pDacPrimitives->DacSetTargetConsistencyChecks( m_fAssertOnTargetInconsistency );
698 }
699
700 //---------------------------------------------------------------------------------------
701 //
702 // Is the DAC/DBI interface initialized? 
703 //
704 // Return Value:
705 //    TRUE iff init.
706 //
707 // Notes:
708 //    The RS will try to initialize DD as soon as it detects the runtime as loaded.
709 //    If the DD interface has not initialized, then it very likely the runtime has not
710 //    been loaded into the target.
711 //
712 BOOL CordbProcess::IsDacInitialized()
713 {
714     return m_pDacPrimitives != NULL;
715 }
716
717 //---------------------------------------------------------------------------------------
718 //
719 // Get the DAC interface. 
720 //
721 // Return Value:
722 //    the Dac/Dbi interface pointer to the process.
723 //    Never returns NULL.
724 //
725 // Assumptions:
726 //    Caller is responsible for ensuring Data-Target is safe to access (eg, not 
727 //    currently running).
728 //    Caller is responsible for ensuring DAC-cache is flushed. Call code:CordbProcess::ForceDacFlush
729 //    as needed.
730 //
731 //---------------------------------------------------------------------------------------
732 IDacDbiInterface * CordbProcess::GetDAC()
733 {
734     // Since the DD primitives may throw, easiest way to model that is to make this throw.
735     CONTRACTL
736     {
737         THROWS;
738     }
739     CONTRACTL_END;
740
741     // We should always have the DAC/DBI interface.
742     _ASSERTE(m_pDacPrimitives != NULL);
743     return m_pDacPrimitives;
744 }
745
746 //---------------------------------------------------------------------------------------
747 // Get the Data-Target
748 // 
749 // Returns:
750 //     pointer to the data-target. Should be non-null.
751 //     Lifetime of the pointer is until this process object is neutered.
752 //
753 ICorDebugDataTarget * CordbProcess::GetDataTarget()
754 {
755     return m_pDACDataTarget;
756 }
757
758 //---------------------------------------------------------------------------------------
759 // Create a CordbProcess object around an existing OS process.
760 //
761 // Arguments:
762 //     pDataTarget - abstracts access to the debuggee.
763 //     clrInstanceId - identifies the CLR instance within the debuggee. (This is the 
764 //         base address of mscorwks)
765 //     pCordb - Pointer to the implementation of the owning Cordb object implementing the 
766 //         owning ICD interface.
767 //         This should go away - we can get the functionality from the pShim.
768 //         If this is null, then pShim must be null too.
769 //     processID - OS process ID of target process. 0 if pShim == NULL.
770 //     pShim - shim counter part object. This allows hooks back for v2 compat. This will
771 //         go away once we no longer support V2 backwards compat.
772 //         This must be non-null for any V2 paths (including non-DAC-ized code).
773 //         If this is null, then we're in a V3 path.
774 //     ppProcess - out parameter for new process object. This gets addreffed.
775 //
776 // Return Value:
777 //     S_OK on success, and *ppProcess set to newly created debuggee object. Else error.
778 //
779 // Notes:
780 //    @dbgtodo - , shim: Cordb, and pShim will all eventually go away.
781 //
782 //---------------------------------------------------------------------------------------
783
784 // static 
785 HRESULT CordbProcess::OpenVirtualProcess(
786     ULONG64 clrInstanceId, 
787     IUnknown * pDataTarget,
788     HMODULE hDacModule,
789     Cordb* pCordb,     
790     DWORD dwProcessID, 
791     ShimProcess * pShim,
792     CordbProcess ** ppProcess)
793 {
794     _ASSERTE(pDataTarget != NULL);
795
796     // In DEBUG builds, verify that we do actually have an ICorDebugDataTarget (i.e. that
797     // someone hasn't messed up the COM interop marshalling, etc.).
798 #ifdef _DEBUG
799     {
800         IUnknown * pTempDt;
801         HRESULT hrQi = pDataTarget->QueryInterface(IID_ICorDebugDataTarget, (void**)&pTempDt);
802         _ASSERTE_MSG(SUCCEEDED(hrQi), "OpenVirtualProcess was passed something that isn't actually an ICorDebugDataTarget");
803         pTempDt->Release();
804     }
805 #endif
806
807     // If we're emulating V2, then both pCordb and pShim are non-NULL.
808     // If we're doing a real V3 path, then they're both NULL.
809     // Either way, they should have the same null-status.
810     _ASSERTE((pCordb == NULL) == (pShim == NULL));
811
812     // If we're doing real V3, then we must have a real instance ID
813     _ASSERTE(!((pShim == NULL) && (clrInstanceId == 0)));
814
815     *ppProcess = NULL;
816
817     HRESULT hr = S_OK;
818     RSUnsafeExternalSmartPtr<CordbProcess> pProcess;
819     pProcess.Assign(new (nothrow) CordbProcess(clrInstanceId, pDataTarget, hDacModule, pCordb, dwProcessID, pShim));
820
821     if (pProcess == NULL)
822     {
823         return E_OUTOFMEMORY;
824     }
825
826     ICorDebugProcess * pThis = pProcess;
827     (void)pThis; //prevent "unused variable" error from GCC
828
829     // CordbProcess::Init may need shim hooks, so connect Shim now.
830     // This will bump reference count.
831     if (pShim != NULL)
832     {
833         pShim->SetProcess(pProcess);    
834
835         _ASSERTE(pShim->GetProcess() == pThis);        
836         _ASSERTE(pShim->GetWin32EventThread() != NULL);
837     }
838
839     hr = pProcess->Init();
840
841     if (SUCCEEDED(hr))
842     {
843         *ppProcess = pProcess;
844         pProcess->ExternalAddRef();
845     }
846     else
847     {
848         // handle failure path
849         pProcess->CleanupHalfBakedLeftSide();
850
851         if (pShim != NULL)
852         {
853             // Shim still needs to be disposed to clean up other resources.
854             pShim->SetProcess(NULL);
855         }
856
857         // In failure case, pProcess's dtor will do the final release.
858     }
859     
860
861     return hr;
862 }
863
864 //---------------------------------------------------------------------------------------
865 // CordbProcess constructor
866 //
867 // Arguments:
868 //     pDataTarget - Pointer to an implementation of ICorDebugDataTarget 
869 //         (or ICorDebugMutableDataTarget), which virtualizes access to the process.
870 //     clrInstanceId - representation of the CLR to debug in the process.  Must be specified
871 //         (non-zero) if pShim is NULL.  If 0, use the first CLR that we see.
872 //     pCordb - Pointer to the implementation of the owning Cordb object implementing the 
873 //         owning ICD interface.
874 //     pW32 - Pointer to the Win32 event thread to use when processing events for this
875 //         process.
876 //     dwProcessID - For V3, 0. 
877 //         Else for shim codepaths, the processID of the process this object will represent. 
878 //     pShim - Pointer to the shim for handling V2 debuggers on the V3 architecture.
879 //
880 //---------------------------------------------------------------------------------------
881
882 CordbProcess::CordbProcess(ULONG64 clrInstanceId,
883                            IUnknown * pDataTarget,
884                            HMODULE hDacModule,
885                            Cordb * pCordb,
886                            DWORD dwProcessID,
887                            ShimProcess * pShim)
888   : CordbBase(NULL, dwProcessID, enumCordbProcess),
889     m_fDoDelayedManagedAttached(false),
890     m_cordb(pCordb), 
891     m_handle(NULL),    
892     m_detached(false), 
893     m_uninitializedStop(false),
894     m_exiting(false),
895     m_terminated(false),
896     m_unrecoverableError(false), 
897     m_specialDeferment(false),
898     m_helperThreadDead(false),
899     m_loaderBPReceived(false),
900     m_cOutstandingEvals(0),
901     m_cOutstandingHandles(0),
902     m_clrInstanceId(clrInstanceId),
903     m_stopCount(0),
904     m_synchronized(false),
905     m_syncCompleteReceived(false),
906     m_pShim(pShim),
907     m_userThreads(11),
908     m_oddSync(false), 
909 #ifdef FEATURE_INTEROP_DEBUGGING
910     m_unmanagedThreads(11),
911 #endif
912     m_appDomains(11),
913     m_sharedAppDomain(0),
914     m_steppers(11),
915     m_continueCounter(1),
916     m_flushCounter(0),
917     m_leftSideEventAvailable(NULL),
918     m_leftSideEventRead(NULL),
919 #if defined(FEATURE_INTEROP_DEBUGGING)
920     m_leftSideUnmanagedWaitEvent(NULL),    
921 #endif // FEATURE_INTEROP_DEBUGGING
922     m_initialized(false),
923     m_stopRequested(false),
924     m_stopWaitEvent(NULL),
925 #ifdef FEATURE_INTEROP_DEBUGGING
926     m_cFirstChanceHijackedThreads(0),
927     m_unmanagedEventQueue(NULL),
928     m_lastQueuedUnmanagedEvent(NULL),
929     m_lastQueuedOOBEvent(NULL),
930     m_outOfBandEventQueue(NULL),
931     m_lastDispatchedIBEvent(NULL),
932     m_dispatchingUnmanagedEvent(false),
933     m_dispatchingOOBEvent(false),
934     m_doRealContinueAfterOOBBlock(false),   
935     m_state(0),
936 #endif // FEATURE_INTEROP_DEBUGGING
937     m_helperThreadId(0),
938     m_pPatchTable(NULL),
939     m_cPatch(0),
940     m_rgData(NULL),
941     m_rgNextPatch(NULL),
942     m_rgUncommitedOpcode(NULL),
943     m_minPatchAddr(MAX_ADDRESS),
944     m_maxPatchAddr(MIN_ADDRESS),
945     m_iFirstPatch(0),
946     m_hHelperThread(NULL),
947     m_dispatchedEvent(DB_IPCE_DEBUGGER_INVALID),
948     m_pDefaultAppDomain(NULL),
949     m_hDacModule(hDacModule),
950     m_pDacPrimitives(NULL),
951     m_pEventChannel(NULL),
952     m_fAssertOnTargetInconsistency(false),
953     m_runtimeOffsetsInitialized(false),
954     m_writableMetadataUpdateMode(LegacyCompatPolicy)
955 {
956     _ASSERTE((m_id == 0) == (pShim == NULL));
957
958     HRESULT hr = pDataTarget->QueryInterface(IID_ICorDebugDataTarget, reinterpret_cast<void **>(&m_pDACDataTarget));
959     IfFailThrow(hr);
960
961 #ifdef FEATURE_INTEROP_DEBUGGING
962     m_DbgSupport.m_DebugEventQueueIdx = 0;
963     m_DbgSupport.m_TotalNativeEvents = 0;
964     m_DbgSupport.m_TotalIB = 0;
965     m_DbgSupport.m_TotalOOB = 0;
966     m_DbgSupport.m_TotalCLR = 0;
967 #endif // FEATURE_INTEROP_DEBUGGING
968
969     g_pRSDebuggingInfo->m_MRUprocess = this;
970
971     // This is a strong reference to ourselves.
972     // This is cleared in code:CordbProcess::Neuter
973     m_pProcess.Assign(this);
974
975 #ifdef _DEBUG
976     // On Debug builds, we'll ASSERT by default whenever the target appears to be corrupt or 
977     // otherwise inconsistent (both in DAC and DBI).  But we also need the ability to 
978     // explicitly test corrupt targets.
979     // Tests should set COMPlus_DbgIgnoreInconsistentTarget=1 to suppress these asserts
980     // Note that this controls two things:
981     //     1) DAC behavior - see code:IDacDbiInterface::DacSetTargetConsistencyChecks
982     //     2) RS-only consistency asserts - see code:CordbProcess::TargetConsistencyCheck
983     if( !CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgDisableTargetConsistencyAsserts) )
984     {
985         m_fAssertOnTargetInconsistency = true;
986     }
987 #endif
988 }
989
990 /*
991     A list of which resources owned by this object are accounted for.
992
993     UNKNOWN
994         Cordb*                      m_cordb;
995         CordbHashTable              m_unmanagedThreads; // Released in CordbProcess but not removed from hash
996         DebuggerIPCEvent*           m_lastQueuedEvent;
997
998         // CordbUnmannagedEvent is a struct which is not derrived from CordbBase.
999         // It contains a CordbUnmannagedThread which may need to be released.
1000         CordbUnmanagedEvent         *m_unmanagedEventQueue;
1001         CordbUnmanagedEvent         *m_lastQueuedUnmanagedEvent;
1002         CordbUnmanagedEvent         *m_outOfBandEventQueue;
1003         CordbUnmanagedEvent         *m_lastQueuedOOBEvent;
1004
1005         BYTE*                       m_pPatchTable;
1006         BYTE                        *m_rgData;
1007         void                        *m_pbRemoteBuf;
1008
1009    RESOLVED
1010         // Nutered
1011         CordbHashTable        m_userThreads;
1012         CordbHashTable        m_appDomains;
1013
1014         // Cleaned up in ExitProcess
1015         DebuggerIPCEvent*     m_queuedEventList;
1016
1017         CordbHashTable        m_steppers; // Closed in ~CordbProcess
1018
1019         // Closed in CloseIPCEventHandles called from ~CordbProcess
1020         HANDLE                m_leftSideEventAvailable;
1021         HANDLE                m_leftSideEventRead;
1022
1023         // Closed in ~CordbProcess
1024         HANDLE                m_handle;
1025         HANDLE                m_leftSideUnmanagedWaitEvent;
1026         HANDLE                m_stopWaitEvent;
1027
1028         // Deleted in ~CordbProcess
1029         CRITICAL_SECTION      m_processMutex;
1030
1031 */
1032
1033
1034 CordbProcess::~CordbProcess()
1035 {
1036     LOG((LF_CORDB, LL_INFO1000, "CP::~CP: deleting process 0x%08x\n", this));
1037
1038     DTOR_ENTRY(this);
1039
1040     _ASSERTE(IsNeutered());
1041
1042     _ASSERTE(m_cordb == NULL);
1043
1044     // We shouldn't still be in Cordb's list of processes. Unfortunately, our root Cordb object
1045     // may have already been deleted b/c we're at the mercy of ref-counting, so we can't check.
1046     
1047         _ASSERTE(m_sharedAppDomain == NULL);
1048         
1049     m_processMutex.Destroy();
1050     m_StopGoLock.Destroy();
1051
1052     // These handles were cleared in neuter
1053     _ASSERTE(m_handle == NULL); 
1054 #if defined(FEATURE_INTEROP_DEBUGGING)
1055     _ASSERTE(m_leftSideUnmanagedWaitEvent == NULL);
1056 #endif // FEATURE_INTEROP_DEBUGGING
1057     _ASSERTE(m_stopWaitEvent == NULL);
1058     
1059     // Set this to mark that we really did cleanup.
1060 }
1061
1062 //-----------------------------------------------------------------------------
1063 // Static build helper.
1064 // This will create a process under the pCordb root, and add it to the list.
1065 // We don't return the process - caller gets the pid and looks it up under
1066 // the Cordb object.
1067 //
1068 // Arguments:
1069 //     pCordb - Pointer to the implementation of the owning Cordb object implementing the 
1070 //         owning ICD interface.
1071 //     szProgramName - Name of the program to execute.
1072 //     szProgramArgs - Command line arguments for the process.
1073 //     lpProcessAttributes - OS-specific attributes for process creation.
1074 //     lpThreadAttributes - OS-specific attributes for thread creation.
1075 //     fInheritFlags - OS-specific flag for child process inheritance.
1076 //     dwCreationFlags - OS-specific creation flags.
1077 //     lpEnvironment - OS-specific environmental strings.
1078 //     szCurrentDirectory - OS-specific string for directory to run in.
1079 //     lpStartupInfo - OS-specific info on startup.
1080 //     lpProcessInformation - OS-specific process information buffer.
1081 //     corDebugFlags - What type of process to create, currently always managed.
1082 //-----------------------------------------------------------------------------
1083 HRESULT ShimProcess::CreateProcess(
1084       Cordb * pCordb,
1085       ICorDebugRemoteTarget * pRemoteTarget,
1086       LPCWSTR szProgramName,
1087       __in_z LPWSTR  szProgramArgs,
1088       LPSECURITY_ATTRIBUTES lpProcessAttributes,
1089       LPSECURITY_ATTRIBUTES lpThreadAttributes,
1090       BOOL fInheritHandles,
1091       DWORD dwCreationFlags,
1092       PVOID lpEnvironment,
1093       LPCWSTR szCurrentDirectory,
1094       LPSTARTUPINFOW lpStartupInfo,
1095       LPPROCESS_INFORMATION lpProcessInformation,
1096       CorDebugCreateProcessFlags corDebugFlags
1097 )
1098 {
1099     _ASSERTE(pCordb != NULL);
1100
1101 #if defined(FEATURE_DBGIPC_TRANSPORT_DI)
1102     // The transport cannot deal with creating a suspended process (it needs the debugger to start up and
1103     // listen for connections).
1104     _ASSERTE((dwCreationFlags & CREATE_SUSPENDED) == 0);
1105 #endif // FEATURE_DBGIPC_TRANSPORT_DI
1106
1107     HRESULT hr = S_OK;
1108
1109     RSExtSmartPtr<ShimProcess> pShim;
1110     EX_TRY
1111     {
1112         pShim.Assign(new ShimProcess());
1113
1114         // Indicate that this process was started under the debugger as opposed to attaching later.
1115         pShim->m_attached = false;
1116
1117         hr = pShim->CreateAndStartWin32ET(pCordb);
1118         IfFailThrow(hr);
1119
1120         // Call out to newly created Win32-event Thread to create the process. 
1121         // If this succeeds, new CordbProcess will add a ref to the ShimProcess
1122         hr = pShim->GetWin32EventThread()->SendCreateProcessEvent(pShim->GetMachineInfo(),
1123                                                                   szProgramName,
1124                                                                   szProgramArgs,
1125                                                                   lpProcessAttributes,
1126                                                                   lpThreadAttributes,
1127                                                                   fInheritHandles,
1128                                                                   dwCreationFlags,
1129                                                                   lpEnvironment,
1130                                                                   szCurrentDirectory,
1131                                                                   lpStartupInfo,
1132                                                                   lpProcessInformation,
1133                                                                   corDebugFlags);
1134         IfFailThrow(hr);
1135     }
1136     EX_CATCH_HRESULT(hr);
1137
1138     // If this succeeds, then process takes ownership of thread. Else we need to kill it.
1139     if (FAILED(hr))
1140     {
1141         if (pShim != NULL)
1142         {
1143             pShim->Dispose();
1144         }
1145     }
1146     // Always release our ref to ShimProcess. If the Process was created, then it takes a reference.
1147
1148     return hr;
1149 }
1150
1151 //-----------------------------------------------------------------------------
1152 // Static build helper for the attach case.
1153 // On success, this will add the process to the pCordb list, and then
1154 // callers can look it up there by pid.
1155 //
1156 // Arguments:
1157 //     pCordb - root under which this all lives
1158 //     dwProcessID - OS process ID to attach to
1159 //     fWin32Attach - are we interop debugging?
1160 //-----------------------------------------------------------------------------
1161 HRESULT ShimProcess::DebugActiveProcess(
1162     Cordb * pCordb,
1163     ICorDebugRemoteTarget * pRemoteTarget,
1164     DWORD dwProcessID,
1165     BOOL fWin32Attach
1166 )
1167 {
1168     _ASSERTE(pCordb != NULL);
1169
1170     HRESULT hr = S_OK;
1171
1172     RSExtSmartPtr<ShimProcess> pShim;
1173
1174     EX_TRY
1175     {
1176         pShim.Assign(new ShimProcess());
1177
1178         // Indicate that this process was attached to, asopposed to being started under the debugger.
1179         pShim->m_attached = true;
1180        
1181         hr = pShim->CreateAndStartWin32ET(pCordb);
1182         IfFailThrow(hr);
1183
1184         // If this succeeds, new CordbProcess will add a ref to the ShimProcess
1185         hr = pShim->GetWin32EventThread()->SendDebugActiveProcessEvent(pShim->GetMachineInfo(),
1186                                                                        dwProcessID,
1187                                                                        fWin32Attach == TRUE,
1188                                                                        NULL);
1189         IfFailThrow(hr);
1190
1191         _ASSERTE(SUCCEEDED(hr));
1192
1193 #if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
1194         // Don't do this when we are remote debugging since we won't be getting the loader breakpoint.
1195         // We don't support JIT attach in remote debugging scenarios anyway.
1196         //
1197         // When doing jit attach for pure managed debugging we allow the native attach event to be signaled
1198         // after DebugActiveProcess completes which means we must wait here long enough to have set the debuggee
1199         // bit indicating managed attach is coming.
1200         // However in interop debugging we can't do that because there are debug events which come before the
1201         // loader breakpoint (which is how far we need to get to set the debuggee bit). If we blocked 
1202         // DebugActiveProcess there then the debug events would be refering to an ICorDebugProcess that hasn't
1203         // yet been returned to the caller of DebugActiveProcess. Instead, for interop debugging we force the
1204         // native debugger to wait until it gets the loader breakpoint to set the event. Note we can't converge
1205         // on that solution for the pure managed case because there is no loader breakpoint event. Hence pure
1206         // managed and interop debugging each require their own solution
1207         //
1208         // See bugs Dev10 600873 and 595322 for examples of what happens if we wait in interop or don't wait
1209         // in pure managed respectively
1210         //
1211         // Long term this should all go away because we won't need to set a managed attach pending bit because
1212         // there shouldn't be any IPC events involved in managed attach. There might not even be a notion of
1213         // being 'managed attached'
1214         if(!pShim->m_fIsInteropDebugging)
1215         {
1216             DWORD  dwHandles = 2;
1217             HANDLE arrHandles[2];
1218
1219             arrHandles[0] = pShim->m_terminatingEvent;
1220             arrHandles[1] = pShim->m_markAttachPendingEvent;
1221
1222             // Wait for the completion of marking pending attach bit or debugger detaching
1223             WaitForMultipleObjectsEx(dwHandles, arrHandles, FALSE, INFINITE, FALSE);
1224         }
1225 #endif //!FEATURE_DBGIPC_TRANSPORT_DI
1226     }
1227     EX_CATCH_HRESULT(hr);
1228     
1229     // If this succeeds, then process takes ownership of thread. Else we need to kill it.
1230     if (FAILED(hr))
1231     {
1232         if (pShim!= NULL)
1233         {
1234             pShim->Dispose();
1235         }
1236     }
1237     
1238     // Always release our ref to ShimProcess. If the Process was created, then it takes a reference.
1239
1240     return hr;
1241 }
1242
1243 //-----------------------------------------------------------------------------
1244 // Neuter all of all children, but not the actual process object.
1245 //
1246 // Assumptions:
1247 //   This clears Right-side state. Assumptions about left-side state are either:
1248 //   1. We're in a shutdown scenario, where all left-side state is already
1249 //   freed.
1250 //   2. Caller already verified there are no left-side resources (eg, by calling
1251 //   code:CordbProcess::IsReadyForDetach)
1252 //   3. Caller did code:CordbProcess::NeuterLeftSideResources first
1253 //   to clean up left-side resources.
1254 //   
1255 // Notes:
1256 //   This could be called multiple times (code:CordbProcess::FlushAll), so
1257 //   be sure to null out any potential dangling pointers. State may be rebuilt
1258 //   up after each time.
1259 void CordbProcess::NeuterChildren()
1260 {   
1261     _ASSERTE(GetProcessLock()->HasLock());
1262     
1263     // Frees left-side resources. See assumptions above.
1264     m_LeftSideResourceCleanupList.NeuterAndClear(this);
1265
1266
1267     m_EvalTable.Clear();    
1268     
1269
1270     // Sweep neuter lists.    
1271     m_ExitNeuterList.NeuterAndClear(this);
1272     m_ContinueNeuterList.NeuterAndClear(this);
1273
1274     m_userThreads.NeuterAndClear(GetProcessLock());
1275     
1276     m_pDefaultAppDomain = NULL;
1277
1278     // Frees per-appdomain left-side resources. See assumptions above.
1279     m_appDomains.NeuterAndClear(GetProcessLock());
1280     if (m_sharedAppDomain != NULL)
1281     {
1282         m_sharedAppDomain->Neuter();
1283         m_sharedAppDomain->InternalRelease();
1284         m_sharedAppDomain = NULL;
1285     }
1286
1287     m_steppers.NeuterAndClear(GetProcessLock());
1288
1289 #ifdef FEATURE_INTEROP_DEBUGGING
1290     m_unmanagedThreads.NeuterAndClear(GetProcessLock());
1291 #endif // FEATURE_INTEROP_DEBUGGING
1292
1293     // Explicitly keep the Win32EventThread alive so that we can use it in the window
1294     // between NeuterChildren + Neuter.
1295 }
1296
1297 //-----------------------------------------------------------------------------
1298 // Neuter
1299 //
1300 // When the process dies, remove all the resources associated with this object.
1301 //
1302 // Notes:
1303 //   Once we neuter ourself, we can no longer send IPC events. So this is useful
1304 //   on detach. This will be called on FlushAll (which has Whidbey detach
1305 //   semantics)
1306 //-----------------------------------------------------------------------------
1307 void CordbProcess::Neuter()
1308 {
1309     // Process's Neuter is at the top of the neuter tree. So we take the process-lock
1310     // here and then all child items (appdomains, modules, etc) will assert
1311     // that they hold the lock.
1312     _ASSERTE(!this->ThreadHoldsProcessLock());
1313
1314     // Take the process lock.
1315     RSLockHolder lockHolder(GetProcessLock());
1316
1317     
1318     NeuterChildren();
1319
1320     // Release the metadata interfaces    
1321     m_pMetaDispenser.Clear();
1322
1323
1324     if (m_hHelperThread != NULL)
1325     {
1326         CloseHandle(m_hHelperThread);
1327         m_hHelperThread = NULL;
1328     }
1329
1330     {
1331         lockHolder.Release();
1332         {
1333             // We may still hold the Stop-Go lock.
1334             // @dbgtodo - left-side resources / shutdown, shim: Currently
1335             // the shim shutdown is too interwoven with CordbProcess to split
1336             // it out from the locks. Must fully hoist the W32ET and make
1337             // it safely outside the RS, and outside the protection of RS
1338             // locks.
1339             PUBLIC_API_UNSAFE_ENTRY_FOR_SHIM(this);
1340
1341             // Now that all of our children are neutered, it should be safe to kill the W32ET.
1342             // Shutdown the shim, and this will also shutdown the W32ET.
1343             // Do this outside of the process-lock so that we can shutdown the
1344             // W23ET.
1345             if (m_pShim != NULL)
1346             {
1347                 m_pShim->Dispose();            
1348                 m_pShim.Clear();
1349             }
1350         }
1351
1352         lockHolder.Acquire();
1353     }
1354
1355     // Unload DAC, and then release our final data target references
1356     FreeDac();
1357     m_pDACDataTarget.Clear();
1358     m_pMutableDataTarget.Clear();
1359     m_pMetaDataLocator.Clear();
1360
1361     if (m_pEventChannel != NULL)
1362     {
1363         m_pEventChannel->Delete();
1364         m_pEventChannel = NULL;
1365     }
1366     
1367     // Need process lock to clear the patch table    
1368     ClearPatchTable();
1369     
1370     CordbProcess::CloseIPCHandles();
1371
1372     CordbBase::Neuter();
1373         
1374     m_cordb.Clear();
1375
1376     // Need to release this reference to ourselves. Other leaf objects may still hold
1377     // strong references back to this CordbProcess object.
1378     _ASSERTE(m_pProcess == this);
1379     m_pProcess.Clear();    
1380 }
1381
1382 // Wrapper to return metadata dispenser.
1383 // 
1384 // Notes:
1385 //    Does not adjust reference count of dispenser.
1386 //    Dispenser is destroyed in code:CordbProcess::Neuter
1387 //    Dispenser is non-null.
1388 IMetaDataDispenserEx * CordbProcess::GetDispenser()
1389 {
1390     _ASSERTE(m_pMetaDispenser != NULL);
1391     return m_pMetaDispenser;
1392 }
1393
1394
1395 void CordbProcess::CloseIPCHandles()
1396 {
1397     INTERNAL_API_ENTRY(this);
1398
1399     // Close off Right Side's handles.
1400     if (m_leftSideEventAvailable != NULL)
1401     {
1402         CloseHandle(m_leftSideEventAvailable);
1403         m_leftSideEventAvailable = NULL;
1404     }
1405
1406     if (m_leftSideEventRead != NULL)
1407     {
1408         CloseHandle(m_leftSideEventRead);
1409         m_leftSideEventRead = NULL;
1410     }
1411
1412     if (m_handle != NULL)
1413     {
1414         // @dbgtodo  - We should probably add asserts to all calls to CloseHandles(), but this has been
1415         // a particularly problematic spot in the past for Mac debugging.
1416         BOOL fSuccess = CloseHandle(m_handle);
1417         (void)fSuccess; //prevent "unused variable" error from GCC
1418         _ASSERTE(fSuccess);
1419
1420         m_handle = NULL;
1421     }
1422
1423 #if defined(FEATURE_INTEROP_DEBUGGING)
1424     if (m_leftSideUnmanagedWaitEvent != NULL)
1425     {
1426         CloseHandle(m_leftSideUnmanagedWaitEvent);
1427         m_leftSideUnmanagedWaitEvent = NULL;
1428     }
1429 #endif // FEATURE_INTEROP_DEBUGGING
1430
1431     if (m_stopWaitEvent != NULL)
1432     {
1433         CloseHandle(m_stopWaitEvent);
1434         m_stopWaitEvent = NULL;
1435     }
1436 }
1437
1438
1439 //-----------------------------------------------------------------------------
1440 // Create new OS Thread for the Win32 Event Thread (the thread used in interop-debugging to sniff
1441 // native debug events). This is 1:1 w/ a CordbProcess object.
1442 // This will then be used to actuall create the CordbProcess object.
1443 // The process object will then take ownership of the thread.
1444 //
1445 // Arguments:
1446 //     pCordb - the root object that the process lives under
1447 //
1448 // Return values:
1449 //     S_OK on success.
1450 //-----------------------------------------------------------------------------
1451 HRESULT ShimProcess::CreateAndStartWin32ET(Cordb * pCordb)
1452 {   
1453
1454     //
1455     // Create the win32 event listening thread
1456     //
1457     CordbWin32EventThread * pWin32EventThread = new (nothrow) CordbWin32EventThread(pCordb, this);
1458
1459     HRESULT hr = S_OK;
1460
1461     if (pWin32EventThread != NULL)
1462     {
1463         hr = pWin32EventThread->Init();
1464
1465         if (SUCCEEDED(hr))
1466         {
1467             hr = pWin32EventThread->Start();
1468         }
1469
1470         if (FAILED(hr))
1471         {
1472             delete pWin32EventThread;
1473             pWin32EventThread = NULL;
1474         }
1475     }
1476     else
1477     {
1478         hr = E_OUTOFMEMORY;
1479     }
1480
1481     m_pWin32EventThread = pWin32EventThread;
1482     return ErrWrapper(hr);
1483 }
1484
1485
1486 //---------------------------------------------------------------------------------------
1487 //
1488 // Try to initialize the DAC. Called in scenarios where it may fail.
1489 //
1490 // Return Value:
1491 //    TRUE  - DAC is initialized.
1492 //    FALSE  - Not initialized, but can try again later. Common case if 
1493 //          target has not yet loaded the runtime.
1494 //    Throws exception - fatal.
1495 //
1496 // Assumptions:
1497 //    Target is stopped by OS, so we can safely inspect it without it moving on us.
1498 // 
1499 // Notes:
1500 //    This can be called eagerly to sniff if the LS is initialized.
1501 //
1502 //---------------------------------------------------------------------------------------
1503 BOOL CordbProcess::TryInitializeDac()
1504 {
1505     CONTRACTL
1506     {
1507         THROWS;
1508     }
1509     CONTRACTL_END;
1510
1511     // Target is stopped by OS, so we can safely inspect it without it moving on us.
1512
1513     // We want to avoid exceptions in the normal case, so we do some pre-checks 
1514     // to detect failure without relying on exceptions.
1515     // Can't initialize DAC until mscorwks is loaded. So that's a sanity test.    
1516     HRESULT hr = EnsureClrInstanceIdSet();
1517     if (FAILED(hr))
1518     {
1519         return FALSE;
1520     }
1521
1522     // By this point, we know which CLR in the target to debug. That means there is a CLR
1523     // in the target, and it's safe to initialize DAC.
1524     _ASSERTE(m_clrInstanceId != 0);
1525
1526     // Now expect it to succeed
1527     InitializeDac();
1528     return TRUE;
1529 }
1530
1531 //---------------------------------------------------------------------------------------
1532 //
1533 // Load & Init DAC, expecting to succeed.
1534 //
1535 // Return Value:
1536 //    Throws on failure. 
1537 //
1538 // Assumptions:
1539 //    Caller invokes this at a point where they can expect it to succeed.
1540 //    This is called early in the startup path because DAC is needed for accessing
1541 //    data in the target.
1542 //
1543 // Notes:
1544 //    This needs to succeed, and should always succeed (baring a bad installation)
1545 //    so we assert on failure paths.
1546 //    This may be called mutliple times. 
1547 //
1548 //---------------------------------------------------------------------------------------
1549 void CordbProcess::InitializeDac()
1550 {
1551     CONTRACTL
1552     {
1553         THROWS;
1554     }
1555     CONTRACTL_END;
1556     INTERNAL_API_ENTRY(this);
1557
1558     // For Mac debugginger, m_hDacModule is not used, and it will always be NULL.  To check whether DAC has
1559     // been initialized, we need to check something else, namely m_pDacPrimitives.
1560     if (m_pDacPrimitives == NULL)
1561     {
1562         LOG((LF_CORDB, LL_INFO1000, "About to load DAC\n"));
1563         CreateDacDbiInterface(); // throws
1564     }
1565     else
1566     {
1567         LOG((LF_CORDB, LL_INFO1000, "Dac already loaded, 0x%p\n", (HMODULE)m_hDacModule));
1568     }
1569     
1570     // Always flush dac.    
1571     ForceDacFlush();
1572 }
1573
1574 //---------------------------------------------------------------------------------------
1575 //
1576 // Free DAC resources
1577 //
1578 // Notes:
1579 //    This should clean up state such that code:CordbProcess::InitializeDac could be called again. 
1580 //
1581 //---------------------------------------------------------------------------------------
1582 void CordbProcess::FreeDac()
1583 {
1584     CONTRACTL
1585     {
1586         NOTHROW; // backout code.
1587     }
1588     CONTRACTL_END;
1589
1590     if (m_pDacPrimitives != NULL)
1591     {
1592         m_pDacPrimitives->Destroy();
1593         m_pDacPrimitives = NULL;
1594     }
1595
1596     if (m_hDacModule != NULL)
1597     {
1598         LOG((LF_CORDB, LL_INFO1000, "Unloading DAC\n"));
1599         m_hDacModule.Clear();
1600     }
1601 }
1602
1603 IEventChannel * CordbProcess::GetEventChannel()
1604 {
1605     _ASSERTE(m_pEventChannel != NULL);
1606     return m_pEventChannel;
1607 }
1608
1609 //---------------------------------------------------------------------------------------
1610 // Mark that the process is being interop-debugged.
1611 //
1612 // Notes:
1613 //   @dbgtodo shim: this should eventually move into the shim or go away. 
1614 //   It's only to support V2 legacy interop-debugging.
1615 //   Called after code:CordbProcess::Init if we want to enable interop debugging.
1616 //   This allows us to separate out Interop-debugging flags from the core initialization,
1617 //   and paves the way for us to eventually remove it.
1618 //   
1619 //   Since we're always on the naitve-pipeline, the Enabling interop debugging just changes
1620 //   how the native debug events are being handled. So this must be called after Init, but
1621 //   before any events are actually handled.
1622 //   This mus be calle on the win32 event thread to gaurantee that it's called before WFDE.
1623 void CordbProcess::EnableInteropDebugging()
1624 {
1625     CONTRACTL
1626     {
1627         THROWS;
1628         PRECONDITION(m_pShim != NULL);
1629     }
1630     CONTRACTL_END;
1631
1632     // Must be on W32ET to gaurantee that we're called after Init yet before WFDE (which
1633     // are both called on the W32et).
1634     _ASSERTE(IsWin32EventThread());
1635 #ifdef FEATURE_INTEROP_DEBUGGING
1636
1637     m_state |= PS_WIN32_ATTACHED;
1638     if (GetDCB() != NULL)
1639     {
1640         GetDCB()->m_rightSideIsWin32Debugger = true; 
1641         UpdateLeftSideDCBField(&(GetDCB()->m_rightSideIsWin32Debugger), sizeof(GetDCB()->m_rightSideIsWin32Debugger));
1642     }
1643
1644     // Tell the Shim we're interop-debugging.
1645     m_pShim->SetIsInteropDebugging(true);
1646 #else
1647     ThrowHR(CORDBG_E_INTEROP_NOT_SUPPORTED);
1648 #endif
1649 }
1650
1651 //---------------------------------------------------------------------------------------
1652 //
1653 // Init -- create any objects that the process object needs to operate.
1654 //
1655 // Arguments:
1656 //
1657 // Return Value:
1658 //    S_OK on success
1659 //
1660 // Assumptions:
1661 //    Called on Win32 Event Thread, after OS debugging pipeline is established but
1662 //    before WaitForDebugEvent / ContinueDebugEvent. This means the target is stopped.
1663 //
1664 // Notes:
1665 //    To enable interop-debugging, call code:CordbProcess::EnableInteropDebugging
1666 //---------------------------------------------------------------------------------------
1667 HRESULT CordbProcess::Init()
1668 {
1669     INTERNAL_API_ENTRY(this);
1670     
1671     HRESULT hr = S_OK;
1672     BOOL fIsLSStarted = FALSE; // see meaning below.
1673
1674     FAIL_IF_NEUTERED(this);
1675
1676
1677     EX_TRY
1678     {
1679         m_processMutex.Init("Process Lock", RSLock::cLockReentrant, RSLock::LL_PROCESS_LOCK);
1680         m_StopGoLock.Init("Stop-Go Lock", RSLock::cLockReentrant, RSLock::LL_STOP_GO_LOCK);
1681
1682 #ifdef _DEBUG
1683         m_appDomains.DebugSetRSLock(GetProcessLock());
1684         m_userThreads.DebugSetRSLock(GetProcessLock());
1685 #ifdef FEATURE_INTEROP_DEBUGGING
1686         m_unmanagedThreads.DebugSetRSLock(GetProcessLock());
1687 #endif
1688         m_steppers.DebugSetRSLock(GetProcessLock());
1689 #endif
1690
1691         // See if the data target is mutable, and cache the mutable interface if it is
1692         // We must initialize this before we try to use the data target to access the memory in the target process.
1693         m_pMutableDataTarget.Clear();            // if we were called already, release
1694         hr = m_pDACDataTarget->QueryInterface(IID_ICorDebugMutableDataTarget, (void**)&m_pMutableDataTarget);
1695         if (!SUCCEEDED(hr))
1696         {
1697             // The data target doesn't support mutation.  We'll fail any requests that require mutation.
1698             m_pMutableDataTarget.Assign(new ReadOnlyDataTargetFacade());
1699         }
1700
1701         m_pMetaDataLocator.Clear();
1702         hr = m_pDACDataTarget->QueryInterface(IID_ICorDebugMetaDataLocator, reinterpret_cast<void **>(&m_pMetaDataLocator));
1703         
1704         // Get the metadata dispenser.        
1705         hr = InternalCreateMetaDataDispenser(IID_IMetaDataDispenserEx, (void **)&m_pMetaDispenser);
1706
1707         // We statically link in the dispenser. We expect it to succeed, except for OOM, which 
1708         // debugger doesn't yet handle.
1709         SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr); 
1710         IfFailThrow(hr);
1711
1712         _ASSERTE(m_pMetaDispenser != NULL);
1713
1714         // In order to allow users to call the metadata reader from multiple threads we need to set
1715         // a flag on the dispenser to create threadsafe readers. This is done best-effort but
1716         // really shouldn't ever fail. See issue 696511.
1717         VARIANT optionValue;
1718         VariantInit(&optionValue);
1719         V_VT(&optionValue) = VT_UI4;
1720         V_UI4(&optionValue) = MDThreadSafetyOn;
1721         m_pMetaDispenser->SetOption(MetaDataThreadSafetyOptions, &optionValue);
1722
1723         //
1724         // Setup internal events.
1725         // @dbgtodo shim: these events should eventually be in the shim.
1726         //
1727
1728
1729         // Managed debugging is built on the native-pipeline, and that will detect against double-attaches.
1730
1731         // @dbgtodo shim: In V2, LSEA + LSER were used by the LS's helper thread. Now with the V3 pipeline,
1732         // that helper-thread uses native-debug events. The W32ET gets those events and then uses LSEA, LSER to 
1733         // signal existing RS infrastructure. Eventually get rid of LSEA, LSER completely.
1734         // 
1735
1736         m_leftSideEventAvailable = WszCreateEvent(NULL, FALSE, FALSE, NULL);
1737         if (m_leftSideEventAvailable == NULL)
1738         {
1739             ThrowLastError();
1740         }
1741
1742         m_leftSideEventRead = WszCreateEvent(NULL, FALSE, FALSE, NULL);
1743         if (m_leftSideEventRead == NULL)
1744         {
1745             ThrowLastError();
1746         }
1747
1748         m_stopWaitEvent = WszCreateEvent(NULL, TRUE, FALSE, NULL);
1749         if (m_stopWaitEvent == NULL)
1750         {
1751             ThrowLastError();
1752         }
1753
1754         if (m_pShim != NULL)
1755         {
1756             // Get a handle to the debuggee.
1757             // This is not needed in the V3 pipeline because we don't assume we have a live, local, process.
1758             m_handle = GetShim()->GetNativePipeline()->GetProcessHandle();
1759
1760             if (m_handle == NULL)
1761             {
1762                 ThrowLastError();
1763             }
1764         }
1765
1766         // The LS startup goes through the following phases:
1767         // 1) mscorwks not yet loaded (eg, any unmanaged app)
1768         // 2) mscorwks loaded (DAC can now be used)
1769         // 3) IPC Block created at OS level
1770         // 4) IPC block data initialized (so we can read meainingful data from it)
1771         // 5) LS marks that it's initialized (queryable by a DAC primitive) (may not be atomic)
1772         // 6) LS fires a "Startup" exception (sniffed by WFDE).
1773         //
1774         // LS is currently stopped by OS debugging, so it's doesn't shift phases.
1775         // From the RS's perspective:
1776         // - after phase 5 is an attach
1777         // - before phase 6 is a launch.
1778         // This means there's an overlap: if we catch it at phase 5, we'll just get
1779         // an extra Startup exception from phase 6, which is safe. This overlap is good
1780         // because it means there's no bad window to do an attach in.
1781         
1782         // fIsLSStarted means before phase 6 (eg, RS should expect a startup exception)
1783
1784         // Determines if the LS is started.
1785         
1786         {
1787             BOOL fReady = TryInitializeDac();
1788
1789             if (fReady)
1790             {
1791                 // Invoke DAC primitive.
1792                 _ASSERTE(m_pDacPrimitives != NULL);
1793                 fIsLSStarted = m_pDacPrimitives->IsLeftSideInitialized();
1794             }
1795             else 
1796             {
1797                 _ASSERTE(m_pDacPrimitives == NULL);
1798
1799                 // DAC is not yet loaded, so we're at least before phase 2, which is before phase 6.
1800                 // So leave fIsLSStarted = false. We'll get a startup exception later.
1801                 _ASSERTE(!fIsLSStarted);
1802             }
1803         }
1804         
1805         
1806         if (fIsLSStarted)
1807         {
1808             // Left-side has started up. This is common for Attach cases when managed-code is already running.
1809
1810             if (m_pShim != NULL)
1811             {
1812                 FinishInitializeIPCChannelWorker(); // throws
1813
1814                 // At this point, the control block is complete and all four
1815                 // events are available and valid for the remote process.
1816
1817                 // Request that the process object send an Attach IPC event.
1818                 // This is only used in an attach case.
1819                 // @dbgtodo sync: this flag can go away once the
1820                 // shim can use real sync APIs.
1821                 m_fDoDelayedManagedAttached = true;
1822             }
1823             else
1824             {
1825                 // In the V3 pipeline case, if we have the DD-interface, then the runtime is loaded 
1826                 // and we consider it initialized.
1827                 if (IsDacInitialized())
1828                 {
1829                     m_initialized = true;
1830                 }
1831             }
1832         }
1833         else
1834         {
1835             // LS is not started yet. This would be common for "Launch" cases.
1836             // We will get a Startup Exception notification when it does start.
1837         }
1838     }
1839     EX_CATCH_HRESULT(hr);
1840
1841     if (FAILED(hr))
1842     {
1843         CleanupHalfBakedLeftSide();
1844     }
1845
1846     return hr;
1847 }
1848
1849
1850 COM_METHOD CordbProcess::CanCommitChanges(ULONG cSnapshots,
1851                 ICorDebugEditAndContinueSnapshot *pSnapshots[],
1852                 ICorDebugErrorInfoEnum **pError)
1853 {
1854     return E_NOTIMPL;
1855 }
1856
1857 COM_METHOD CordbProcess::CommitChanges(ULONG cSnapshots,
1858     ICorDebugEditAndContinueSnapshot *pSnapshots[],
1859     ICorDebugErrorInfoEnum **pError)
1860 {
1861     return E_NOTIMPL;
1862 }
1863
1864
1865 //
1866 // Terminating -- places the process into the terminated state. This should
1867 // also get any blocking process functions unblocked so they'll return
1868 // a failure code.
1869 //
1870 void CordbProcess::Terminating(BOOL fDetach)
1871 {
1872     INTERNAL_API_ENTRY(this);
1873
1874     LOG((LF_CORDB, LL_INFO1000,"CP::T: Terminating process 0x%x detach=%d\n", m_id, fDetach));
1875     m_terminated = true;
1876
1877     m_cordb->ProcessStateChanged();
1878
1879     // Set events that may be blocking stuff.
1880     // But don't set RSER unless we actually read the event. We don't block on RSER
1881     // since that wait also checks the leftside's process handle.
1882     SetEvent(m_leftSideEventRead);
1883     SetEvent(m_leftSideEventAvailable);
1884     SetEvent(m_stopWaitEvent);
1885
1886     if (m_pShim != NULL)
1887         m_pShim->SetTerminatingEvent();
1888
1889     if (fDetach && (m_pEventChannel != NULL))
1890     {
1891         m_pEventChannel->Detach();
1892     }
1893 }
1894
1895
1896 // Wrapper to give shim access to code:CordbProcess::QueueManagedAttachIfNeededWorker
1897 void CordbProcess::QueueManagedAttachIfNeeded()
1898 {
1899     PUBLIC_API_ENTRY_FOR_SHIM(this);
1900     QueueManagedAttachIfNeededWorker();
1901 }
1902
1903 //---------------------------------------------------------------------------------------
1904 // Hook from Shim to request a managed attach IPC event
1905 // 
1906 // Notes:
1907 //   Called by shim after the loader-breakpoint is handled. 
1908 //   @dbgtodo sync: ths should go away once the shim can initiate
1909 //   a sync 
1910 void CordbProcess::QueueManagedAttachIfNeededWorker()
1911 {
1912     HRESULT hrQueue = S_OK;
1913
1914     // m_fDoDelayedManagedAttached ensures that we only send an Attach event if the LS is actually present.
1915     if (m_fDoDelayedManagedAttached && GetShim()->GetAttached())
1916     {
1917         RSLockHolder lockHolder(&this->m_processMutex);            
1918         GetDAC()->MarkDebuggerAttachPending();                            
1919
1920         hrQueue = this->QueueManagedAttach();
1921     } 
1922     
1923     if (m_pShim != NULL)
1924         m_pShim->SetMarkAttachPendingEvent();
1925     
1926     IfFailThrow(hrQueue); 
1927 }
1928
1929 //---------------------------------------------------------------------------------------
1930 //
1931 // QueueManagedAttach
1932 //
1933 // Send a managed attach. This is asynchronous and will return immediately.
1934 //
1935 // Return Value:
1936 //    S_OK on success
1937 //
1938 //---------------------------------------------------------------------------------------
1939 HRESULT CordbProcess::QueueManagedAttach()
1940 {
1941     INTERNAL_API_ENTRY(this);
1942
1943     _ASSERTE(ThreadHoldsProcessLock());
1944
1945     _ASSERTE(m_fDoDelayedManagedAttached);
1946     m_fDoDelayedManagedAttached = false;
1947
1948     _ASSERTE(IsDacInitialized());
1949
1950     // We don't know what Queue it.
1951     SendAttachProcessWorkItem * pItem = new (nothrow) SendAttachProcessWorkItem(this);
1952     
1953     if (pItem == NULL)
1954     {
1955         return E_OUTOFMEMORY;
1956     }
1957     
1958     this->m_cordb->m_rcEventThread->QueueAsyncWorkItem(pItem);
1959     
1960     return S_OK;
1961 }
1962
1963 // However, we still want to synchronize.
1964 // @dbgtodo sync: when we hoist attaching, we can send an DB_IPCE_ASYNC_BREAK event instead or Attach 
1965 // (for V2 semantics, we still need to synchronize the process)?
1966 void SendAttachProcessWorkItem::Do()
1967 {
1968     HRESULT hr;
1969
1970     // This is being processed on the RCET, where it's safe to take the Stop-Go lock.
1971     RSLockHolder ch(this->GetProcess()->GetStopGoLock());
1972
1973     DebuggerIPCEvent *event = (DebuggerIPCEvent*) _alloca(CorDBIPC_BUFFER_SIZE);
1974     
1975     // This just acts like an async-break, which will kick off things.
1976     // This will not induce any faked attach events from the VM (like it did in V2).
1977     // The Left-side will still slip foward allowing the async-break to happen, so 
1978     // we may get normal debug events in addition to the sync-complete.
1979     //
1980     // 1. In the common attach case, we should just get a sync-complete.
1981     // 2. In Jit-attach cases, the LS is sending an event, and so we'll get that event and then the sync-complete.
1982     GetProcess()->InitAsyncIPCEvent(event, DB_IPCE_ATTACHING, VMPTR_AppDomain::NullPtr());
1983
1984     // This should result in a sync-complete from the Left-side, which will be raised as an exception
1985     // that the debugger passes into Filter and then internally goes through code:CordbProcess::TriageSyncComplete 
1986     // and that triggers code:CordbRCEventThread::FlushQueuedEvents to be called on the RCET.
1987     // We already pre-queued a fake CreateProcess event.
1988
1989     // The left-side will also mark itself as attached in response to this event. 
1990     // We explicitly don't mark it as attached from the right-side because we want to let the left-side 
1991     // synchronize first (to stop all running threads) before marking the debugger as attached.
1992     LOG((LF_CORDB, LL_INFO1000, "[%x] CP::S: sending attach.\n", GetCurrentThreadId()));
1993
1994     hr = GetProcess()->SendIPCEvent(event, CorDBIPC_BUFFER_SIZE);
1995
1996     LOG((LF_CORDB, LL_INFO1000, "[%x] CP::S: sent attach.\n", GetCurrentThreadId()));
1997 }
1998
1999 //---------------------------------------------------------------------------------------
2000 // Try to lookup a cached thread object
2001 //
2002 // Arguments:
2003 //     vmThread - vm identifier for thread.
2004 //
2005 // Returns:
2006 //     Thread object if cached; null if not yet cached.
2007 //
2008 // Notes:
2009 //     This does not create the thread object if it's not cached. Caching is unpredictable,
2010 //     and so this may appear to randomly return NULL. 
2011 //     Callers should prefer code:CordbProcess::LookupOrCreateThread unless they expicitly
2012 //     want to check RS state.
2013 CordbThread * CordbProcess::TryLookupThread(VMPTR_Thread vmThread)
2014 {
2015     return m_userThreads.GetBase(VmPtrToCookie(vmThread));
2016 }
2017
2018 //---------------------------------------------------------------------------------------
2019 // Lookup (or create) a CordbThread object by the given volatile OS id. Returns null if not a manged thread
2020 //
2021 // Arguments:
2022 //      dwThreadId - os thread id that a managed thread may be using.
2023 //
2024 // Returns:
2025 //      Thread instance if there is currently a managed thread scheduled to run on dwThreadId.
2026 //      NULL if this tid is not a valid Managed thread. (This is considered a common case)
2027 //      Throws on error.
2028 //
2029 // Notes:
2030 //      OS Thread ID is not fiber-safe, so this is a dangerous function to call.
2031 //      Avoid this as much as possible. Prefer using VMPTR_Thread and 
2032 //      code:CordbProcess::LookupOrCreateThread instead of OS thread IDs.
2033 //      See code:CordbThread::GetID for details.
2034 CordbThread * CordbProcess::TryLookupOrCreateThreadByVolatileOSId(DWORD dwThreadId)
2035 {
2036     PrepopulateThreadsOrThrow();
2037     return TryLookupThreadByVolatileOSId(dwThreadId);
2038 }
2039
2040 //---------------------------------------------------------------------------------------
2041 // Lookup a cached CordbThread object by the tid. Returns null if not in the cache (which 
2042 // includes unmanged thread)
2043 //
2044 // Arguments:
2045 //      dwThreadId - os thread id that a managed thread may be using.
2046 //
2047 // Returns:
2048 //      Thread instance if there is currently a managed thread scheduled to run on dwThreadId.
2049 //      NULL if this tid is not a valid Managed thread. (This is considered a common case)
2050 //      Throws on error.
2051 //
2052 // Notes:
2053 //   Avoids this method:
2054 //   * OS Thread ID is not fiber-safe, so this is a dangerous function to call.
2055 //   * This is juts a Lookup, not LookupOrCreate, so it should only be used by methods
2056 //    that care about the RS state (instead of just LS state).
2057 //   Prefer using VMPTR_Thread and code:CordbProcess::LookupOrCreateThread 
2058 //
2059 CordbThread * CordbProcess::TryLookupThreadByVolatileOSId(DWORD dwThreadId)
2060 {
2061     HASHFIND find;
2062     for (CordbThread * pThread = m_userThreads.FindFirst(&find);
2063          pThread != NULL;
2064          pThread =  m_userThreads.FindNext(&find))
2065     {
2066         _ASSERTE(pThread != NULL);
2067
2068         // Get the OS tid. This returns 0 if the thread is switched out.
2069         DWORD dwThreadId2 = GetDAC()->TryGetVolatileOSThreadID(pThread->m_vmThreadToken);
2070         if (dwThreadId2 == dwThreadId)
2071         {
2072             return pThread;
2073         }
2074     }
2075
2076     // This OS thread ID does not match any managed thread id.
2077     return NULL; 
2078 }
2079
2080 //---------------------------------------------------------------------------------------
2081 // Preferred CordbThread lookup routine.
2082 //
2083 // Arguments:
2084 //     vmThread - LS thread to lookup. Must be non-null.
2085 //
2086 // Returns:
2087 //     CordbThread instance for given vmThread. May return a previously cached
2088 //     instance or create a new instance. Never returns NULL.
2089 //     Throw on error.
2090 CordbThread * CordbProcess::LookupOrCreateThread(VMPTR_Thread vmThread)
2091 {
2092     _ASSERTE(!vmThread.IsNull());
2093
2094     // Return if we have an existing instance.
2095     CordbThread * pReturn = TryLookupThread(vmThread);
2096     if (pReturn != NULL)
2097     {
2098         return pReturn;
2099     }
2100
2101     RSInitHolder<CordbThread> pThread(new CordbThread(this, vmThread)); // throws
2102     pReturn = pThread.TransferOwnershipToHash(&m_userThreads);
2103
2104     return pReturn;
2105 }
2106
2107
2108
2109
2110 HRESULT CordbProcess::QueryInterface(REFIID id, void **pInterface)
2111 {
2112     if (id == IID_ICorDebugProcess)
2113     {
2114         *pInterface = static_cast<ICorDebugProcess*>(this);
2115     }
2116     else if (id == IID_ICorDebugController)
2117     {
2118         *pInterface = static_cast<ICorDebugController*>(static_cast<ICorDebugProcess*>(this));
2119     }
2120     else if (id == IID_ICorDebugProcess2)
2121
2122     {
2123         *pInterface = static_cast<ICorDebugProcess2*>(this);
2124     }
2125     else if (id == IID_ICorDebugProcess3)
2126     {
2127         *pInterface = static_cast<ICorDebugProcess3*>(this);
2128     }
2129     else if (id == IID_ICorDebugProcess4)
2130     {
2131         *pInterface = static_cast<ICorDebugProcess4*>(this);
2132     }
2133     else if (id == IID_ICorDebugProcess5)
2134     {
2135         *pInterface = static_cast<ICorDebugProcess5*>(this);
2136     }
2137     else if (id == IID_ICorDebugProcess7)
2138     {
2139         *pInterface = static_cast<ICorDebugProcess7*>(this);
2140     }
2141     else if (id == IID_ICorDebugProcess8)
2142     {
2143         *pInterface = static_cast<ICorDebugProcess8*>(this);
2144     }
2145 #ifdef FEATURE_LEGACYNETCF_DBG_HOST_CONTROL
2146     else if (id == IID_ICorDebugLegacyNetCFHostCallbackInvoker_PrivateWindowsPhoneOnly)
2147     {
2148         *pInterface = static_cast<ICorDebugLegacyNetCFHostCallbackInvoker_PrivateWindowsPhoneOnly*>(this);
2149     }
2150 #endif
2151     else if (id == IID_IUnknown)
2152     {
2153         *pInterface = static_cast<IUnknown*>(static_cast<ICorDebugProcess*>(this));
2154     }
2155
2156     else
2157     {
2158         *pInterface = NULL;
2159         return E_NOINTERFACE;
2160     }
2161
2162     ExternalAddRef();
2163     return S_OK;
2164 }
2165
2166
2167
2168
2169 // Public implementation of ICorDebugProcess4::ProcessStateChanged
2170 HRESULT CordbProcess::ProcessStateChanged(CorDebugStateChange eChange)
2171 {
2172     HRESULT hr = S_OK;
2173     PUBLIC_API_BEGIN(this)            
2174     {        
2175         switch(eChange)
2176         {
2177         case PROCESS_RUNNING:            
2178             FlushProcessRunning();                
2179             break;
2180
2181         case FLUSH_ALL:
2182             FlushAll();
2183             break;
2184
2185         default:
2186             ThrowHR(E_INVALIDARG);
2187
2188         }
2189     }
2190     PUBLIC_API_END(hr);
2191     return hr;
2192 }
2193
2194
2195 HRESULT CordbProcess::EnumerateHeap(ICorDebugHeapEnum **ppObjects)
2196 {
2197     if (!ppObjects)
2198         return E_POINTER;
2199     
2200     HRESULT hr = S_OK;
2201     PUBLIC_API_ENTRY(this);
2202     ATT_REQUIRE_STOPPED_MAY_FAIL(this);
2203     
2204     EX_TRY
2205     {
2206         if (m_pDacPrimitives->AreGCStructuresValid())
2207         {
2208             CordbHeapEnum *pHeapEnum = new CordbHeapEnum(this);
2209             GetContinueNeuterList()->Add(this, pHeapEnum);
2210             hr = pHeapEnum->QueryInterface(__uuidof(ICorDebugHeapEnum), (void**)ppObjects);
2211         }
2212         else
2213         {
2214             hr = CORDBG_E_GC_STRUCTURES_INVALID;
2215         }
2216     } 
2217     EX_CATCH_HRESULT(hr);
2218     
2219     return hr;
2220 }
2221
2222 HRESULT CordbProcess::GetGCHeapInformation(COR_HEAPINFO *pHeapInfo)
2223 {
2224     if (!pHeapInfo)
2225         return E_INVALIDARG;
2226         
2227     HRESULT hr = S_OK;
2228     PUBLIC_API_ENTRY(this);
2229     ATT_REQUIRE_STOPPED_MAY_FAIL(this);
2230     
2231     EX_TRY
2232     {
2233         GetDAC()->GetGCHeapInformation(pHeapInfo);
2234     }
2235     EX_CATCH_HRESULT(hr);
2236     
2237     return hr;
2238 }
2239
2240 HRESULT CordbProcess::EnumerateHeapRegions(ICorDebugHeapSegmentEnum **ppRegions)
2241 {
2242     if (!ppRegions)
2243         return E_INVALIDARG;
2244
2245     HRESULT hr = S_OK;
2246     PUBLIC_API_ENTRY(this);
2247     ATT_REQUIRE_STOPPED_MAY_FAIL(this);
2248     
2249     EX_TRY
2250     {
2251         DacDbiArrayList<COR_SEGMENT> segments;
2252         hr = GetDAC()->GetHeapSegments(&segments);
2253         
2254         if (SUCCEEDED(hr))
2255         {
2256             if (!segments.IsEmpty())
2257             {
2258                 CordbHeapSegmentEnumerator *segEnum = new CordbHeapSegmentEnumerator(this, &segments[0], (DWORD)segments.Count());
2259                 GetContinueNeuterList()->Add(this, segEnum);
2260                 hr = segEnum->QueryInterface(__uuidof(ICorDebugHeapSegmentEnum), (void**)ppRegions);
2261             }
2262             else
2263             {
2264                 hr = E_OUTOFMEMORY;
2265             }
2266         }
2267     }
2268     EX_CATCH_HRESULT(hr);
2269     
2270     return hr;
2271 }
2272
2273 HRESULT CordbProcess::GetObject(CORDB_ADDRESS addr, ICorDebugObjectValue **pObject)
2274 {
2275     HRESULT hr = S_OK;
2276     
2277     PUBLIC_REENTRANT_API_ENTRY(this);
2278     ATT_REQUIRE_STOPPED_MAY_FAIL(this);
2279     
2280     EX_TRY
2281     {
2282         if (!m_pDacPrimitives->IsValidObject(addr))
2283         {
2284             hr = CORDBG_E_CORRUPT_OBJECT;
2285         }
2286         else if (pObject == NULL)
2287         {
2288             hr = E_INVALIDARG;
2289         }
2290         else
2291         {
2292             RSLockHolder ch(GetProcess()->GetStopGoLock());
2293             RSLockHolder procLock(this->GetProcess()->GetProcessLock());
2294             
2295             CordbAppDomain *cdbAppDomain = NULL;
2296             CordbType *pType = NULL;
2297             hr = GetTypeForObject(addr, &pType, &cdbAppDomain);
2298             
2299             if (SUCCEEDED(hr))
2300             {
2301                 _ASSERTE(pType != NULL);
2302                 _ASSERTE(cdbAppDomain != NULL);
2303                 
2304                 DebuggerIPCE_ObjectData objData;
2305                 m_pDacPrimitives->GetBasicObjectInfo(addr, ELEMENT_TYPE_CLASS, cdbAppDomain->GetADToken(), &objData);
2306                 
2307                 NewHolder<CordbObjectValue> pNewObjectValue(new CordbObjectValue(cdbAppDomain, pType, TargetBuffer(addr, (ULONG)objData.objSize), &objData));
2308                 hr = pNewObjectValue->Init();
2309                 
2310                 if (SUCCEEDED(hr))
2311                 {
2312                     hr = pNewObjectValue->QueryInterface(__uuidof(ICorDebugObjectValue), (void**)pObject);
2313                     if (SUCCEEDED(hr))
2314                         pNewObjectValue.SuppressRelease();
2315                 }
2316             }
2317         }
2318     }
2319     EX_CATCH_HRESULT(hr);
2320
2321     return hr;
2322 }
2323
2324
2325 HRESULT CordbProcess::EnumerateGCReferences(BOOL enumerateWeakReferences, ICorDebugGCReferenceEnum **ppEnum)
2326 {
2327     if (!ppEnum)
2328         return E_POINTER;
2329         
2330     HRESULT hr = S_OK;
2331     PUBLIC_API_ENTRY(this);
2332     ATT_REQUIRE_STOPPED_MAY_FAIL(this);
2333     
2334     EX_TRY
2335     {
2336         CordbRefEnum *pRefEnum = new CordbRefEnum(this, enumerateWeakReferences);
2337         GetContinueNeuterList()->Add(this, pRefEnum);
2338         hr = pRefEnum->QueryInterface(IID_ICorDebugGCReferenceEnum, (void**)ppEnum);
2339     }
2340     EX_CATCH_HRESULT(hr);
2341     return hr;
2342 }
2343
2344 HRESULT CordbProcess::EnumerateHandles(CorGCReferenceType types, ICorDebugGCReferenceEnum **ppEnum)
2345 {
2346     if (!ppEnum)
2347         return E_POINTER;
2348         
2349     HRESULT hr = S_OK;
2350     PUBLIC_API_ENTRY(this);
2351     ATT_REQUIRE_STOPPED_MAY_FAIL(this);
2352     
2353     EX_TRY
2354     {
2355         CordbRefEnum *pRefEnum = new CordbRefEnum(this, types);
2356         GetContinueNeuterList()->Add(this, pRefEnum);
2357         hr = pRefEnum->QueryInterface(IID_ICorDebugGCReferenceEnum, (void**)ppEnum);
2358     }
2359     EX_CATCH_HRESULT(hr);
2360     
2361     return hr;
2362 }
2363
2364 HRESULT CordbProcess::EnableNGENPolicy(CorDebugNGENPolicy ePolicy)
2365 {
2366     return E_NOTIMPL;
2367 }
2368
2369
2370 HRESULT CordbProcess::GetTypeID(CORDB_ADDRESS obj, COR_TYPEID *pId)
2371 {
2372     if (pId == NULL)
2373         return E_POINTER;
2374         
2375     HRESULT hr = S_OK;
2376     PUBLIC_API_ENTRY(this);
2377     ATT_REQUIRE_STOPPED_MAY_FAIL(this);
2378     
2379     EX_TRY
2380     {
2381         hr = GetProcess()->GetDAC()->GetTypeID(obj, pId);
2382     }
2383     EX_CATCH_HRESULT(hr);
2384     
2385     return hr;
2386 }
2387
2388 HRESULT CordbProcess::GetTypeForTypeID(COR_TYPEID id, ICorDebugType **ppType)
2389 {
2390     if (ppType == NULL)
2391         return E_POINTER;
2392         
2393     HRESULT hr = S_OK;
2394     
2395     PUBLIC_API_ENTRY(this);
2396     RSLockHolder stopGoLock(this->GetProcess()->GetStopGoLock());
2397     RSLockHolder procLock(this->GetProcess()->GetProcessLock());
2398     
2399     EX_TRY
2400     {
2401         DebuggerIPCE_ExpandedTypeData data;
2402         GetDAC()->GetObjectExpandedTypeInfoFromID(AllBoxed, VMPTR_AppDomain::NullPtr(), id, &data);
2403
2404         CordbType *type = 0;
2405         hr = CordbType::TypeDataToType(GetSharedAppDomain(), &data, &type);
2406
2407         if (SUCCEEDED(hr))
2408             hr = type->QueryInterface(IID_ICorDebugType, (void**)ppType);
2409     } 
2410     EX_CATCH_HRESULT(hr);
2411
2412     return hr;
2413 }
2414
2415
2416 COM_METHOD CordbProcess::GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT *pLayout)
2417 {
2418     if (pLayout == NULL)
2419         return E_POINTER;
2420         
2421     HRESULT hr = S_OK;
2422     PUBLIC_API_BEGIN(this);
2423
2424     hr = GetProcess()->GetDAC()->GetArrayLayout(id, pLayout);
2425     
2426     PUBLIC_API_END(hr);
2427     return hr;
2428 }
2429
2430 COM_METHOD CordbProcess::GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT *pLayout)
2431 {
2432     if (pLayout == NULL)
2433         return E_POINTER;
2434         
2435     HRESULT hr = S_OK;
2436     PUBLIC_API_BEGIN(this);
2437     
2438     hr = GetProcess()->GetDAC()->GetTypeLayout(id, pLayout);
2439     
2440     PUBLIC_API_END(hr);
2441     return hr;
2442 }
2443
2444 COM_METHOD CordbProcess::GetTypeFields(COR_TYPEID id, ULONG32 celt, COR_FIELD fields[], ULONG32 *pceltNeeded)
2445 {
2446     HRESULT hr = S_OK;
2447     PUBLIC_API_BEGIN(this);
2448     
2449     hr = GetProcess()->GetDAC()->GetObjectFields(id, celt, fields, pceltNeeded);
2450     
2451     PUBLIC_API_END(hr);
2452     return hr;
2453 }
2454
2455 COM_METHOD CordbProcess::SetWriteableMetadataUpdateMode(WriteableMetadataUpdateMode flags)
2456 {
2457     HRESULT hr = S_OK;
2458     PUBLIC_API_BEGIN(this);
2459     
2460     if(flags != LegacyCompatPolicy &&
2461        flags != AlwaysShowUpdates)
2462     {
2463         hr = E_INVALIDARG;
2464     }
2465     else if(m_pShim != NULL)
2466     {
2467         if(flags != LegacyCompatPolicy)
2468         {
2469             hr = CORDBG_E_UNSUPPORTED;
2470         }
2471     }
2472
2473     if(SUCCEEDED(hr))
2474     {
2475         m_writableMetadataUpdateMode = flags;
2476     }
2477     
2478     PUBLIC_API_END(hr);
2479     return hr;
2480 }
2481
2482 COM_METHOD CordbProcess::EnableExceptionCallbacksOutsideOfMyCode(BOOL enableExceptionsOutsideOfJMC)
2483 {
2484     HRESULT hr = S_OK;
2485     PUBLIC_API_BEGIN(this);
2486
2487     hr = GetProcess()->GetDAC()->SetSendExceptionsOutsideOfJMC(enableExceptionsOutsideOfJMC);
2488
2489     PUBLIC_API_END(hr);
2490     return hr;
2491 }
2492
2493 #ifdef FEATURE_LEGACYNETCF_DBG_HOST_CONTROL
2494
2495 COM_METHOD CordbProcess::InvokePauseCallback()
2496 {
2497     return S_OK;
2498 }
2499
2500 COM_METHOD CordbProcess::InvokeResumeCallback()
2501 {
2502     return S_OK;
2503 }
2504
2505 #endif
2506
2507 HRESULT CordbProcess::GetTypeForObject(CORDB_ADDRESS addr, CordbType **ppType, CordbAppDomain **pAppDomain)
2508 {
2509     VMPTR_AppDomain appDomain;
2510     VMPTR_Module mod;
2511     VMPTR_DomainFile domainFile;
2512     
2513     HRESULT hr = E_FAIL;
2514     if (GetDAC()->GetAppDomainForObject(addr, &appDomain, &mod, &domainFile))
2515     {
2516         CordbAppDomain *cdbAppDomain = appDomain.IsNull() ? GetSharedAppDomain() : LookupOrCreateAppDomain(appDomain);
2517         
2518         _ASSERTE(cdbAppDomain);
2519         
2520         DebuggerIPCE_ExpandedTypeData data;
2521         GetDAC()->GetObjectExpandedTypeInfo(AllBoxed, appDomain, addr, &data);
2522
2523         CordbType *type = 0;
2524         hr = CordbType::TypeDataToType(cdbAppDomain, &data, &type);
2525         
2526         if (SUCCEEDED(hr))
2527         {
2528             *ppType = type;
2529             if (pAppDomain)
2530                 *pAppDomain = cdbAppDomain;
2531         }
2532     }
2533     
2534     return hr;
2535 }
2536
2537
2538 // ******************************************
2539 // CordbRefEnum
2540 // ******************************************
2541 CordbRefEnum::CordbRefEnum(CordbProcess *proc, BOOL walkWeakRefs)
2542     : CordbBase(proc, 0, enumCordbHeap), mRefHandle(0), mEnumStacksFQ(TRUE),
2543       mHandleMask((UINT32)(walkWeakRefs ? CorHandleAll : CorHandleStrongOnly))
2544 {
2545 }
2546
2547 CordbRefEnum::CordbRefEnum(CordbProcess *proc, CorGCReferenceType types)
2548     : CordbBase(proc, 0, enumCordbHeap), mRefHandle(0), mEnumStacksFQ(FALSE),
2549       mHandleMask((UINT32)types)
2550 {
2551 }
2552
2553 void CordbRefEnum::Neuter()
2554 {
2555     EX_TRY
2556     {
2557         if (mRefHandle)
2558         {
2559             GetProcess()->GetDAC()->DeleteRefWalk(mRefHandle);
2560             mRefHandle = 0;
2561         }
2562     }
2563     EX_CATCH
2564     {
2565         _ASSERTE(!"Hit an error freeing a ref walk."); 
2566     }
2567     EX_END_CATCH(SwallowAllExceptions)
2568     
2569     CordbBase::Neuter();
2570 }
2571
2572 HRESULT CordbRefEnum::QueryInterface(REFIID riid, void **ppInterface)
2573 {
2574     if (ppInterface == NULL)
2575         return E_INVALIDARG;
2576         
2577     if (riid == IID_ICorDebugGCReferenceEnum)
2578     {
2579         *ppInterface = static_cast<ICorDebugGCReferenceEnum*>(this);
2580     }
2581     else if (riid == IID_IUnknown)
2582     {
2583         *ppInterface = static_cast<IUnknown*>(static_cast<ICorDebugGCReferenceEnum*>(this));
2584     }
2585     else
2586     {
2587         *ppInterface = NULL;
2588         return E_NOINTERFACE;
2589     }
2590
2591     ExternalAddRef();
2592     return S_OK;
2593 }
2594
2595 HRESULT CordbRefEnum::Skip(ULONG celt)
2596 {
2597     return E_NOTIMPL;
2598 }
2599
2600 HRESULT CordbRefEnum::Reset()
2601 {
2602     PUBLIC_API_ENTRY(this);
2603     HRESULT hr = S_OK;
2604     EX_TRY
2605     {
2606         if (mRefHandle)
2607         {
2608             GetProcess()->GetDAC()->DeleteRefWalk(mRefHandle);
2609             mRefHandle = 0;
2610         }
2611     }
2612     EX_CATCH_HRESULT(hr);
2613     
2614     return hr;
2615 }
2616
2617 HRESULT CordbRefEnum::Clone(ICorDebugEnum **ppEnum)
2618 {
2619     return E_NOTIMPL;
2620 }
2621
2622 HRESULT CordbRefEnum::GetCount(ULONG *pcelt)
2623 {
2624     return E_NOTIMPL;
2625 }
2626
2627
2628 //
2629
2630 HRESULT CordbRefEnum::Next(ULONG celt, COR_GC_REFERENCE refs[], ULONG *pceltFetched)
2631 {
2632     if (refs == NULL || pceltFetched == NULL)
2633         return E_POINTER;
2634     
2635     CordbProcess *process = GetProcess();
2636     HRESULT hr = S_OK;
2637     
2638     PUBLIC_API_ENTRY(this);
2639     FAIL_IF_NEUTERED(this);
2640     ATT_REQUIRE_STOPPED_MAY_FAIL(process);
2641     
2642     RSLockHolder procLockHolder(process->GetProcessLock());
2643     
2644     EX_TRY
2645     {
2646         if (!mRefHandle)
2647             hr = process->GetDAC()->CreateRefWalk(&mRefHandle, mEnumStacksFQ, mEnumStacksFQ, mHandleMask);
2648             
2649         if (SUCCEEDED(hr))
2650         {
2651             DacGcReference dacRefs[32];
2652             ULONG toFetch = _countof(dacRefs);
2653             ULONG total = 0;
2654             
2655             for (ULONG c = 0; SUCCEEDED(hr) && c < (celt/_countof(dacRefs) + 1); ++c)
2656             {
2657                 // Fetch 32 references at a time, the last time, only fetch the remainder (that is, if
2658                 // the user didn't fetch a multiple of 32).
2659                 if (c == celt/_countof(dacRefs))
2660                     toFetch = celt % _countof(dacRefs);
2661                     
2662                 ULONG fetched = 0;
2663                 hr = process->GetDAC()->WalkRefs(mRefHandle, toFetch, dacRefs, &fetched);
2664                 
2665                 if (SUCCEEDED(hr))
2666                 {
2667                     for (ULONG i = 0; i < fetched; ++i)
2668                     {
2669                         CordbAppDomain *pDomain = process->LookupOrCreateAppDomain(dacRefs[i].vmDomain);
2670                         
2671                         ICorDebugAppDomain *pAppDomain;
2672                         ICorDebugValue *pOutObject = NULL;
2673                         if (dacRefs[i].pObject & 1)
2674                         {
2675                             dacRefs[i].pObject &= ~1;
2676                             ICorDebugObjectValue *pObjValue = NULL;
2677                             
2678                             hr = process->GetObject(dacRefs[i].pObject, &pObjValue);
2679                             
2680                             if (SUCCEEDED(hr))
2681                             {
2682                                 hr = pObjValue->QueryInterface(IID_ICorDebugValue, (void**)&pOutObject);
2683                                 pObjValue->Release();
2684                             }
2685                         }
2686                         else
2687                         {
2688                             ICorDebugReferenceValue *tmpValue = NULL;
2689                             IfFailThrow(CordbReferenceValue::BuildFromGCHandle(pDomain,
2690                                                                    dacRefs[i].objHnd,
2691                                                                    &tmpValue));
2692                             
2693                             if (SUCCEEDED(hr))
2694                             {
2695                                 hr = tmpValue->QueryInterface(IID_ICorDebugValue, (void**)&pOutObject);
2696                                 tmpValue->Release();
2697                             }
2698                         }
2699                         
2700                         if (SUCCEEDED(hr) && pDomain)
2701                         {
2702                             hr = pDomain->QueryInterface(IID_ICorDebugAppDomain, (void**)&pAppDomain);
2703                         }
2704                         
2705                         if (FAILED(hr))
2706                             break;
2707                         
2708                         refs[total].Domain = pAppDomain;
2709                         refs[total].Location = pOutObject;
2710                         refs[total].Type = (CorGCReferenceType)dacRefs[i].dwType;
2711                         refs[total].ExtraData = dacRefs[i].i64ExtraData;
2712                         
2713                         total++;
2714                     }
2715                 }
2716             }
2717             
2718             *pceltFetched = total;
2719         }
2720     }
2721     EX_CATCH_HRESULT(hr);
2722
2723     return hr;
2724 }
2725
2726
2727 // ******************************************
2728 // CordbHeapEnum
2729 // ******************************************
2730 CordbHeapEnum::CordbHeapEnum(CordbProcess *proc)
2731     : CordbBase(proc, 0, enumCordbHeap), mHeapHandle(0)
2732 {
2733 }
2734
2735 HRESULT CordbHeapEnum::QueryInterface(REFIID riid, void **ppInterface)
2736 {
2737     if (ppInterface == NULL)
2738         return E_INVALIDARG;
2739         
2740     if (riid == IID_ICorDebugHeapEnum)
2741     {
2742         *ppInterface = static_cast<ICorDebugHeapEnum*>(this);
2743     }
2744     else if (riid == IID_IUnknown)
2745     {
2746         *ppInterface = static_cast<IUnknown*>(static_cast<ICorDebugHeapEnum*>(this));
2747     }
2748     else
2749     {
2750         *ppInterface = NULL;
2751         return E_NOINTERFACE;
2752     }
2753
2754     ExternalAddRef();
2755     return S_OK;
2756 }
2757
2758 HRESULT CordbHeapEnum::Skip(ULONG celt)
2759 {
2760     return E_NOTIMPL;
2761 }
2762
2763 HRESULT CordbHeapEnum::Reset()
2764 {
2765     Clear();
2766     return S_OK;
2767 }
2768
2769 void CordbHeapEnum::Clear()
2770 {
2771     EX_TRY
2772     {
2773         if (mHeapHandle)
2774         {
2775             GetProcess()->GetDAC()->DeleteHeapWalk(mHeapHandle);
2776             mHeapHandle = 0;
2777         }
2778     }
2779     EX_CATCH
2780     {
2781         _ASSERTE(!"Hit an error freeing the heap walk."); 
2782     }
2783     EX_END_CATCH(SwallowAllExceptions)
2784 }
2785
2786 HRESULT CordbHeapEnum::Clone(ICorDebugEnum **ppEnum)
2787 {
2788     return E_NOTIMPL;
2789 }
2790
2791 HRESULT CordbHeapEnum::GetCount(ULONG *pcelt)
2792 {
2793     return E_NOTIMPL;
2794 }
2795
2796 HRESULT CordbHeapEnum::Next(ULONG celt, COR_HEAPOBJECT objects[], ULONG *pceltFetched)
2797 {
2798     HRESULT hr = S_OK;
2799     PUBLIC_API_ENTRY(this);
2800     RSLockHolder stopGoLock(this->GetProcess()->GetStopGoLock());
2801     RSLockHolder procLock(this->GetProcess()->GetProcessLock());
2802     ULONG fetched = 0;
2803
2804     EX_TRY
2805     {
2806         if (mHeapHandle == 0)
2807         {
2808             hr = GetProcess()->GetDAC()->CreateHeapWalk(&mHeapHandle);
2809         }
2810
2811         if (SUCCEEDED(hr))
2812         {
2813             hr = GetProcess()->GetDAC()->WalkHeap(mHeapHandle, celt, objects, &fetched);
2814             _ASSERTE(fetched <= celt);
2815         }
2816         
2817         if (SUCCEEDED(hr))
2818         {
2819             // Return S_FALSE if we've reached the end of the enum.
2820             if (fetched < celt)
2821                 hr = S_FALSE;
2822         }
2823     } 
2824     EX_CATCH_HRESULT(hr);
2825
2826     // Set the fetched parameter to reflect the number of elements (if any) 
2827     // that were successfully saved to "objects"
2828     if (pceltFetched)
2829         *pceltFetched = fetched;
2830
2831     return hr;
2832 }
2833
2834 //---------------------------------------------------------------------------------------
2835 // Flush state for when the process starts running.
2836 // 
2837 // Notes:
2838 //   Helper for code:CordbProcess::ProcessStateChanged.
2839 //   Since ICD Arrowhead does not own the eventing pipeline, it needs the debugger to 
2840 //   notifying it of when the process is running again.  This is like the counterpart
2841 //   to code:CordbProcess::Filter
2842 void CordbProcess::FlushProcessRunning()
2843 {
2844     _ASSERTE(GetProcessLock()->HasLock());
2845     
2846     // Update the continue counter.
2847     m_continueCounter++;
2848
2849     // Safely dispose anything that should be neutered on continue.
2850     MarkAllThreadsDirty();    
2851     ForceDacFlush();
2852 }
2853
2854 //---------------------------------------------------------------------------------------
2855 // Flush all cached state and bring us back to "cold startup"
2856 // 
2857 // Notes:
2858 //   Helper for code:CordbProcess::ProcessStateChanged.
2859 //   This is used if the data-target changes underneath us in a way that is
2860 //   not consistent with the process running forward. For example, if for
2861 //   a time-travel debugger, the data-target may flow "backwards" in time.
2862 //   
2863 void CordbProcess::FlushAll()
2864 {
2865     CONTRACTL
2866     {
2867         THROWS;
2868     }
2869     CONTRACTL_END;
2870
2871     HRESULT hr;
2872     _ASSERTE(GetProcessLock()->HasLock());
2873
2874     //
2875     // First, determine if it's safe to Flush
2876     //
2877
2878     hr = IsReadyForDetach();
2879     IfFailThrow(hr);
2880
2881     // Check for outstanding CordbHandle values. 
2882     if (OutstandingHandles())
2883     {
2884         ThrowHR(CORDBG_E_DETACH_FAILED_OUTSTANDING_TARGET_RESOURCES);
2885     }
2886
2887     // FlushAll is a superset of FlushProcessRunning.
2888     // This will also ensure we clear the DAC cache.
2889     FlushProcessRunning();
2890
2891     // If we detach before the CLR is loaded into the debuggee, then we can no-op a lot of work.
2892     // We sure can't be sending IPC events to the LS before it exists.
2893     NeuterChildren();    
2894 }
2895
2896 //---------------------------------------------------------------------------------------
2897 //
2898 // Detach the Debugger from the LS process.
2899 //
2900 //
2901 // Return Value:
2902 //    S_OK on successful detach. Else errror.
2903 //
2904 // Assumptions:
2905 //    Target is stopped.
2906 //
2907 // Notes:
2908 //    Once we're detached, the LS can resume running and exit.
2909 //    So it's possible to get an ExitProcess callback in the middle of the Detach phase. If that happens,
2910 //    we must return CORDBG_E_PROCESS_TERMINATED and pretend that the exit happened before we tried to detach.
2911 //    Else if we detach successfully, return S_OK.
2912 //
2913 //    @dbgtodo attach-bit: need to figure out semantics of Detach
2914 //    in V3, especially w.r.t to an attach bit.
2915 //---------------------------------------------------------------------------------------
2916 HRESULT CordbProcess::Detach()
2917 {   
2918     PUBLIC_API_ENTRY(this);
2919
2920     FAIL_IF_NEUTERED(this);
2921
2922     if (IsInteropDebugging())
2923     {
2924         return CORDBG_E_INTEROP_NOT_SUPPORTED; 
2925     }
2926
2927
2928     HRESULT hr = S_OK;
2929     // A very important note: we require that the process is synchronized before doing a detach. This ensures
2930     // that no events are on their way from the Left Side. We also require that the user has drained the
2931     // managed event queue, but there is currently no way to really enforce that here.
2932     // @todo-  why can't we enforce that the managed event Q is drained?
2933     ATT_REQUIRE_SYNCED_OR_NONINIT_MAY_FAIL(this);
2934
2935     
2936     hr = IsReadyForDetach();
2937     if (FAILED(hr))
2938     {
2939         // Avoid neutering. Gives client a chance to fix detach issue and retry.
2940         return hr;
2941     }
2942
2943     // Since the detach may resume the LS and allow it to exit, which may invoke the EP callback
2944     // which may destroy this process object, be sure to protect us w/ an extra AddRef/Release
2945     RSSmartPtr<CordbProcess> pRef(this);
2946
2947
2948     
2949     LOG((LF_CORDB, LL_INFO1000, "CP::Detach - beginning\n"));
2950     if (m_pShim == NULL) // This API is moved off to the shim
2951     {
2952         
2953         // This is still invasive. 
2954         // Ignore failures. This will fail for a non-invasive target. 
2955         if (IsDacInitialized())
2956         {
2957             HRESULT hrIgnore = S_OK;
2958             EX_TRY
2959             {
2960                 GetDAC()->MarkDebuggerAttached(FALSE);
2961             }
2962             EX_CATCH_HRESULT(hrIgnore);
2963         }
2964     }
2965     else
2966     {         
2967         EX_TRY
2968         {
2969             DetachShim();       
2970         }
2971         EX_CATCH_HRESULT(hr);
2972     }
2973
2974     // Either way, neuter everything.
2975     this->Neuter();
2976
2977     // Implicit release on pRef
2978     LOG((LF_CORDB, LL_INFO1000, "CP::Detach - returning w/ hr=0x%x\n", hr));
2979     return hr;
2980 }
2981
2982 // Free up key left-side resources
2983 // 
2984 // Called on detach
2985 // This does key neutering of objects that hold left-side resources and require
2986 // preemptively freeing the resources.
2987 // After this, code:CordbProcess::Neuter should only affect right-side state.
2988 void CordbProcess::NeuterChildrenLeftSideResources()
2989 {
2990     _ASSERTE(GetStopGoLock()->HasLock());
2991     
2992     _ASSERTE(!GetProcessLock()->HasLock());
2993     RSLockHolder lockHolder(GetProcessLock());
2994
2995     
2996     // Need process-lock to operate on hashtable, but can't yet Neuter under process-lock,
2997     // so we have to copy the contents to an auxilary list which we can then traverse outside the lock.
2998     RSPtrArray<CordbAppDomain> listAppDomains;
2999     m_appDomains.CopyToArray(&listAppDomains);
3000     
3001     
3002
3003     // Must not hold process lock so that we can be safe to send IPC events
3004     // to cleanup left-side resources.
3005     lockHolder.Release();
3006     _ASSERTE(!GetProcessLock()->HasLock());
3007
3008     // Frees left-side resources. This may send IPC events. 
3009     // This will make normal neutering a nop.
3010     m_LeftSideResourceCleanupList.NeuterLeftSideResourcesAndClear(this);
3011
3012     for(unsigned int idx = 0; idx < listAppDomains.Length(); idx++)
3013     {
3014         CordbAppDomain * pAppDomain = listAppDomains[idx];
3015
3016         // CordbHandleValue is in the appdomain exit list, and that needs
3017         // to send an IPC event to cleanup and release the handle from
3018         // the GCs handle table. 
3019         pAppDomain->GetSweepableExitNeuterList()->NeuterLeftSideResourcesAndClear(this);
3020     }
3021     listAppDomains.Clear();
3022     
3023 }
3024
3025 //---------------------------------------------------------------------------------------
3026 // Detach the Debugger from the LS process for the V2 case
3027 // 
3028 // Assumptions:
3029 //      This will NeuterChildren(), caller will do the real Neuter()
3030 //      Caller has already ensured that detach is safe.
3031 // 
3032 //   @dbgtodo attach-bit: this should be moved into the shim; need
3033 //   to figure out semantics for freeing left-side resources (especially GC
3034 //   handles) on detach.
3035 void CordbProcess::DetachShim()
3036 {
3037
3038     HASHFIND hashFind;
3039     HRESULT hr = S_OK;
3040
3041     // If we detach before the CLR is loaded into the debuggee, then we can no-op a lot of work.
3042     // We sure can't be sending IPC events to the LS before it exists.
3043     if (m_initialized)
3044     {   
3045         // The managed event queue is not necessarily drained. Cordbg could call detach between any callback.
3046         // While the process is still stopped, neuter all of our children.
3047         // This will make our Neuter() a nop and saves the W32ET from having to do dangerous work.
3048         this->NeuterChildrenLeftSideResources();
3049         {
3050             RSLockHolder lockHolder(GetProcessLock());
3051             this->NeuterChildren();
3052         }
3053
3054         // Go ahead and detach from the entire process now. This is like sending a "Continue".
3055         DebuggerIPCEvent * pIPCEvent = (DebuggerIPCEvent *) _alloca(CorDBIPC_BUFFER_SIZE);
3056         InitIPCEvent(pIPCEvent, DB_IPCE_DETACH_FROM_PROCESS, true, VMPTR_AppDomain::NullPtr());
3057
3058         hr = m_cordb->SendIPCEvent(this, pIPCEvent, CorDBIPC_BUFFER_SIZE);
3059         hr = WORST_HR(hr, pIPCEvent->hr);
3060         IfFailThrow(hr);
3061     }
3062     else
3063     {
3064         // @dbgtodo attach-bit: push this up, once detach IPC event is hoisted.
3065         RSLockHolder lockHolder(GetProcessLock()); 
3066
3067         // Shouldn't have any appdomains.
3068         (void)hashFind; //prevent "unused variable" error from GCC
3069         _ASSERTE(m_appDomains.FindFirst(&hashFind) == NULL);
3070     }
3071
3072     LOG((LF_CORDB, LL_INFO10000, "CP::Detach - got reply from LS\n"));
3073
3074     // It's possible that the LS may exit after they reply to our detach_from_process, but
3075     // before we update our internal state that they're detached. So still have to check
3076     // failure codes here.
3077     hr = this->m_pShim->GetWin32EventThread()->SendDetachProcessEvent(this);
3078
3079
3080     // Since we're auto-continuing when we detach, we should set the stop count back to zero.
3081     // This (along w/ m_detached) prevents anyone from calling Continue on this process
3082     // after this call returns.
3083     m_stopCount = 0;
3084
3085     if (hr != CORDBG_E_PROCESS_TERMINATED)
3086     {
3087         // Remember that we've detached from this process object. This will prevent any further operations on
3088         // this process, just in case... :)
3089         // If LS exited, then don't set this flag because it overrides m_terminated when reporting errors;
3090         // and we want to provide a consistent story about whether we detached or whether the LS exited.
3091         m_detached = true;
3092     }
3093     IfFailThrow(hr);
3094     
3095
3096     // Now that all complicated cleanup is done, caller can do a final neuter.
3097     // This will implicitly stop our Win32 event thread as well.
3098 }
3099
3100 // Delete all events from the queue without dispatching. This is useful in shutdown.
3101 // An event that is currently dispatching is not on the queue.
3102 void CordbProcess::DeleteQueuedEvents()
3103 {
3104     INTERNAL_API_ENTRY(this);
3105     // We must have the process lock to ensure that no one is trying to add an event
3106     _ASSERTE(!ThreadHoldsProcessLock());
3107
3108     if (m_pShim != NULL)
3109     {
3110         PUBLIC_CALLBACK_IN_THIS_SCOPE0_NO_LOCK(this);
3111
3112         // DeleteAll() is part of the shim, and it will change external ref counts, so must really
3113         // be marked as outside the RS.
3114         m_pShim->GetManagedEventQueue()->DeleteAll();
3115     }
3116 }
3117
3118 //---------------------------------------------------------------------------------------
3119 //
3120 // Track that we're about to dispatch a managed event.
3121 //
3122 // Arguments:
3123 //      event - event being dispatched
3124 //
3125 // Assumptions:
3126 //    This is used to support code:CordbProcess::AreDispatchingEvent
3127 //    This is always called on the same thread as code:CordbProcess::FinishEventDispatch
3128 void CordbProcess::StartEventDispatch(DebuggerIPCEventType event)
3129 {
3130     LIMITED_METHOD_CONTRACT;
3131
3132     _ASSERTE(m_dispatchedEvent == DB_IPCE_DEBUGGER_INVALID);
3133     _ASSERTE(event != DB_IPCE_DEBUGGER_INVALID);
3134     m_dispatchedEvent = event;
3135 }
3136
3137 //---------------------------------------------------------------------------------------
3138 //
3139 // Track that we're done dispatching a managed event.
3140 //
3141 //
3142 // Assumptions:
3143 //    This is always called on the same thread as code:CordbProcess::StartEventDispatch
3144 //
3145 // Notes:
3146 //   @dbgtodo shim: eventually this goes into the shim when we hoist Continue
3147 void CordbProcess::FinishEventDispatch()
3148 {
3149     LIMITED_METHOD_CONTRACT;
3150
3151     _ASSERTE(m_dispatchedEvent != DB_IPCE_DEBUGGER_INVALID);
3152     m_dispatchedEvent = DB_IPCE_DEBUGGER_INVALID;
3153 }
3154
3155 //---------------------------------------------------------------------------------------
3156 //
3157 // Are we in the middle of dispatching an event?
3158 //
3159 // Notes:
3160 //   This is used by code::CordbProcess::ContinueInternal. Continue logic takes
3161 //   a shortcut if the continue is called on the dispatch thread.
3162 //   It doesn't matter which event is being dispatch; only that we're on the dispatch thread.
3163 //   @dbgtodo shim: eventually this goes into the shim when we hoist Continue
3164 bool CordbProcess::AreDispatchingEvent()
3165 {
3166     LIMITED_METHOD_CONTRACT;
3167
3168     return m_dispatchedEvent != DB_IPCE_DEBUGGER_INVALID;
3169 }
3170
3171
3172
3173
3174
3175 // Terminate the app. We'll still dispatch an ExitProcess callback, so the app
3176 // must wait for that before calling Cordb::Terminate.
3177 // If this fails, the client can always call the OS's TerminateProcess command
3178 // to rudely kill the debuggee.
3179 HRESULT CordbProcess::Terminate(unsigned int exitCode)
3180 {
3181     PUBLIC_API_ENTRY(this);
3182
3183     LOG((LF_CORDB, LL_INFO1000, "CP::Terminate: with exitcode %u\n", exitCode));
3184     FAIL_IF_NEUTERED(this);
3185
3186
3187     // @dbgtodo shutdown: eventually, all of Terminate() will be in the Shim.
3188     // Free all the remaining events. Since this will call into the shim, do this outside of any locks. 
3189     // (ATT_ takes locks).
3190     DeleteQueuedEvents();
3191
3192     ATT_REQUIRE_SYNCED_OR_NONINIT_MAY_FAIL(this);
3193
3194     // When we terminate the process, it's handle will become signaled and
3195     // Win32 Event Thread will leap into action and call CordbWin32EventThread::ExitProcess
3196     // Unfortunately, that may destroy this object if the ExitProcess callback
3197     // decides to call Release() on the process.
3198
3199
3200     // Indicate that the process is exiting so that (among other things) we don't try and
3201     // send messages to the left side while it's being deleted.
3202     Lock();
3203
3204     // In case we're continuing from the loader bp, we don't want to try and kick off an attach. :)
3205     m_fDoDelayedManagedAttached = false;
3206     m_exiting = true;
3207
3208
3209
3210     // We'd like to just take a lock around everything here, but that may deadlock us
3211     // since W32ET will wait on the lock, and Continue may wait on W32ET.
3212     // So we just do an extra AddRef/Release to make sure we're still around.
3213     // @todo - could we move this smartptr up so that it's well-nested w/ the lock?
3214     RSSmartPtr<CordbProcess> pRef(this);
3215
3216     Unlock();
3217
3218
3219     // At any point after this call, the w32 ET may run the ExitProcess code which will race w/ the continue call.
3220     // This call only posts a request that the process terminate and does not guarantee the process actually
3221     // terminates. In particular, the process can not exit until any outstanding IO requests are done (on cancelled).
3222     // It also can not exit if we have an outstanding not-continued native-debug event.
3223     // Fortunately, the interesting work in terminate is done in ExitProcessWorkItem::Do, which can take the Stop-Go lock.
3224     // Since we're currently holding the stop-go lock, that means we at least get some serialization.
3225     //
3226     // Note that on Windows, the process isn't really terminated until we receive the EXIT_PROCESS_DEBUG_EVENT.
3227     // Before then, we can still still access the debuggee's address space.  On the other, for Mac debugging,
3228     // the process can die any time after this call, and so we can no longer call into the DAC.  
3229     GetShim()->GetNativePipeline()->TerminateProcess(exitCode);
3230
3231     // We just call Continue() so that the debugger doesn't have to. (It's arguably odd
3232     // to call Continue() after Terminate).
3233     // We're stopped & Synced.
3234     // For interop-debugging this is very important because the Terminate may not really kill the process
3235     // until after we continue from the current native debug event.
3236     ContinueInternal(FALSE);
3237
3238     // Implicit release on pRef here (since it's going out of scope)...
3239     // After this release, this object may be destroyed. So don't use any member functions
3240     // (including Locks) after here.
3241
3242
3243     return S_OK;
3244 }
3245
3246 // This can be called at any time, even if we're in an unrecoverable error state.
3247 HRESULT CordbProcess::GetID(DWORD *pdwProcessId)
3248 {
3249     PUBLIC_REENTRANT_API_ENTRY(this);
3250     OK_IF_NEUTERED(this);
3251     VALIDATE_POINTER_TO_OBJECT(pdwProcessId, DWORD *);
3252
3253     HRESULT hr = S_OK;
3254     EX_TRY
3255     {
3256         // This shouldn't be used in V3 paths. Normally, we can enforce that by checking against
3257         // m_pShim. However, this API can be called after being neutered, in which case m_pShim is cleared.
3258         // So check against 0 instead.    
3259         if (m_id == 0) 
3260         {
3261             *pdwProcessId = 0;
3262             ThrowHR(E_NOTIMPL);
3263         }
3264         *pdwProcessId = GetPid();
3265     }
3266     EX_CATCH_HRESULT(hr);
3267     return hr;
3268 }
3269
3270 // Helper to get PID internally. We know we'll always succeed.
3271 // This is more convient for internal callers since they can just use it as an expression
3272 // without having to check HRESULTS.
3273 DWORD CordbProcess::GetPid()
3274 {
3275     // This shouldn't be used in V3 paths, in which case it's set to 0. Only the shim should be
3276     // calling this. Assert to catch anybody else.
3277     _ASSERTE(m_id != 0);
3278
3279     return (DWORD) m_id;
3280 }
3281
3282
3283 HRESULT CordbProcess::GetHandle(HANDLE *phProcessHandle)
3284 {
3285     PUBLIC_REENTRANT_API_ENTRY(this);
3286     FAIL_IF_NEUTERED(this); // Once we neuter the process, we close our OS handle to it.
3287     VALIDATE_POINTER_TO_OBJECT(phProcessHandle, HANDLE *);
3288
3289     if (m_pShim == NULL)
3290     {
3291         _ASSERTE(!"CordbProcess::GetHandle() should be not be called on the new architecture");
3292         *phProcessHandle = NULL;
3293         return E_NOTIMPL;
3294     }
3295     else
3296     {
3297         *phProcessHandle = m_handle;
3298         return S_OK;
3299     }
3300 }
3301
3302 HRESULT CordbProcess::IsRunning(BOOL *pbRunning)
3303 {
3304     PUBLIC_API_ENTRY(this);
3305     FAIL_IF_NEUTERED(this);
3306     VALIDATE_POINTER_TO_OBJECT(pbRunning, BOOL*);
3307
3308     *pbRunning = !GetSynchronized();
3309
3310     return S_OK;
3311 }
3312
3313 HRESULT CordbProcess::EnableSynchronization(BOOL bEnableSynchronization)
3314 {
3315     /* !!! */
3316     PUBLIC_API_ENTRY(this);
3317     return E_NOTIMPL;
3318 }
3319
3320 HRESULT CordbProcess::Stop(DWORD dwTimeout)
3321 {
3322     PUBLIC_API_ENTRY(this);
3323     CORDBRequireProcessStateOK(this);
3324
3325     HRESULT hr = StopInternal(dwTimeout, VMPTR_AppDomain::NullPtr());
3326
3327     return ErrWrapper(hr);
3328 }
3329
3330 HRESULT CordbProcess::StopInternal(DWORD dwTimeout, VMPTR_AppDomain pAppDomainToken)
3331 {
3332     LOG((LF_CORDB, LL_INFO1000, "CP::S: stopping process 0x%x(%d) with timeout %d\n", m_id, m_id,  dwTimeout));
3333
3334     INTERNAL_API_ENTRY(this);
3335
3336     // Stop + Continue are executed under the Stop-Go lock. This makes them atomic.
3337     // We'll toggle the process-lock (b/c we communicate w/ the W32et, so just the process-lock is
3338     // not sufficient to make this atomic).
3339     // It's ok to take this lock before checking if the CordbProcess has been neutered because 
3340     // the lock is destroyed in the dtor after neutering.
3341     RSLockHolder ch(&m_StopGoLock);
3342
3343     // Check if this CordbProcess has been neutered under the SG lock.  
3344     // Otherwise it's possible to race with Detach() and Terminate().
3345     FAIL_IF_NEUTERED(this);
3346     CORDBFailIfOnWin32EventThread(this);
3347
3348     if (m_pShim == NULL) // Stop/Go is moved off to the shim
3349     {
3350         return E_NOTIMPL;
3351     }
3352
3353
3354     DebuggerIPCEvent* event;
3355     HRESULT hr = S_OK;
3356
3357     STRESS_LOG2(LF_CORDB, LL_INFO1000, "CP::SI, timeout=%d, this=%p\n", dwTimeout, this);
3358
3359     // Stop() is a syncronous (blocking) operation. Furthermore, we have no way to cancel the async-break request.
3360     // Thus if we returned early on a timeout, then we'll be in a random state b/c the LS may get stopped at any
3361     // later spot.
3362     // One solution just require the param is INFINITE until we fix this and E_INVALIDARG if it's not.
3363     // But that could be a breaking change (what if a debugger passes in a really large value that's effectively
3364     // INFINITE).
3365     // So we'll just ignore it and always treat it as infinite.
3366     dwTimeout = INFINITE;
3367
3368     // Do the checks on the process state under the SG lock.  This ensures that another thread cannot come in
3369     // after we do the checks and take the lock before we do.  For example, Detach() can race with Stop() such
3370     // that:
3371     //      1. Thread A calls CordbProcess::Detach() and takes the stop-go lock
3372     //      2. Thread B calls CordbProcess::Stop(), passes all the checks, and then blocks on the stop-go lock
3373     //      3. Thread A finishes the detach, invalides the process state, cleans all the resources, and then
3374     //         releases the stop-go lock
3375     //      4. Thread B gets the lock, but everything has changed
3376     CORDBRequireProcessStateOK(this);
3377
3378     Lock();
3379
3380     ASSERT_SINGLE_THREAD_ONLY(HoldsLock(&m_StopGoLock));
3381
3382     // Don't need to stop if the process hasn't even executed any managed code yet.
3383     if (!m_initialized)
3384     {
3385         LOG((LF_CORDB, LL_INFO1000, "CP::S: process isn't initialized yet.\n"));
3386
3387         // Mark the process as synchronized so no events will be dispatched until the thing is continued.
3388         SetSynchronized(true);
3389
3390         // Remember uninitialized stop...
3391         m_uninitializedStop = true;
3392
3393 #ifdef FEATURE_INTEROP_DEBUGGING
3394         // If we're Win32 attached, then suspend all the unmanaged threads in the process.
3395         // We may or may not be stopped at a native debug event.
3396         if (IsInteropDebugging())
3397         {
3398             SuspendUnmanagedThreads();
3399         }
3400 #endif // FEATURE_INTEROP_DEBUGGING
3401
3402         // Get the RC Event Thread to stop listening to the process.
3403         m_cordb->ProcessStateChanged();
3404
3405         hr = S_OK;
3406         goto Exit;
3407     }
3408
3409     // Don't need to stop if the process is already synchronized.
3410     // @todo - Issue 129917. It's possible that we'll get a call to Stop when the LS is already stopped.
3411     // Sending an AsyncBreak would deadlock here (b/c the LS will ignore the frivilous request,
3412     // and thus never send a SyncComplete, and thus our Waiting on the SyncComplete will deadlock).
3413     // We avoid this case by checking m_syncCompleteReceived (which should roughly correspond to
3414     // the LS's m_stopped variable).
3415     // One window this can happen is after a Continue() pings the RCET but before the RCET actually sweeps + flushes.
3416
3417     if (GetSynchronized() || GetSyncCompleteRecv())
3418     {
3419         LOG((LF_CORDB, LL_INFO1000, "CP::S: process was already synchronized. m_syncCompleteReceived=%d\n", GetSyncCompleteRecv()));
3420
3421         if (GetSyncCompleteRecv())
3422         {
3423             // We must be in that window alluded to above (while the RCET is sweeping). Re-ping the RCET.
3424             SetSynchronized(true);
3425             m_cordb->ProcessStateChanged();
3426         }
3427         hr = S_OK;
3428         goto Exit;
3429     }
3430
3431     STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::S: process not sync'd, requesting stop.\n");
3432
3433     m_stopRequested = true;
3434
3435     // We don't want to dispatch any Win32 debug events while we're trying to stop.
3436     // Setting m_specialDeferment=true means that any debug event we get will be queued and not dispatched.
3437     // We do this to avoid a nested call to Continue.
3438     // These defered events will get dispatched when somebody calls continue (and since they're calling
3439     // stop now, they must call continue eventually).
3440     // Note that if we got a Win32 debug event between when we took the Stop-Go lock above and now,
3441     // that even may have been dispatched. We're ok because SSFW32Stop will hijack that event and continue it,
3442     // and then all future events will be queued.
3443     m_specialDeferment = true;
3444     Unlock();
3445
3446     BOOL asyncBreakSent;
3447
3448     // We need to ensure that the helper thread is alive.
3449     hr = this->StartSyncFromWin32Stop(&asyncBreakSent);
3450     if (FAILED(hr))
3451     {
3452         return hr;
3453     }
3454
3455
3456     if (asyncBreakSent)
3457     {
3458         hr = S_OK;
3459         Lock();
3460
3461         m_stopRequested = false;
3462
3463         goto Exit;
3464     }
3465
3466     // Send the async break event to the RC.
3467     event = (DebuggerIPCEvent*) _alloca(CorDBIPC_BUFFER_SIZE);
3468     InitIPCEvent(event, DB_IPCE_ASYNC_BREAK, false, pAppDomainToken);
3469
3470     STRESS_LOG1(LF_CORDB, LL_INFO1000, "CP::S: sending async stop to appd 0x%x.\n", VmPtrToCookie(pAppDomainToken));
3471
3472     hr = m_cordb->SendIPCEvent(this, event, CorDBIPC_BUFFER_SIZE);
3473     hr = WORST_HR(hr, event->hr);
3474     if (FAILED(hr))
3475     {
3476         // We don't hold the lock so just return immediately. Don't adjust stop-count.
3477         _ASSERTE(!ThreadHoldsProcessLock());
3478         return hr;
3479     }
3480
3481     LOG((LF_CORDB, LL_INFO1000, "CP::S: sent async stop to appd 0x%x.\n", VmPtrToCookie(pAppDomainToken)));
3482
3483     // Wait for the sync complete message to come in. Note: when the sync complete message arrives to the RCEventThread,
3484     // it will mark the process as synchronized and _not_ dispatch any events. Instead, it will set m_stopWaitEvent
3485     // which will let this function return. If the user wants to process any queued events, they will need to call
3486     // Continue.
3487     STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::S: waiting for event.\n");
3488
3489     DWORD ret;
3490     ret = SafeWaitForSingleObject(this, m_stopWaitEvent, dwTimeout);
3491
3492     STRESS_LOG1(LF_CORDB, LL_INFO1000, "CP::S: got event, %d.\n", ret);
3493
3494     if (m_terminated)
3495     {
3496         return CORDBG_E_PROCESS_TERMINATED;
3497     }
3498
3499     if (ret == WAIT_OBJECT_0)
3500     {
3501         LOG((LF_CORDB, LL_INFO1000, "CP::S: process stopped.\n"));
3502
3503         m_stopRequested = false;
3504         m_cordb->ProcessStateChanged();
3505
3506         hr = S_OK;
3507         Lock();
3508         goto Exit;
3509     }
3510     else if (ret == WAIT_TIMEOUT)
3511     {
3512         hr = ErrWrapper(CORDBG_E_TIMEOUT);
3513     }
3514     else
3515         hr = HRESULT_FROM_GetLastError();
3516
3517     // We came out of the wait, but we weren't signaled because a sync complete event came in. Re-check the process and
3518     // remove the stop requested flag.
3519     Lock();
3520     m_stopRequested = false;
3521
3522     if (GetSynchronized())
3523     {
3524         LOG((LF_CORDB, LL_INFO1000, "CP::S: process stopped.\n"));
3525
3526         m_cordb->ProcessStateChanged();
3527
3528         hr = S_OK;
3529     }
3530
3531 Exit:
3532     _ASSERTE(ThreadHoldsProcessLock());
3533
3534     // Stop queuing any Win32 Debug events. We should be synchronized now.
3535     m_specialDeferment = false;
3536
3537     if (SUCCEEDED(hr))
3538     {
3539         IncStopCount();
3540     }
3541
3542     STRESS_LOG2(LF_CORDB, LL_INFO1000, "CP::S: returning from Stop, hr=0x%08x, m_stopCount=%d.\n", hr, GetStopCount());
3543
3544     Unlock();
3545
3546     return hr;
3547 }
3548
3549 //---------------------------------------------------------------------------------------
3550 // Clear all RS state on all CordbThread objects.
3551 //
3552 // Notes:
3553 //   This clears all the thread-related state that the RS may have cached,
3554 //   such as locals, frames, etc.
3555 //   This would be called if the debugger is resuming execution.
3556 void CordbProcess::MarkAllThreadsDirty()
3557 {
3558     INTERNAL_API_ENTRY(this);
3559     _ASSERTE(ThreadHoldsProcessLock());
3560
3561     CordbThread * pThread;
3562     HASHFIND find;
3563
3564     // We don't need to prepopulate here (to collect LS state) because we're just updating RS state.
3565     for (pThread =  m_userThreads.FindFirst(&find);
3566          pThread != NULL;
3567          pThread =  m_userThreads.FindNext(&find))
3568     {
3569         _ASSERTE(pThread != NULL);
3570         pThread->MarkStackFramesDirty();
3571     }
3572
3573     ClearPatchTable();
3574 }
3575
3576 HRESULT CordbProcess::Continue(BOOL fIsOutOfBand)
3577 {
3578     PUBLIC_API_ENTRY(this);
3579
3580     if (m_pShim == NULL) // This API is moved off to the shim
3581     {
3582         // bias towards failing with CORDBG_E_NUETERED.
3583         FAIL_IF_NEUTERED(this); 
3584         return E_NOTIMPL;
3585     }
3586
3587     HRESULT hr;
3588
3589     if (fIsOutOfBand)
3590     {
3591 #ifdef FEATURE_INTEROP_DEBUGGING
3592         hr = ContinueOOB();
3593 #else
3594         hr = E_INVALIDARG;
3595 #endif // FEATURE_INTEROP_DEBUGGING
3596     }
3597     else
3598     {
3599         hr = ContinueInternal(fIsOutOfBand);
3600     }
3601
3602     return hr;
3603 }
3604
3605 #ifdef FEATURE_INTEROP_DEBUGGING
3606 //---------------------------------------------------------------------------------------
3607 //
3608 // ContinueOOB
3609 //
3610 // Continue the Win32 event as an out-of-band event.
3611 //
3612 // Return Value:
3613 //    S_OK on successful continue. Else error.
3614 //
3615 //---------------------------------------------------------------------------------------
3616 HRESULT CordbProcess::ContinueOOB()
3617 {
3618     INTERNAL_API_ENTRY(this);
3619     FAIL_IF_NEUTERED(this);
3620
3621     HRESULT hr = S_OK;
3622
3623     // If we're continuing from an out-of-band unmanaged event, then just go
3624     // ahead and get the Win32 event thread to continue the process. No other
3625     // work needs to be done (i.e., don't need to send a managed continue message
3626     // or dispatch any events) because any processing done due to the out-of-band
3627     // message can't alter the synchronized state of the process.
3628
3629     Lock();
3630     _ASSERTE(m_outOfBandEventQueue != NULL);
3631
3632     // Are we calling this from the unmanaged callback?
3633     if (m_dispatchingOOBEvent)
3634     {
3635         STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::CI: continue while dispatching unmanaged out-of-band event.\n");
3636         // We don't know what thread we're on here.
3637
3638         // Tell the Win32 event thread to continue when it returns from handling its unmanaged callback.
3639         m_dispatchingOOBEvent = false;
3640
3641         Unlock();
3642     }
3643     else
3644     {
3645         STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::CI: continue outside of dispatching.\n");
3646
3647         // If we're not dispatching this, then they shouldn't be on the win32 event thread.
3648         _ASSERTE(!this->IsWin32EventThread());
3649
3650         Unlock();
3651
3652         // Send an event to the Win32 event thread to do the continue. This is an out-of-band continue.
3653         hr = this->m_pShim->GetWin32EventThread()->SendUnmanagedContinue(this, cOobUMContinue);
3654     }
3655
3656     return hr;
3657
3658
3659 }
3660 #endif // FEATURE_INTEROP_DEBUGGING
3661
3662 //---------------------------------------------------------------------------------------
3663 //
3664 // ContinueInternal
3665 //
3666 // Continue the Win32 event.
3667 //
3668 // Return Value:
3669 //    S_OK on success. Else error.
3670 //
3671 //---------------------------------------------------------------------------------------
3672 HRESULT CordbProcess::ContinueInternal(BOOL fIsOutOfBand)
3673 {
3674     INTERNAL_API_ENTRY(this);
3675     FAIL_IF_NEUTERED(this);
3676
3677     // Continue has an ATT similar to ATT_REQUIRE_STOPPED_MAY_FAIL, but w/ some subtle differences.
3678     // - if we're stopped at a native DE, but not synchronized, we don't want to sync.
3679     // - We may get Debug events (especially native ones) at weird times, and thus we have to continue
3680     // at weird times.
3681
3682     // External APIs should not have the process lock.
3683     _ASSERTE(!ThreadHoldsProcessLock());
3684     _ASSERTE(m_pShim != NULL);
3685
3686     // OutOfBand should use ContinueOOB
3687     _ASSERTE(!fIsOutOfBand);
3688
3689     // Since Continue is process-wide, just use a null appdomain pointer.
3690     VMPTR_AppDomain pAppDomainToken = VMPTR_AppDomain::NullPtr();
3691
3692     HRESULT hr = S_OK;
3693
3694     if (m_unrecoverableError)
3695     {
3696         return CORDBHRFromProcessState(this, NULL);
3697     }
3698
3699
3700     // We can't call ContinueInternal for an inband event on the win32 event thread.
3701     // This is an issue in the CLR (or an API design decision, depending on your perspective).
3702     // Continue() may send an IPC event and we can't do that on the win32 event thread.
3703
3704     CORDBFailIfOnWin32EventThread(this);
3705
3706     STRESS_LOG1(LF_CORDB, LL_INFO1000, "CP::CI: continuing IB,  this=0x%X\n", this);
3707
3708     // Stop + Continue are executed under the Stop-Go lock. This makes them atomic.
3709     // We'll toggle the process-lock (b/c we communicate w/ the W32et, so that's not sufficient).
3710     RSLockHolder rsLockHolder(&m_StopGoLock);
3711
3712     // Check for other failures (do these after we have the SG lock).
3713     if (m_terminated)
3714     {
3715         return CORDBG_E_PROCESS_TERMINATED;
3716     }
3717     if (m_detached)
3718     {
3719         return CORDBG_E_PROCESS_DETACHED;
3720     }
3721
3722     Lock();
3723
3724     ASSERT_SINGLE_THREAD_ONLY(HoldsLock(&m_StopGoLock));
3725     _ASSERTE(fIsOutOfBand == FALSE);
3726
3727     // If we've got multiple Stop calls, we need a Continue for each one. So, if the stop count > 1, just go ahead and
3728     // return without doing anything. Note: this is only for in-band or managed events. OOB events are still handled as
3729     // normal above.
3730     _ASSERTE(GetStopCount() > 0);
3731
3732     if (GetStopCount() == 0)
3733     {
3734         Unlock();
3735         _ASSERTE(!"Superflous Continue. ICorDebugProcess.Continue() called too many times");
3736         return CORDBG_E_SUPERFLOUS_CONTINUE;
3737     }
3738
3739     DecStopCount();
3740
3741     // We give managed events priority over unmanaged events. That way, the entire queued managed state can drain before
3742     // we let any other unmanaged events through.
3743
3744     // Every stop or event must be matched by a corresponding Continue. m_stopCount counts outstanding stopping events
3745     // along with calls to Stop. If the count is high at this point, we simply return. This ensures that even if someone
3746     // calls Stop just as they're receiving an event that they can call Continue for that Stop and for that event
3747     // without problems.
3748     if (GetStopCount() > 0)
3749     {
3750         STRESS_LOG1(LF_CORDB, LL_INFO1000, "CP::CI: m_stopCount=%d, Continue just returning S_OK...\n", GetStopCount());
3751
3752         Unlock();
3753         return S_OK;
3754     }
3755
3756     // We're no longer stopped, so reset the m_stopWaitEvent.
3757     ResetEvent(m_stopWaitEvent);
3758
3759     // If we're continuing from an uninitialized stop, then we don't need to do much at all. No event need be sent to
3760     // the Left Side (duh, it isn't even there yet.) We just need to get the RC Event Thread to start listening to the
3761     // process again, and resume any unmanaged threads if necessary.
3762     if (m_uninitializedStop)
3763     {
3764         STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::CI: continuing from uninitialized stop.\n");
3765
3766         // No longer synchronized (it was a partial sync in the first place.)
3767         SetSynchronized(false);
3768         MarkAllThreadsDirty();
3769
3770         // No longer in an uninitialized stop.
3771         m_uninitializedStop = false;
3772
3773         // Notify the RC Event Thread.
3774         m_cordb->ProcessStateChanged();
3775
3776         Unlock();
3777
3778 #ifdef FEATURE_INTEROP_DEBUGGING
3779         // We may or may not have a native debug event queued here.
3780         // If Cordbg called Stop() from a native debug event (to get the process Synchronized), then
3781         // we'll have a native debug event, and we need to continue it.
3782         // If Cordbg called Stop() to do an AsyncBreak, then there's no native-debug event.
3783
3784         // If we're Win32 attached, resume all the unmanaged threads.
3785         if (IsInteropDebugging())
3786         {
3787             if(m_lastDispatchedIBEvent != NULL)
3788             {
3789                 m_lastDispatchedIBEvent->SetState(CUES_UserContinued);
3790             }
3791
3792             // Send to the Win32 event thread to do the unmanaged continue for us.
3793             // If we're at a debug event, this will continue it.
3794             // Else it will degenerate into ResumeUnmanagedThreads();
3795             this->m_pShim->GetWin32EventThread()->SendUnmanagedContinue(this, cRealUMContinue);
3796         }
3797 #endif // FEATURE_INTEROP_DEBUGGING
3798
3799
3800         return S_OK;
3801     }
3802
3803     // If there are more managed events, get them dispatched now.
3804     if (!m_pShim->GetManagedEventQueue()->IsEmpty() && GetSynchronized())
3805     {
3806         STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::CI: managed event queued.\n");
3807
3808         // Mark that we're not synchronized anymore.
3809         SetSynchronized(false);
3810
3811         // If the callback queue is not empty, then the LS is not actually continuing, and so our cached
3812         // state is still valid. 
3813
3814         // If we're in the middle of dispatching a managed event, then simply return. This indicates to HandleRCEvent
3815         // that the user called Continue and HandleRCEvent will dispatch the next queued event. But if Continue was
3816         // called outside the managed callback, all we have to do is tell the RC event thread that something about the
3817         // process has changed and it will dispatch the next managed event.
3818         if (!AreDispatchingEvent())
3819         {
3820             STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::CI: continuing while not dispatching managed event.\n");
3821
3822             m_cordb->ProcessStateChanged();
3823         }
3824
3825         Unlock();
3826         return S_OK;
3827     }
3828
3829     // Neuter if we have an outstanding object.
3830     // Only do this if we're really continuining the debuggee. So don't do this if our stop-count is high b/c we
3831     // shouldn't neuter until we're done w/ the current event. And don't do this until we drain the current callback queue.
3832     // Note that we can't hold the process lock while we do this b/c Neutering may send IPC events.
3833     // However, we're still under the StopGo lock b/c that may help us serialize things.
3834
3835     // Sweep neuter list. This will catch anything that's marked as 'safe to neuter'. This includes
3836     // all objects added to the 'neuter-on-Continue'.
3837     // Only do this if we're synced- we don't want to do this if we're continuing from a Native Debug event.
3838     if (GetSynchronized())
3839     {
3840         // Need process-lock to operate on hashtable, but can't yet Neuter under process-lock,
3841         // so we have to copy the contents to an auxilary list which we can then traverse outside the lock.
3842         RSPtrArray<CordbAppDomain> listAppDomains;
3843         HRESULT hrCopy = S_OK;
3844         EX_TRY // @dbgtodo cleanup: push this up
3845         {
3846             m_appDomains.CopyToArray(&listAppDomains);
3847         }
3848         EX_CATCH_HRESULT(hrCopy);
3849         SetUnrecoverableIfFailed(GetProcess(), hrCopy);
3850
3851         m_ContinueNeuterList.NeuterAndClear(this);
3852
3853         // @dbgtodo left-side resources: eventually (once
3854         // NeuterLeftSideResources is process-lock safe), do this all under the
3855         // lock. Can't hold process lock b/c neutering left-side resources
3856         // may send events.
3857         Unlock();
3858
3859         // This may send IPC events. 
3860         // This will make normal neutering a nop.
3861         // This will toggle the process lock.
3862         m_LeftSideResourceCleanupList.SweepNeuterLeftSideResources(this);
3863
3864
3865         // Many objects (especially CordbValue, FuncEval) don't have clear lifetime semantics and
3866         // so they must be put into an exit-neuter list (Process/AppDomain) for worst-case scenarios.
3867         // These objects are likely released early, and so we sweep them aggressively on each Continue (kind of like a mini-GC).
3868         //
3869         // One drawback is that there may be a lot of useless sweeping if the debugger creates a lot of
3870         // objects that it holds onto. Consider instead of sweeping, have the object explicitly post itself
3871         // to a list that's guaranteed to be cleared. This would let us avoid sweeping not-yet-ready objects.
3872         // This will toggle the process lock
3873         m_ExitNeuterList.SweepAllNeuterAtWillObjects(this);
3874
3875
3876         for(unsigned int idx = 0; idx < listAppDomains.Length(); idx++)
3877         {
3878             CordbAppDomain * pAppDomain = listAppDomains[idx];
3879
3880             // CordbHandleValue is in the appdomain exit list, and that needs
3881             // to send an IPC event to cleanup and release the handle from
3882             // the GCs handle table. 
3883             // This will toggle the process lock.
3884             pAppDomain->GetSweepableExitNeuterList()->SweepNeuterLeftSideResources(this); 
3885         }
3886         listAppDomains.Clear();
3887
3888         Lock();
3889     }
3890
3891
3892     // At this point, if the managed event queue is empty, m_synchronized may still be true if we had previously
3893     // synchronized.
3894
3895 #ifdef FEATURE_INTEROP_DEBUGGING
3896     // Next, check for unmanaged events that may be queued. If there are some queued, then we need to get the Win32
3897     // event thread to go ahead and dispatch the next one. If there aren't any queued, then we can just fall through and
3898     // send the continue message to the left side. This works even if we have an outstanding ownership request, because
3899     // until that answer is received, its just like the event hasn't happened yet.
3900     //
3901     // If we're terminated, then we've already continued from the last win32 event and so don't continue.
3902     // @todo - or we could ensure the PS_SOME_THREADS_SUSPENDED | PS_HIJACKS_IN_PLACE are removed.
3903     // Either way, we're just protecting against exit-process at strange times.
3904     bool fDoWin32Continue = !m_terminated && ((m_state & (PS_WIN32_STOPPED | PS_SOME_THREADS_SUSPENDED | PS_HIJACKS_IN_PLACE)) != 0);
3905
3906     // We need to store this before marking the event user continued below
3907     BOOL fHasUserUncontinuedEvents = HasUserUncontinuedNativeEvents();
3908
3909     if(m_lastDispatchedIBEvent != NULL)
3910     {
3911         m_lastDispatchedIBEvent->SetState(CUES_UserContinued);
3912     }
3913
3914     if (fHasUserUncontinuedEvents)
3915     {
3916         // ExitProcess is the last debug event we'll get. The Process Handle is not signaled until
3917         // after we continue from ExitProcess. m_terminated is only set once we know the process is signaled.
3918         // (This isn't 100% true for the detach case, but since you can't do interop detach, we don't care)
3919         //_ASSERTE(!m_terminated);
3920
3921         STRESS_LOG1(LF_CORDB, LL_INFO1000, "CP::CI: there are queued uncontinued events. m_dispatchingUnmanagedEvent = %d\n", m_dispatchingUnmanagedEvent);
3922
3923         // Are we being called while in the unmanaged event callback?
3924         if (m_dispatchingUnmanagedEvent)
3925         {
3926             LOG((LF_CORDB, LL_INFO1000, "CP::CI: continue while dispatching.\n"));
3927             // The Win32ET could have made a cross-thread call to Continue while dispatching,
3928             // so we don't know if this is the win32 ET.
3929
3930             // Tell the Win32 thread to continue when it returns from handling its unmanaged callback.
3931             m_dispatchingUnmanagedEvent = false;
3932
3933             // If there are no more unmanaged events, then we fall through and continue the process for real. Otherwise,
3934             // we can simply return.
3935             if (HasUndispatchedNativeEvents())
3936             {
3937                 STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::CI: more unmanaged events need dispatching.\n");
3938
3939                 // Note: if we tried to access the Left Side while stopped but couldn't, then m_oddSync will be true. We
3940                 // need to reset it to false since we're continuing now.
3941                 m_oddSync = false;
3942
3943                 Unlock();
3944                 return S_OK;
3945             }
3946             else
3947             {
3948                 // Also, if there are no more unmanaged events, then when DispatchUnmanagedInBandEvent sees that
3949                 // m_dispatchingUnmanagedEvent is false, it will continue the process. So we set doWin32Continue to
3950                 // false here so that we don't try to double continue the process below.
3951                 STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::CI: no more unmanaged events to dispatch.\n");
3952
3953                 fDoWin32Continue = false;
3954             }
3955         }
3956         else
3957         {
3958             // after the DebugEvent callback returned the continue still had no been issued. Then later
3959             // on another thread the user called back to continue the event, which gets us to right here
3960             LOG((LF_CORDB, LL_INFO1000, "CP::CI: continue outside of dispatching.\n"));
3961
3962             // This should be the common place to Dispatch an IB event that was hijacked for sync.
3963
3964             // If we're not dispatching, this better not be the win32 event thread.
3965             _ASSERTE(!IsWin32EventThread());
3966
3967             // If the event at the head of the queue is really the last event, or if the event at the head of the queue
3968             // hasn't been dispatched yet, then we simply fall through and continue the process for real. However, if
3969             // its not the last event, we send to the Win32 event thread and get it to continue, then we return.
3970             if (HasUndispatchedNativeEvents())
3971             {
3972                 STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::CI: more unmanaged events need dispatching.\n");
3973
3974                 // Note: if we tried to access the Left Side while stopped but couldn't, then m_oddSync will be true. We
3975                 // need to reset it to false since we're continuing now.
3976                 m_oddSync = false;
3977
3978                 Unlock();
3979
3980                 hr = this->m_pShim->GetWin32EventThread()->SendUnmanagedContinue(this, cRealUMContinue);
3981
3982                 return hr;
3983             }
3984         }
3985     }
3986 #endif // FEATURE_INTEROP_DEBUGGING
3987
3988     // Both the managed and unmanaged event queues are now empty. Go
3989     // ahead and continue the process for real.
3990     LOG((LF_CORDB, LL_INFO1000, "CP::CI: headed for true continue.\n"));
3991
3992     // We need to check these while under the lock, but action must be
3993     // taked outside of the lock.
3994     bool fIsExiting = m_exiting;
3995     bool fWasSynchronized = GetSynchronized();
3996
3997     // Mark that we're no longer synchronized.
3998     if (fWasSynchronized)
3999     {
4000         LOG((LF_CORDB, LL_INFO1000, "CP::CI: process was synchronized.\n"));
4001
4002         SetSynchronized(false);
4003         SetSyncCompleteRecv(false);
4004
4005         // we're no longer in a callback, so set flags to indicate that we've finished. 
4006         GetShim()->NotifyOnContinue();
4007
4008         // Flush will update state, including continue counter and marking
4009         // frames dirty.
4010         this->FlushProcessRunning();
4011
4012
4013         // Tell the RC event thread that something about this process has changed.
4014         m_cordb->ProcessStateChanged();
4015     }
4016
4017     m_continueCounter++;
4018
4019     // If m_oddSync is set, then out last synchronization was due to us syncing the process because we were Win32
4020     // stopped. Therefore, while we do need to do most of the work to continue the process below, we don't actually have
4021     // to send the managed continue event. Setting wasSynchronized to false here helps us do that.
4022     if (m_oddSync)
4023     {
4024         fWasSynchronized = false;
4025         m_oddSync = false;
4026     }
4027
4028 #ifdef FEATURE_INTEROP_DEBUGGING
4029     // We must ensure that all managed threads are suspended here. We're about to let all managed threads run free via
4030     // the managed continue message to the Left Side. If we don't suspend the managed threads, then they may start
4031     // slipping forward even if we receive an in-band unmanaged event. We have to hijack in-band unmanaged events while
4032     // getting the managed continue message over to the Left Side to keep the process running free. Otherwise, the
4033     // SendIPCEvent will hang below. But in doing so, we could let managed threads slip to far. So we ensure they're all
4034     // suspended here.
4035     //
4036     // Note: we only do this suspension if the helper thread hasn't died yet. If the helper thread has died, then we
4037     // know that we're loosing the Runtime. No more managed code is going to run, so we don't bother trying to prevent
4038     // managed threads from slipping via the call below.
4039     //
4040     // Note: we just remember here, under the lock, so we can unlock then wait for the syncing thread to free the
4041     // debugger lock. Otherwise, we may block here and prevent someone from continuing from an OOB event, which also
4042     // prevents the syncing thread from releasing the debugger lock like we want it to.
4043     bool fNeedSuspend = fWasSynchronized && fDoWin32Continue && !m_helperThreadDead;
4044
4045     // If we receive a new in-band event once we unlock, we need to know to hijack it and keep going while we're still
4046     // trying to send the managed continue event to the process.
4047     if (fWasSynchronized && fDoWin32Continue && !fIsExiting)
4048     {
4049         m_specialDeferment = true;
4050     }
4051
4052     if (fNeedSuspend)
4053     {
4054         // @todo - what does this actually accomplish? We already suspended everything when we first synced.
4055
4056         // Any thread that may hold a lock blocking the helper is
4057         // inside of a can't stop region, and thus we won't suspend it.
4058         SuspendUnmanagedThreads();
4059     }
4060 #endif // FEATURE_INTEROP_DEBUGGING
4061
4062     Unlock();
4063
4064     // Although we've released the Process-lock, we still have the Stop-Go lock.
4065     _ASSERTE(m_StopGoLock.HasLock());
4066
4067     // If we're processing an ExitProcess managed event, then we don't want to really continue the process, so just fall
4068     // thru.  Note: we did let the unmanaged continue go through above for this case.
4069     if (fIsExiting)
4070     {
4071         LOG((LF_CORDB, LL_INFO1000, "CP::CI: continuing from exit case.\n"));
4072     }
4073     else if (fWasSynchronized)
4074     {
4075         LOG((LF_CORDB, LL_INFO1000, "CP::CI: Sending continue to AppD:0x%x.\n", VmPtrToCookie(pAppDomainToken)));
4076 #ifdef FEATURE_INTEROP_DEBUGGING
4077         STRESS_LOG2(LF_CORDB, LL_INFO1000, "Continue flags:special=%d, dowin32=%d\n", m_specialDeferment, fDoWin32Continue);
4078 #endif
4079         // Send to the RC to continue the process.
4080         DebuggerIPCEvent * pEvent = (DebuggerIPCEvent *) _alloca(CorDBIPC_BUFFER_SIZE);
4081
4082         InitIPCEvent(pEvent, DB_IPCE_CONTINUE, false, pAppDomainToken);
4083
4084         hr = m_cordb->SendIPCEvent(this, pEvent, CorDBIPC_BUFFER_SIZE);
4085
4086         // It is possible that we continue and then the process immediately exits before the helper
4087         // thread is finished continuing and can report success back to us. That's arguably a success
4088         // case sinceu the process did indeed continue, but since we didn't get the acknowledgement,
4089         // we can't be sure it's success. So we call it S_FALSE instead of S_OK.
4090         // @todo - how do we handle other failure here?
4091         if (hr == CORDBG_E_PROCESS_TERMINATED)
4092         {
4093             hr = S_FALSE;
4094         }
4095         _ASSERTE(SUCCEEDED(pEvent->hr));
4096
4097         LOG((LF_CORDB, LL_INFO1000, "CP::CI: Continue sent to AppD:0x%x.\n", VmPtrToCookie(pAppDomainToken)));
4098     }
4099
4100 #ifdef FEATURE_INTEROP_DEBUGGING
4101     // If we're win32 attached to the Left side, then we need to win32 continue the process too (unless, of course, it's
4102     // already been done above.)
4103     //
4104     // Note: we do this here because we want to get the Left Side to receive and ack our continue message above if we
4105     // were sync'd. If we were sync'd, then by definition the process (and the helper thread) is running anyway, so all
4106     // this continue is going to do is to let the threads that have been suspended go.
4107     if (fDoWin32Continue)
4108     {
4109 #ifdef _DEBUG
4110         {
4111             // A little pause here extends the special deferment region and thus causes native-debug
4112             // events to get hijacked. This test some wildly different corner case paths.
4113             // See VSWhidbey bugs 131905, 168971
4114             static DWORD dwRace = -1;
4115             if (dwRace == -1)
4116                 dwRace = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgRace);
4117
4118             if ((dwRace & 1) == 1)
4119             {
4120                 Sleep(30);
4121             }
4122         }
4123 #endif
4124
4125         STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::CI: sending unmanaged continue.\n");
4126
4127         // Send to the Win32 event thread to do the unmanaged continue for us.
4128         hr = this->m_pShim->GetWin32EventThread()->SendUnmanagedContinue(this, cRealUMContinue);
4129     }
4130 #endif // FEATURE_INTEROP_DEBUGGING
4131
4132     STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::CI: continue done, returning.\n");
4133
4134     return hr;
4135 }
4136
4137 HRESULT CordbProcess::HasQueuedCallbacks(ICorDebugThread *pThread,
4138                                          BOOL *pbQueued)
4139 {
4140     PUBLIC_REENTRANT_API_ENTRY(this);
4141     FAIL_IF_NEUTERED(this);
4142     VALIDATE_POINTER_TO_OBJECT_OR_NULL(pThread,ICorDebugThread *);
4143     VALIDATE_POINTER_TO_OBJECT(pbQueued,BOOL *);
4144
4145     // Shim owns the event queue
4146     if (m_pShim != NULL)
4147     {
4148         PUBLIC_CALLBACK_IN_THIS_SCOPE0_NO_LOCK(this); // Calling to shim, leaving RS.
4149         *pbQueued = m_pShim->GetManagedEventQueue()->HasQueuedCallbacks(pThread);
4150         return S_OK;
4151     }
4152     return E_NOTIMPL; // Not implemented in V3. 
4153 }
4154
4155 //
4156 // A small helper function to convert a CordbBreakpoint to an ICorDebugBreakpoint based on its type.
4157 //
4158 static ICorDebugBreakpoint *CordbBreakpointToInterface(CordbBreakpoint * pBreakpoint)
4159 {
4160     _ASSERTE(pBreakpoint != NULL);
4161
4162     //
4163     // I really dislike this. We've got three subclasses of CordbBreakpoint, but we store them all into the same hash
4164     // (m_breakpoints), so when we get one out of the hash, we don't really know what type it is. But we need to know
4165     // what type it is because we need to cast it to the proper interface before passing it out. I.e., when we create a
4166     // function breakpoint, we return the breakpoint casted to an ICorDebugFunctionBreakpoint. But if we grab that same
4167     // breakpoint out of the hash as a CordbBreakpoint and pass it out as an ICorDebugBreakpoint, then that's a
4168     // different pointer, and its wrong. So I've added the type to the breakpoint so we can cast properly here. I'd love
4169     // to do this a different way, though...
4170     //
4171     // -- Mon Dec 14 21:06:46 1998
4172     //
4173     switch(pBreakpoint->GetBPType())
4174     {
4175     case CBT_FUNCTION:
4176         return static_cast<ICorDebugFunctionBreakpoint *>(static_cast<CordbFunctionBreakpoint *> (pBreakpoint));
4177         break;
4178
4179     case CBT_MODULE:
4180         return static_cast<ICorDebugModuleBreakpoint*>(static_cast<CordbModuleBreakpoint *> (pBreakpoint));
4181         break;
4182
4183     case CBT_VALUE:
4184         return static_cast<ICorDebugValueBreakpoint *>(static_cast<CordbValueBreakpoint *> (pBreakpoint));
4185         break;
4186
4187     default:
4188         _ASSERTE(!"Invalid breakpoint type!");
4189     }
4190
4191     return NULL;
4192 }
4193
4194
4195 // Callback data for code:CordbProcess::GetAssembliesInLoadOrder
4196 class ShimAssemblyCallbackData
4197 {
4198 public:
4199     // Ctor to intialize callback data
4200     // 
4201     // Arguments:
4202     //   pAppDomain - appdomain that the assemblies are in.
4203     //   pAssemblies - preallocated array of smart pointers to hold assemblies
4204     //   countAssemblies - size of pAssemblies in elements.
4205     ShimAssemblyCallbackData(
4206         CordbAppDomain * pAppDomain,
4207         RSExtSmartPtr<ICorDebugAssembly>* pAssemblies,
4208         ULONG countAssemblies)
4209     {
4210         _ASSERTE(pAppDomain != NULL);
4211         _ASSERTE(pAssemblies != NULL);
4212
4213         m_pProcess = pAppDomain->GetProcess();
4214         m_pAppDomain = pAppDomain;
4215         m_pAssemblies = pAssemblies;
4216         m_countElements = countAssemblies;
4217         m_index = 0;
4218
4219         // Just to be safe, clear them all out
4220         for(ULONG i = 0; i < countAssemblies; i++)
4221         {
4222             pAssemblies[i].Clear();
4223         }
4224     }   
4225
4226     // Dtor
4227     // 
4228     // Notes:
4229     //   This can assert end-of-enumeration invariants.
4230     ~ShimAssemblyCallbackData()
4231     {
4232         // Ensure that we went through all assemblies.
4233         _ASSERTE(m_index == m_countElements);
4234     }
4235     
4236     // Callback invoked from DAC enumeration.
4237     // 
4238     // arguments:
4239     //    vmDomainAssembly - VMPTR for assembly
4240     //    pData - a 'this' pointer
4241     //  
4242     static void Callback(VMPTR_DomainAssembly vmDomainAssembly, void * pData)
4243     {
4244         ShimAssemblyCallbackData * pThis = static_cast<ShimAssemblyCallbackData *> (pData);
4245         INTERNAL_DAC_CALLBACK(pThis->m_pProcess);
4246
4247         CordbAssembly * pAssembly = pThis->m_pAppDomain->LookupOrCreateAssembly(vmDomainAssembly);
4248
4249         pThis->SetAndMoveNext(pAssembly);
4250     }
4251
4252     // Set the current index in the table and increment the cursor.
4253     // 
4254     // Arguments:
4255     //    pAssembly - assembly from DAC enumerator
4256     void SetAndMoveNext(CordbAssembly * pAssembly)
4257     {
4258         _ASSERTE(pAssembly != NULL);
4259
4260         if (m_index >= m_countElements)
4261         {
4262             // Enumerating the assemblies in the target should be fixed since
4263             // the target is not running. 
4264             // We should never get here unless the target is unstable. 
4265             // The caller (the shim) pre-allocated the table of assemblies.
4266             m_pProcess->TargetConsistencyCheck(!"Target changed assembly count");
4267             return;
4268         }
4269
4270         m_pAssemblies[m_index].Assign(pAssembly);
4271         m_index++;
4272     }
4273
4274 protected:
4275     CordbProcess * m_pProcess;
4276     CordbAppDomain * m_pAppDomain;
4277     RSExtSmartPtr<ICorDebugAssembly>* m_pAssemblies;
4278     ULONG m_countElements;
4279     ULONG m_index;
4280 };
4281
4282 //---------------------------------------------------------------------------------------
4283 // Shim Helper to enumerate the assemblies in the load-order
4284 // 
4285 // Arguments:
4286 //    pAppdomain - non-null appdmomain to enumerate assemblies.
4287 //    pAssemblies - caller pre-allocated array to hold assemblies
4288 //    countAssemblies - size of the array.
4289 //    
4290 // Notes:
4291 //    Caller preallocated array (likely from ICorDebugAssemblyEnum::GetCount),
4292 //    and now this function fills in the assemblies in the order they were
4293 //    loaded.
4294 //    
4295 //    The target should be stable, such that the number of assemblies in the
4296 //    target is stable, and therefore countAssemblies as determined by the
4297 //    shim via ICorDebugAssemblyEnum::GetCount should match the number of
4298 //    assemblies enumerated here. 
4299 //    
4300 //    Called by code:ShimProcess::QueueFakeAttachEvents. 
4301 //    This provides the assemblies in load-order. In contrast,
4302 //    ICorDebugAppDomain::EnumerateAssemblies is a random order. The shim needs
4303 //    load-order to match Whidbey semantics for dispatching fake load-assembly
4304 //    callbacks on attach. The debugger then uses the order
4305 //    in its module display window.
4306 //    
4307 void CordbProcess::GetAssembliesInLoadOrder(
4308     ICorDebugAppDomain * pAppDomain, 
4309     RSExtSmartPtr<ICorDebugAssembly>* pAssemblies,
4310     ULONG countAssemblies)
4311 {
4312     PUBLIC_API_ENTRY_FOR_SHIM(this);
4313     RSLockHolder lockHolder(GetProcessLock());
4314
4315     _ASSERTE(GetShim() != NULL);
4316
4317     CordbAppDomain * pAppDomainInternal = static_cast<CordbAppDomain *> (pAppDomain);
4318
4319     ShimAssemblyCallbackData data(pAppDomainInternal, pAssemblies, countAssemblies);
4320
4321     // Enumerate through and fill out pAssemblies table.
4322     GetDAC()->EnumerateAssembliesInAppDomain(
4323         pAppDomainInternal->GetADToken(),
4324         ShimAssemblyCallbackData::Callback,
4325         &data); // user data
4326
4327     // pAssemblies array has now been updated. 
4328 }
4329
4330 // Callback data for code:CordbProcess::GetModulesInLoadOrder
4331 class ShimModuleCallbackData
4332 {
4333 public:
4334     // Ctor to intialize callback data
4335     // 
4336     // Arguments:
4337     //   pAssembly - assembly that the Modules are in.
4338     //   pModules - preallocated array of smart pointers to hold Modules
4339     //   countModules - size of pModules in elements.
4340     ShimModuleCallbackData(
4341         CordbAssembly * pAssembly,
4342         RSExtSmartPtr<ICorDebugModule>* pModules,
4343         ULONG countModules)
4344     {
4345         _ASSERTE(pAssembly != NULL);
4346         _ASSERTE(pModules != NULL);
4347
4348         m_pProcess = pAssembly->GetAppDomain()->GetProcess();
4349         m_pAssembly = pAssembly;
4350         m_pModules = pModules;
4351         m_countElements = countModules;
4352         m_index = 0;
4353
4354         // Just to be safe, clear them all out
4355         for(ULONG i = 0; i < countModules; i++)
4356         {
4357             pModules[i].Clear();
4358         }
4359     }   
4360
4361     // Dtor
4362     // 
4363     // Notes:
4364     //   This can assert end-of-enumeration invariants.
4365     ~ShimModuleCallbackData()
4366     {
4367         // Ensure that we went through all Modules.
4368         _ASSERTE(m_index == m_countElements);
4369     }
4370     
4371     // Callback invoked from DAC enumeration.
4372     // 
4373     // arguments:
4374     //    vmDomainFile - VMPTR for Module
4375     //    pData - a 'this' pointer
4376     //  
4377     static void Callback(VMPTR_DomainFile vmDomainFile, void * pData)
4378     {
4379         ShimModuleCallbackData * pThis = static_cast<ShimModuleCallbackData *> (pData);
4380         INTERNAL_DAC_CALLBACK(pThis->m_pProcess);
4381
4382         CordbModule * pModule = pThis->m_pAssembly->GetAppDomain()->LookupOrCreateModule(vmDomainFile);
4383
4384         pThis->SetAndMoveNext(pModule);
4385     }
4386
4387     // Set the current index in the table and increment the cursor.
4388     // 
4389     // Arguments:
4390     //    pModule - Module from DAC enumerator
4391     void SetAndMoveNext(CordbModule * pModule)
4392     {
4393         _ASSERTE(pModule != NULL);
4394
4395         if (m_index >= m_countElements)
4396         {
4397             // Enumerating the Modules in the target should be fixed since
4398             // the target is not running. 
4399             // We should never get here unless the target is unstable. 
4400             // The caller (the shim) pre-allocated the table of Modules.
4401             m_pProcess->TargetConsistencyCheck(!"Target changed Module count");
4402             return;
4403         }
4404
4405         m_pModules[m_index].Assign(pModule);
4406         m_index++;
4407     }
4408
4409 protected:
4410     CordbProcess * m_pProcess;
4411     CordbAssembly * m_pAssembly;
4412     RSExtSmartPtr<ICorDebugModule>* m_pModules;
4413     ULONG m_countElements;
4414     ULONG m_index;
4415 };
4416
4417 //---------------------------------------------------------------------------------------
4418 // Shim Helper to enumerate the Modules in the load-order
4419 // 
4420 // Arguments:
4421 //    pAppdomain - non-null appdmomain to enumerate Modules.
4422 //    pModules - caller pre-allocated array to hold Modules
4423 //    countModules - size of the array.
4424 //    
4425 // Notes:
4426 //    Caller preallocated array (likely from ICorDebugModuleEnum::GetCount),
4427 //    and now this function fills in the Modules in the order they were
4428 //    loaded.
4429 //    
4430 //    The target should be stable, such that the number of Modules in the
4431 //    target is stable, and therefore countModules as determined by the
4432 //    shim via ICorDebugModuleEnum::GetCount should match the number of
4433 //    Modules enumerated here. 
4434 //    
4435 //    Called by code:ShimProcess::QueueFakeAssemblyAndModuleEvent.
4436 //    This provides the Modules in load-order. In contrast,
4437 //    ICorDebugAssembly::EnumerateModules is a random order. The shim needs
4438 //    load-order to match Whidbey semantics for dispatching fake load-Module
4439 //    callbacks on attach. The most important thing is that the manifest module
4440 //    gets a LodModule callback before any secondary modules.  For dynamic
4441 //    modules, this is necessary for operations on the secondary module
4442 //    that rely on manifest metadata (eg. GetSimpleName).
4443 //    
4444 //    @dbgtodo : This is almost identical to GetAssembliesInLoadOrder, and 
4445 //    (together wih the CallbackData classes) seems a HUGE amount of code and 
4446 //    complexity for such a simple thing.  We also have extra code to order
4447 //    AppDomains and Threads.  We should try and rip all of this extra complexity
4448 //    out, and replace it with better data structures for storing these items.
4449 //    Eg., if we used std::map, we could have efficient lookups and ordered 
4450 //    enumerations.  However, we do need to be careful about exposing new invariants
4451 //    through ICorDebug that customers may depend on, which could place a long-term
4452 //    compatibility burden on us.  We could have a simple generic data structure
4453 //    (eg. built on std::hash_map and std::list) which provided efficient look-up
4454 //    and both in-order and random enumeration.
4455 //    
4456 void CordbProcess::GetModulesInLoadOrder(
4457     ICorDebugAssembly * pAssembly, 
4458     RSExtSmartPtr<ICorDebugModule>* pModules,
4459     ULONG countModules)
4460 {
4461     PUBLIC_API_ENTRY_FOR_SHIM(this);
4462     RSLockHolder lockHolder(GetProcessLock());
4463
4464     _ASSERTE(GetShim() != NULL);
4465
4466     CordbAssembly * pAssemblyInternal = static_cast<CordbAssembly *> (pAssembly);
4467
4468     ShimModuleCallbackData data(pAssemblyInternal, pModules, countModules);
4469
4470     // Enumerate through and fill out pModules table.
4471     GetDAC()->EnumerateModulesInAssembly(
4472         pAssemblyInternal->GetDomainAssemblyPtr(),
4473         ShimModuleCallbackData::Callback,
4474         &data); // user data
4475
4476     // pModules array has now been updated. 
4477 }
4478
4479
4480 //---------------------------------------------------------------------------------------
4481 // Callback to count the number of enumerations in a process.
4482 // 
4483 // Arguments:
4484 //     id - the connection id.
4485 //     pName - name of the connection
4486 //     pUserData - an EnumerateConnectionsData
4487 //
4488 // Notes:
4489 //    Helper function for code:CordbProcess::QueueFakeConnectionEvents
4490 //
4491 // static 
4492 void CordbProcess::CountConnectionsCallback(DWORD id, LPCWSTR pName, void * pUserData)
4493 {
4494 }
4495
4496 //---------------------------------------------------------------------------------------
4497 // Callback to enumerate all the connections in a process.
4498 // 
4499 // Arguments:
4500 //     id - the connection id.
4501 //     pName - name of the connection
4502 //     pUserData - an EnumerateConnectionsData
4503 //
4504 // Notes:
4505 //    Helper function for code:CordbProcess::QueueFakeConnectionEvents
4506 //
4507 // static  
4508 void CordbProcess::EnumerateConnectionsCallback(DWORD id, LPCWSTR pName, void * pUserData)
4509 {
4510 }
4511
4512 //---------------------------------------------------------------------------------------
4513 // Callback from Shim to queue fake Connection events on attach.
4514 //
4515 // Notes:
4516 //    See code:ShimProcess::QueueFakeAttachEvents
4517 void CordbProcess::QueueFakeConnectionEvents()
4518 {
4519     PUBLIC_API_ENTRY_FOR_SHIM(this);
4520
4521 }
4522
4523 //
4524 // DispatchRCEvent -- dispatches a previously queued IPC event received
4525 // from the runtime controller. This represents the last amount of processing
4526 // the DI gets to do on an event before giving it to the user.
4527 //
4528 void CordbProcess::DispatchRCEvent()
4529 {
4530     INTERNAL_API_ENTRY(this);
4531
4532     CONTRACTL
4533     {
4534         // This is happening on the RCET thread, so there's no place to propogate an error back up.
4535         NOTHROW;
4536     }
4537     CONTRACTL_END;
4538
4539     _ASSERTE(m_pShim != NULL); // V2 case
4540
4541     //
4542     // Note: the current thread should have the process locked when it
4543     // enters this method.
4544     //
4545     _ASSERTE(ThreadHoldsProcessLock());
4546
4547     // Create/Launch paths already ensured that we had a callback.
4548     _ASSERTE(m_cordb != NULL);
4549     _ASSERTE(m_cordb->m_managedCallback != NULL);
4550     _ASSERTE(m_cordb->m_managedCallback2 != NULL);
4551     _ASSERTE(m_cordb->m_managedCallback3 != NULL);
4552
4553
4554     // Bump up the stop count. Either we'll dispatch a managed event,
4555     // or the logic below will decide not to dispatch one and call
4556     // Continue itself. Either way, the stop count needs to go up by
4557     // one...
4558     _ASSERTE(this->GetSyncCompleteRecv());
4559     SetSynchronized(true);
4560     IncStopCount();
4561
4562     // As soon as we call Unlock(), we might get neutered and lose our reference to
4563     // the shim.  Grab it now for use later.
4564     RSExtSmartPtr<ShimProcess> pShim(m_pShim);
4565
4566     Unlock();
4567
4568     _ASSERTE(!ThreadHoldsProcessLock());
4569
4570
4571     // We want to stay synced until after the callbacks return. This is b/c we're on the RCET,
4572     // and we may deadlock if we send IPC events on the RCET if we're not synced (see SendIPCEvent for details).
4573     // So here, stopcount=1. The StopContinueHolder bumps it up to 2.
4574     // - If Cordbg calls continue in the callback, that bumps it back down to 1, but doesn't actually continue.
4575     //   The holder dtor then bumps it down to 0, doing the real continue.
4576     // - If Cordbg doesn't call continue in the callback, then stopcount stays at 2, holder dtor drops it down to 1,
4577     //   and then the holder was just a nop.
4578     // This gives us delayed continues w/ no extra state flags.
4579
4580
4581     // The debugger may call Detach() immediately after it returns from the callback, but before this thread returns 
4582     // from this function.  Thus after we execute the callbacks, it's possible the CordbProcess object has been neutered.
4583     
4584     // Since we're already sycned, the Stop from the holder here is practically a nop that just bumps up a count.
4585     // Create an extra scope for the StopContinueHolder.
4586     {
4587         StopContinueHolder h;
4588         HRESULT hr = h.Init(this);
4589         if (FAILED(hr))
4590         {
4591             CORDBSetUnrecoverableError(this, hr, 0);
4592         }
4593
4594         HRESULT hrCallback = S_OK;
4595         // It's possible a ICorDebugProcess::Detach() may have occurred by now. 
4596         {
4597             // @dbgtodo shim: eventually the entire RCET should be considered outside the RS.
4598             PUBLIC_CALLBACK_IN_THIS_SCOPE0_NO_LOCK(this); 
4599
4600
4601             // Snag the first event off the queue.    
4602             // Holder will call Delete, which will invoke virtual Dtor that will release ICD objects.
4603             // Since these are external refs, we want to do it while "outside" the RS.
4604             NewHolder<ManagedEvent> pEvent(pShim->DequeueManagedEvent());
4605
4606             // Normally pEvent shouldn't be NULL, since this method is called when the queue is not empty.
4607             // But due to a race between CordbProcess::Terminate(), CordbWin32EventThread::ExitProcess() and this method
4608             // it is totally possible that the queue has already been cleaned up and we can't expect that event is always available.
4609             if (pEvent != NULL)
4610             {
4611                 // Since we need to access a member (m_cordb), protect this block with a
4612                 // lock and a check for Neutering (in case process detach has just
4613                 // occurred).  We'll release the lock around the dispatch later on.
4614                 RSLockHolder lockHolder(GetProcessLock());
4615                 if (!IsNeutered())
4616                 {
4617 #ifdef _DEBUG
4618                     // On a debug build, keep track of the last IPC event we dispatched.
4619                     m_pDBGLastIPCEventType = pEvent->GetDebugCookie();
4620 #endif
4621
4622                     ManagedEvent::DispatchArgs args(m_cordb->m_managedCallback, m_cordb->m_managedCallback2, m_cordb->m_managedCallback3);        
4623
4624                     {
4625                         // Release lock around the dispatch of the event
4626                         RSInverseLockHolder inverseLockHolder(GetProcessLock());
4627
4628                         EX_TRY
4629                         {
4630                             // This dispatches almost directly into the user's callbacks.
4631                             // It does not update any RS state.
4632                             hrCallback = pEvent->Dispatch(args);
4633                         } 
4634                         EX_CATCH_HRESULT(hrCallback);
4635                     }
4636                 }
4637             }
4638
4639         } // we're now back inside the RS
4640
4641         if (hrCallback == E_NOTIMPL)
4642         {
4643             ContinueInternal(FALSE);
4644         }
4645         
4646            
4647     } // forces Continue to be called
4648
4649     Lock();  
4650
4651 };
4652
4653 #ifdef _DEBUG
4654 //---------------------------------------------------------------------------------------
4655 // Debug-only callback to ensure that an appdomain is not available after the ExitAppDomain event.
4656 // 
4657 // Arguments:
4658 //    vmAppDomain - appdomain from enumeration
4659 //    pUserData - pointer to a DbgAssertAppDomainDeletedData which contains the VMAppDomain that was just deleted.
4660 // notes:
4661 //    see code:CordbProcess::DbgAssertAppDomainDeleted for details.
4662 void CordbProcess::DbgAssertAppDomainDeletedCallback(VMPTR_AppDomain vmAppDomain, void * pUserData)
4663 {
4664     DbgAssertAppDomainDeletedData * pCallbackData = reinterpret_cast<DbgAssertAppDomainDeletedData *>(pUserData);
4665     INTERNAL_DAC_CALLBACK(pCallbackData->m_pThis);
4666
4667     VMPTR_AppDomain vmAppDomainDeleted = pCallbackData->m_vmAppDomainDeleted;
4668     CONSISTENCY_CHECK_MSGF((vmAppDomain != vmAppDomainDeleted), 
4669         ("An ExitAppDomain event was sent for appdomain, but it still shows up in the enumeration.\n vmAppDomain=%p\n", 
4670         VmPtrToCookie(vmAppDomainDeleted)));
4671 }
4672
4673 //---------------------------------------------------------------------------------------
4674 // Debug-only helper to Assert that VMPTR is actually removed.
4675 // 
4676 // Arguments:
4677 //    vmAppDomainDeleted - vmptr of appdomain that we just got exit event for. 
4678 //       This should not be discoverable from the RS.
4679 //       
4680 // Notes:
4681 //   See code:IDacDbiInterface#Enumeration for rules that we're asserting.
4682 //   Once the exit appdomain event is dispatched, the appdomain should not be discoverable by the RS.
4683 //   Else the RS may use the AppDomain* after it's deleted. 
4684 //   This asserts that the AppDomain* is not discoverable. 
4685 //
4686 //   Since this is a debug-only function, it should have no side-effects.
4687 void CordbProcess::DbgAssertAppDomainDeleted(VMPTR_AppDomain vmAppDomainDeleted)
4688 {
4689     DbgAssertAppDomainDeletedData callbackData;
4690     callbackData.m_pThis = this;
4691     callbackData.m_vmAppDomainDeleted = vmAppDomainDeleted;
4692
4693     GetDAC()->EnumerateAppDomains(
4694         CordbProcess::DbgAssertAppDomainDeletedCallback,
4695         &callbackData);
4696 }
4697
4698 #endif  // _DEBUG
4699
4700 //---------------------------------------------------------------------------------------
4701 // Update state and potentially Dispatch a single event.
4702 //
4703 // Arguments:
4704 //    pEvent - non-null pointer to debug event.
4705 //    pCallback1 - callback object to dispatch on (for V1 callbacks)
4706 //    pCallback2 - 2nd callback object to dispatch on (for new V2 callbacks)
4707 //    pCallback3 - 3rd callback object to dispatch on (for new V4 callbacks)
4708 //       
4709 //
4710 // Returns:
4711 //    Nothing. Throws on error. 
4712 //       
4713 // Notes:
4714 //    Generally, this will dispatch exactly 1 callback. It may dispatch 0 callbacks if there is an error
4715 //    or in other corner cases (documented within the dispatch code below). 
4716 //    Errors could occur because:
4717 //    - the event is corrupted (exceptional case)
4718 //    - the RS is corrupted / OOM (exceptional case)
4719 //    Exception errors here will propogate back to the Filter() call, and there's not really anything
4720 //    a debugger can do about an error here (perhaps report it to the user).
4721 //    Errors must leave IcorDebug in a consistent state. 
4722 //
4723 //    This is dispatched directly on the Win32Event Thread in response to calling Filter.
4724 //    Therefore, this can't send any IPC events (Not an issue once everything is DAC-ized).
4725 //    A V2 shim can provide a proxy calllack that takes these events and queues them and 
4726 //    does the real dispatch to the user to emulate V2 semantics.
4727 //
4728 #ifdef _PREFAST_
4729 #pragma warning(push)
4730 #pragma warning(disable:21000) // Suppress PREFast warning about overly large function
4731 #endif
4732 void CordbProcess::RawDispatchEvent(
4733     DebuggerIPCEvent *          pEvent, 
4734     RSLockHolder *              pLockHolder,
4735     ICorDebugManagedCallback *  pCallback1, 
4736     ICorDebugManagedCallback2 * pCallback2,
4737     ICorDebugManagedCallback3 * pCallback3)
4738 {
4739     CONTRACTL
4740     {
4741         THROWS;
4742     }
4743     CONTRACTL_END;
4744
4745     HRESULT hr = S_OK;
4746     // We start off with the lock, and we'll toggle it.
4747     _ASSERTE(ThreadHoldsProcessLock());
4748
4749
4750     //
4751     // Call StartEventDispatch to true to guard against calls to Continue()
4752     // from within the user's callback. We need Continue() to behave a little
4753     // bit differently in such a case.
4754     //
4755     // Also note that Win32EventThread::ExitProcess will take the lock and free all
4756     // events in the queue. (the current event is already off the queue, so
4757     // it will be ok). But we can't do the EP callback in the middle of this dispatch
4758     // so if this flag is set, EP will wait on the miscWaitEvent (which will
4759     // get set in FlushQueuedEvents when we return from here) and let us finish here.
4760     //
4761     StartEventDispatch(pEvent->type); 
4762
4763     // Keep strong references to these objects in case a callback deletes them from underneath us.
4764     RSSmartPtr<CordbAppDomain> pAppDomain;
4765     CordbThread * pThread = NULL;
4766
4767    
4768     // Get thread that this event is on. In attach scenarios, this may be the first time ICorDebug has seen this thread.
4769     if (!pEvent->vmThread.IsNull())
4770     {
4771         pThread = LookupOrCreateThread(pEvent->vmThread); 
4772     }
4773
4774     if (!pEvent->vmAppDomain.IsNull())
4775     {
4776         pAppDomain.Assign(LookupOrCreateAppDomain(pEvent->vmAppDomain));
4777     }
4778
4779     DWORD dwVolatileThreadId = 0;
4780     if (pThread != NULL) 
4781     {
4782         dwVolatileThreadId = pThread->GetUniqueId();
4783     }
4784
4785
4786     //
4787     // Update the app domain that this thread lives in.
4788     //
4789     if ((pThread != NULL) && (pAppDomain != NULL))
4790     {
4791         // It shouldn't be possible for us to see an exited AppDomain here
4792         _ASSERTE( !pAppDomain->IsNeutered() );
4793         
4794          pThread->m_pAppDomain = pAppDomain;
4795     }
4796
4797     _ASSERTE(pEvent != NULL);
4798     _ASSERTE(pCallback1 != NULL);
4799     _ASSERTE(pCallback2 != NULL);
4800     _ASSERTE(pCallback3 != NULL);
4801     
4802
4803     STRESS_LOG1(LF_CORDB, LL_EVERYTHING, "Pre-Dispatch IPC event: %s\n", IPCENames::GetName(pEvent->type));
4804
4805     switch (pEvent->type & DB_IPCE_TYPE_MASK)
4806     {
4807     case DB_IPCE_CREATE_PROCESS:
4808         {
4809             PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
4810             pCallback1->CreateProcess(static_cast<ICorDebugProcess*> (this));
4811         }
4812         break;
4813
4814     case DB_IPCE_BREAKPOINT:
4815         {
4816             _ASSERTE(pThread != NULL);
4817             _ASSERTE(pAppDomain != NULL);
4818
4819             // Find the breakpoint object on this side.            
4820             CordbBreakpoint *pBreakpoint = NULL;
4821
4822             // We've found cases out in the wild where we get this event on a thread we don't recognize.
4823             // We're not sure how this happens. Add a runtime check to protect ourselves to avoid the 
4824             // an AV. We still assert because this should not be happening.
4825             // It likely means theres some issue where we failed to send a CreateThread notification.
4826             TargetConsistencyCheck(pThread != NULL);
4827             pBreakpoint = pAppDomain->m_breakpoints.GetBase(LsPtrToCookie(pEvent->BreakpointData.breakpointToken));
4828
4829             if (pBreakpoint != NULL)
4830             {
4831                 ICorDebugBreakpoint * pIBreakpoint = CordbBreakpointToInterface(pBreakpoint);
4832                 _ASSERTE(pIBreakpoint != NULL);
4833
4834                 {
4835                     PUBLIC_CALLBACK_IN_THIS_SCOPE2(this, pLockHolder, pEvent, "thread=0x%p, bp=0x%p", pThread, pBreakpoint);
4836                     pCallback1->Breakpoint(pAppDomain, pThread, pIBreakpoint);
4837                 }
4838             }
4839         }
4840         break;
4841
4842     case DB_IPCE_USER_BREAKPOINT:
4843         {
4844             STRESS_LOG1(LF_CORDB, LL_INFO1000, "[%x] RCET::DRCE: user breakpoint.\n",
4845                  GetCurrentThreadId());
4846
4847             _ASSERTE(pThread != NULL);
4848             _ASSERTE(pAppDomain != NULL);
4849             _ASSERTE(pThread->m_pAppDomain != NULL);
4850
4851             {
4852                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
4853                 pCallback1->Break(pThread->m_pAppDomain, pThread);
4854             }
4855
4856         }
4857         break;
4858
4859     case DB_IPCE_STEP_COMPLETE:
4860         {
4861             STRESS_LOG1(LF_CORDB, LL_INFO1000, "[%x] RCET::DRCE: step complete.\n",
4862                  GetCurrentThreadId());
4863
4864             PREFIX_ASSUME(pThread != NULL);
4865
4866             CordbStepper * pStepper = m_steppers.GetBase(LsPtrToCookie(pEvent->StepData.stepperToken));
4867
4868             // It's possible the stepper is NULL if:
4869             // - event X & step-complete are both in the queue
4870             // - during dispatch for event X, Cordbg cancels the stepper (thus removing it from m_steppers)
4871             // - the Step-Complete still stays in the queue, and so we're here, but out stepper's been removed.
4872             // (This could happen for breakpoints too)
4873             // Don't dispatch a callback if the stepper is NULL.
4874             if (pStepper != NULL)
4875             {
4876                 RSSmartPtr<CordbStepper> pRef(pStepper);
4877                 pStepper->m_active = false;
4878                 m_steppers.RemoveBase((ULONG_PTR)pStepper->m_id);
4879
4880                 {
4881                     _ASSERTE(pThread->m_pAppDomain != NULL);
4882                     PUBLIC_CALLBACK_IN_THIS_SCOPE2(this, pLockHolder, pEvent, "thrad=0x%p, stepper=0x%p", pThread, pStepper);
4883                     pCallback1->StepComplete(pThread->m_pAppDomain, pThread, pStepper, pEvent->StepData.reason);
4884                 }
4885
4886                 // implicit Release on pRef
4887             }
4888         }
4889         break;
4890
4891     case DB_IPCE_EXCEPTION:
4892         {
4893             STRESS_LOG1(LF_CORDB, LL_INFO1000, "[%x] RCET::DRCE: exception.\n",
4894                  GetCurrentThreadId());
4895
4896             _ASSERTE(pAppDomain != NULL);
4897
4898             // For some exceptions very early in startup (eg, TypeLoad), this may have occurred before we
4899             // even executed jitted code on the thread. We may have not received a CreateThread yet.
4900             // In V2, we detected this and sent a LogMessage on a random thread.
4901             // In V3, we lazily create the CordbThread objects (possibly before the CreateThread event),
4902             // and so we know we should have one.            
4903             _ASSERTE(pThread != NULL);
4904             
4905             pThread->SetExInfo(pEvent->Exception.vmExceptionHandle);
4906
4907             _ASSERTE(pThread->m_pAppDomain != NULL);
4908
4909             {
4910                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
4911                 pCallback1->Exception(pThread->m_pAppDomain, pThread, !pEvent->Exception.firstChance);
4912             }
4913
4914         }
4915         break;
4916
4917     case DB_IPCE_SYNC_COMPLETE:
4918         _ASSERTE(!"Should have never queued a sync complete pEvent.");
4919         break;
4920
4921     case DB_IPCE_THREAD_ATTACH:
4922         {
4923             STRESS_LOG1(LF_CORDB, LL_INFO100, "RCET::DRCE: thread attach : ID=%x.\n", dwVolatileThreadId);
4924
4925             TargetConsistencyCheck(pThread != NULL);
4926             {
4927                 PUBLIC_CALLBACK_IN_THIS_SCOPE1(this, pLockHolder, pEvent, "thread=0x%p", pThread);
4928                 pCallback1->CreateThread(pAppDomain, pThread);
4929             }
4930         }
4931         break;
4932
4933     case DB_IPCE_THREAD_DETACH:
4934         {
4935             STRESS_LOG2(LF_CORDB, LL_INFO100, "[%x] RCET::HRCE: thread detach : ID=%x \n",
4936                  GetCurrentThreadId(), dwVolatileThreadId);
4937
4938             // If the runtime thread never entered managed code, there
4939             // won't be a CordbThread, and CreateThread was never
4940             // called, so don't bother calling ExitThread.
4941             if (pThread != NULL)
4942             {
4943                 AddToNeuterOnContinueList(pThread);
4944
4945                 RSSmartPtr<CordbThread>    pRefThread(pThread);
4946
4947                 _ASSERTE(pAppDomain != NULL);
4948
4949                 // A thread is reported as dead before we get the exit event.                
4950                 // See code:IDacDbiInterface#IsThreadMarkedDead for the invariant being asserted here.
4951                 TargetConsistencyCheck(pThread->IsThreadDead());
4952
4953                 // Enforce the enumeration invariants (see code:IDacDbiInterface#Enumeration)that the thread is not discoverable.
4954                 INDEBUG(pThread->DbgAssertThreadDeleted());
4955
4956                 // Remove the thread from the hash. If we've removed it from the hash, we really should
4957                 // neuter it ... but that causes test failures.
4958                 // We'll neuter it in continue.
4959                 m_userThreads.RemoveBase(VmPtrToCookie(pThread->m_vmThreadToken));
4960
4961
4962                 LOG((LF_CORDB, LL_INFO1000, "[%x] RCET::HRCE: sending thread detach.\n", GetCurrentThreadId()));
4963
4964                 {
4965                     PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
4966                     pCallback1->ExitThread(pAppDomain, pThread);
4967                 }
4968
4969                 // Implicit release on thread & pAppDomain
4970             }
4971         }
4972         break;
4973
4974     case DB_IPCE_METADATA_UPDATE:
4975         {
4976             CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->MetadataUpdateData.vmDomainFile);
4977             pModule->RefreshMetaData();
4978         }
4979         break;
4980
4981     case DB_IPCE_LOAD_MODULE:
4982         {
4983             _ASSERTE (pAppDomain != NULL);
4984             CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->LoadModuleData.vmDomainFile);                        
4985             
4986             {         
4987                 pModule->SetLoadEventContinueMarker();
4988
4989                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
4990                 pCallback1->LoadModule(pAppDomain, pModule);
4991             }
4992
4993         }
4994         break;
4995
4996     case DB_IPCE_CREATE_CONNECTION:
4997         {
4998             STRESS_LOG1(LF_CORDB, LL_INFO100,
4999                 "RCET::HRCE: Connection change %d \n",
5000                 pEvent->CreateConnection.connectionId);
5001
5002             // pass back the connection id and the connection name.
5003             PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5004             pCallback2->CreateConnection(
5005                 this,
5006                 pEvent->CreateConnection.connectionId,
5007                 const_cast<WCHAR*> (pEvent->CreateConnection.wzConnectionName.GetString()));
5008         }   
5009         break;
5010
5011     case DB_IPCE_DESTROY_CONNECTION:
5012         {
5013             STRESS_LOG1(LF_CORDB, LL_INFO100,
5014                  "RCET::HRCE: Connection destroyed %d \n",
5015                  pEvent->ConnectionChange.connectionId);
5016             PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5017             pCallback2->DestroyConnection(this, pEvent->ConnectionChange.connectionId);
5018         }
5019         break;
5020
5021     case DB_IPCE_CHANGE_CONNECTION:
5022         {
5023             STRESS_LOG1(LF_CORDB, LL_INFO100,
5024                  "RCET::HRCE: Connection changed %d \n",
5025                  pEvent->ConnectionChange.connectionId);
5026
5027             PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5028             pCallback2->ChangeConnection(this, pEvent->ConnectionChange.connectionId);
5029         }
5030         break;
5031
5032     case DB_IPCE_UNLOAD_MODULE:
5033         {
5034             STRESS_LOG3(LF_CORDB, LL_INFO100, "RCET::HRCE: unload module on thread %#x Mod:0x%x AD:0x%08x\n",
5035                  dwVolatileThreadId,
5036                  VmPtrToCookie(pEvent->UnloadModuleData.vmDomainFile),
5037                  VmPtrToCookie(pEvent->vmAppDomain));
5038
5039             PREFIX_ASSUME (pAppDomain != NULL);
5040             
5041             CordbModule *module = pAppDomain->LookupOrCreateModule(pEvent->UnloadModuleData.vmDomainFile);
5042
5043             if (module == NULL)
5044             {
5045                 LOG((LF_CORDB, LL_INFO100, "Already unloaded Module - continue()ing!" ));
5046                 break;
5047             }
5048             _ASSERTE(module != NULL);
5049             INDEBUG(module->DbgAssertModuleDeleted());
5050
5051             // The appdomain we're unloading in must be the appdomain we were loaded in. Otherwise, we've got mismatched
5052             // module and appdomain pointers. Bugs 65943 & 81728.
5053             _ASSERTE(pAppDomain == module->GetAppDomain());
5054
5055             // Ensure the module gets neutered once we call continue.
5056             AddToNeuterOnContinueList(module); // throws
5057             {
5058                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5059                 pCallback1->UnloadModule(pAppDomain, module);
5060             }
5061             
5062             pAppDomain->m_modules.RemoveBase(VmPtrToCookie(pEvent->UnloadModuleData.vmDomainFile));
5063         }
5064         break;
5065
5066     case DB_IPCE_LOAD_CLASS:
5067         {
5068             CordbClass *pClass = NULL;
5069
5070             LOG((LF_CORDB, LL_INFO10000,
5071                  "RCET::HRCE: load class on thread %#x Tok:0x%08x Mod:0x%08x Asm:0x%08x AD:0x%08x\n",
5072                  dwVolatileThreadId,
5073                  pEvent->LoadClass.classMetadataToken,
5074                  VmPtrToCookie(pEvent->LoadClass.vmDomainFile),
5075                  LsPtrToCookie(pEvent->LoadClass.classDebuggerAssemblyToken),
5076                  VmPtrToCookie(pEvent->vmAppDomain)));
5077
5078             _ASSERTE (pAppDomain != NULL);
5079
5080             CordbModule* pModule = pAppDomain->LookupOrCreateModule(pEvent->LoadClass.vmDomainFile);
5081             if (pModule == NULL)
5082             {
5083                 LOG((LF_CORDB, LL_INFO100, "Load Class on not-loaded Module - continue()ing!" ));
5084                 break;
5085             }
5086             _ASSERTE(pModule != NULL);
5087
5088             BOOL fDynamic = pModule->IsDynamic();
5089
5090             // If this is a class load in a dynamic module, the metadata has become invalid.
5091             if (fDynamic)
5092             {
5093                 pModule->RefreshMetaData();
5094             }
5095
5096             hr = pModule->LookupOrCreateClass(pEvent->LoadClass.classMetadataToken, &pClass);
5097             _ASSERTE(SUCCEEDED(hr) == (pClass != NULL));
5098             IfFailThrow(hr);
5099
5100             // Prevent class load from being sent twice.
5101             // @dbgtodo - Microsoft, cordbclass: this is legacy. Can this really happen? Investigate as we dac-ize CordbClass.
5102             if (pClass->LoadEventSent())
5103             {
5104                 // Dynamic modules are dynamic at the module level -
5105                 // you can't add a new version of a class once the module
5106                 // is baked.
5107                 // EnC adds completely new classes.
5108                 // There shouldn't be any other way to send multiple
5109                 // ClassLoad events.
5110                 // Except that there are race conditions between loading
5111                 // an appdomain, and loading a class, so if we get the extra
5112                 // class load, we should ignore it.
5113                 break; //out of the switch statement
5114             }
5115             pClass->SetLoadEventSent(TRUE);
5116
5117
5118             if (pClass != NULL)
5119             {
5120                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5121                 pCallback1->LoadClass(pAppDomain, pClass);
5122             }
5123         }
5124         break;
5125
5126     case DB_IPCE_UNLOAD_CLASS:
5127         {
5128             LOG((LF_CORDB, LL_INFO10000,
5129                  "RCET::HRCE: unload class on thread %#x Tok:0x%08x Mod:0x%08x AD:0x%08x\n",
5130                  dwVolatileThreadId,
5131                  pEvent->UnloadClass.classMetadataToken,
5132                  VmPtrToCookie(pEvent->UnloadClass.vmDomainFile),
5133                  VmPtrToCookie(pEvent->vmAppDomain)));
5134
5135             // get the appdomain object
5136             _ASSERTE (pAppDomain != NULL);
5137
5138             CordbModule *pModule = pAppDomain->LookupOrCreateModule(pEvent->UnloadClass.vmDomainFile);
5139             if (pModule == NULL)
5140             {
5141                 LOG((LF_CORDB, LL_INFO100, "Unload Class on not-loaded Module - continue()ing!" ));
5142                 break;
5143             }
5144             _ASSERTE(pModule != NULL);
5145
5146             CordbClass *pClass = pModule->LookupClass(pEvent->UnloadClass.classMetadataToken);
5147
5148             if (pClass != NULL && !pClass->HasBeenUnloaded())
5149             {
5150                 pClass->SetHasBeenUnloaded(true);
5151
5152                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5153                 pCallback1->UnloadClass(pAppDomain, pClass);
5154             }
5155         }
5156         break;
5157
5158     case DB_IPCE_FIRST_LOG_MESSAGE:
5159         {
5160             _ASSERTE(pThread != NULL);
5161             _ASSERTE(pAppDomain != NULL);
5162
5163             const WCHAR * pszContent = pEvent->FirstLogMessage.szContent.GetString();
5164             {
5165                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5166                 pCallback1->LogMessage(
5167                    pAppDomain,
5168                    pThread,
5169                    pEvent->FirstLogMessage.iLevel,
5170                    const_cast<WCHAR*> (pEvent->FirstLogMessage.szCategory.GetString()),
5171                    const_cast<WCHAR*> (pszContent));
5172             }
5173         }
5174         break;
5175
5176     case DB_IPCE_LOGSWITCH_SET_MESSAGE:
5177         {
5178
5179             LOG((LF_CORDB, LL_INFO10000,
5180                 "[%x] RCET::DRCE: Log Switch Setting Message.\n",
5181                  GetCurrentThreadId()));
5182
5183             _ASSERTE(pThread != NULL);
5184
5185             const WCHAR *pstrLogSwitchName = pEvent->LogSwitchSettingMessage.szSwitchName.GetString();
5186             const WCHAR *pstrParentName = pEvent->LogSwitchSettingMessage.szParentSwitchName.GetString();
5187
5188             // from the thread object get the appdomain object
5189             _ASSERTE(pAppDomain == pThread->m_pAppDomain);
5190             _ASSERTE (pAppDomain != NULL);
5191
5192             {
5193                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5194                 pCallback1->LogSwitch(
5195                     pAppDomain,
5196                     pThread,
5197                     pEvent->LogSwitchSettingMessage.iLevel,
5198                     pEvent->LogSwitchSettingMessage.iReason,
5199                     const_cast<WCHAR*> (pstrLogSwitchName),
5200                     const_cast<WCHAR*> (pstrParentName));
5201
5202             }
5203         }
5204
5205         break;
5206     case DB_IPCE_CUSTOM_NOTIFICATION:
5207         {
5208             _ASSERTE(pThread != NULL);
5209             _ASSERTE(pAppDomain != NULL);
5210
5211
5212             // determine first whether custom notifications for this type are enabled -- if not
5213             // we just return without doing anything. 
5214             CordbClass * pNotificationClass = LookupClass(pAppDomain, 
5215                                                           pEvent->CustomNotification.vmDomainFile, 
5216                                                           pEvent->CustomNotification.classToken);
5217
5218             // if the class is NULL, that means the debugger never enabled notifications for it. Otherwise,
5219             // the CordbClass instance would already have been created when the notifications were 
5220             // enabled. 
5221             if ((pNotificationClass != NULL) && pNotificationClass->CustomNotificationsEnabled())
5222
5223             {
5224                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5225                 pCallback3->CustomNotification(pThread, pAppDomain);
5226             }
5227         }
5228
5229         break;
5230
5231     case DB_IPCE_CREATE_APP_DOMAIN:
5232         {
5233             STRESS_LOG2(LF_CORDB, LL_INFO100,
5234                  "RCET::HRCE: create appdomain on thread %#x AD:0x%08x \n",
5235                  dwVolatileThreadId,
5236                  VmPtrToCookie(pEvent->vmAppDomain));
5237
5238
5239             // Enumerate may have prepopulated the appdomain, so check if it already exists.
5240             // Either way, still send the CreateEvent. (We don't want to skip the Create event 
5241             // just because the debugger did an enumerate)
5242             // We remove AppDomains from the hash as soon as they are exited.
5243             pAppDomain.Assign(LookupOrCreateAppDomain(pEvent->AppDomainData.vmAppDomain));
5244             _ASSERTE(pAppDomain != NULL); // throws on failure
5245
5246             {   
5247                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5248                 hr = pCallback1->CreateAppDomain(this, pAppDomain);
5249             }
5250         }
5251
5252
5253         break;
5254
5255     case DB_IPCE_EXIT_APP_DOMAIN:
5256         {
5257             STRESS_LOG2(LF_CORDB, LL_INFO100, "RCET::HRCE: exit appdomain on thread %#x AD:0x%08x \n",
5258                  dwVolatileThreadId,
5259                  VmPtrToCookie(pEvent->vmAppDomain));
5260
5261             // In debug-only builds, assert that the appdomain is indeed deleted and not discoverable.
5262             INDEBUG(DbgAssertAppDomainDeleted(pEvent->vmAppDomain));
5263
5264             // If we get an ExitAD message for which we have no AppDomain, then ignore it.
5265             // This can happen if an AD gets torn down very early (before the LS AD is to the
5266             // point that it can be published).
5267             // This could also happen if we attach a debugger right before the Exit event is sent.
5268             // In this case, the debuggee is no longer publishing the appdomain.
5269             if (pAppDomain == NULL)
5270             {
5271                 break;
5272             }
5273             _ASSERTE (pAppDomain != NULL);
5274
5275             // See if this is the default AppDomain exiting.  This should only happen very late in
5276             // the shutdown cycle, and so we shouldn't do anything significant with m_pDefaultDomain==NULL.
5277             // We should try and remove m_pDefaultDomain entirely since we can't count on it always existing.
5278             if (pAppDomain == m_pDefaultAppDomain)
5279             {
5280                 m_pDefaultAppDomain = NULL;
5281             }
5282
5283             // Update any threads which were last seen in this AppDomain.  We don't 
5284             // get any notification when a thread leaves an AppDomain, so our idea
5285             // of what AppDomain the thread is in may be out of date.
5286             UpdateThreadsForAdUnload( pAppDomain );
5287             
5288             // This will still maintain weak references so we could call Continue.
5289             AddToNeuterOnContinueList(pAppDomain);
5290
5291             {
5292                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5293                 hr = pCallback1->ExitAppDomain(this, pAppDomain);
5294             }
5295
5296             // @dbgtodo appdomain: This should occur before the callback.
5297             // Even after ExitAppDomain, the outside world will want to continue calling
5298             // Continue (and thus they may need to call CordbAppDomain::GetProcess(), which Neutering
5299             // would clear). Thus we can't neuter yet.
5300
5301             // Remove this app domain. This means any attempt to lookup the AppDomain
5302             // will fail (which we do at the top of this method).  Since any threads (incorrectly) referring
5303             // to this AppDomain have been moved to the default AppDomain, no one should be 
5304             // interested in looking this AppDomain up anymore.
5305             m_appDomains.RemoveBase(VmPtrToCookie(pEvent->vmAppDomain));
5306         }
5307
5308         break;
5309
5310     case DB_IPCE_LOAD_ASSEMBLY:
5311         {
5312             LOG((LF_CORDB, LL_INFO100,
5313                 "RCET::HRCE: load assembly on thread %#x Asm:0x%08x AD:0x%08x \n",
5314                 dwVolatileThreadId,
5315                 VmPtrToCookie(pEvent->AssemblyData.vmDomainAssembly),
5316                 VmPtrToCookie(pEvent->vmAppDomain)));
5317
5318             _ASSERTE (pAppDomain != NULL);
5319
5320             // Determine if this Assembly is cached.
5321             CordbAssembly * pAssembly = pAppDomain->LookupOrCreateAssembly(pEvent->AssemblyData.vmDomainAssembly);
5322             _ASSERTE(pAssembly != NULL); // throws on error
5323
5324             // If created, or have, an Assembly, notify callback.
5325             {
5326                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5327                 hr = pCallback1->LoadAssembly(pAppDomain, pAssembly);
5328             }
5329         }
5330
5331         break;
5332
5333     case DB_IPCE_UNLOAD_ASSEMBLY:
5334         {
5335             LOG((LF_CORDB, LL_INFO100, "RCET::DRCE: unload assembly on thread %#x Asm:0x%x AD:0x%x\n",
5336                  dwVolatileThreadId,
5337                  VmPtrToCookie(pEvent->AssemblyData.vmDomainAssembly),
5338                  VmPtrToCookie(pEvent->vmAppDomain)));
5339
5340             _ASSERTE (pAppDomain != NULL);
5341
5342             CordbAssembly * pAssembly = pAppDomain->LookupOrCreateAssembly(pEvent->AssemblyData.vmDomainAssembly);
5343             
5344             if (pAssembly == NULL)
5345             {
5346                 // No assembly. This could happen if we attach right before an unload event is sent.
5347                 return;
5348             }
5349            _ASSERTE(pAssembly != NULL);
5350            INDEBUG(pAssembly->DbgAssertAssemblyDeleted());
5351
5352             // Ensure the assembly gets neutered when we call continue.
5353             AddToNeuterOnContinueList(pAssembly); // throws
5354
5355             {
5356                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5357                 hr = pCallback1->UnloadAssembly(pAppDomain, pAssembly);
5358             }
5359
5360             pAppDomain->RemoveAssemblyFromCache(pEvent->AssemblyData.vmDomainAssembly);
5361         }
5362
5363         break;
5364
5365     case DB_IPCE_FUNC_EVAL_COMPLETE:
5366         {
5367             LOG((LF_CORDB, LL_INFO1000, "RCET::DRCE: func eval complete.\n"));
5368
5369             CordbEval *pEval = NULL;
5370             {
5371                 pEval = pEvent->FuncEvalComplete.funcEvalKey.UnWrapAndRemove(this);
5372                 if (pEval  == NULL)
5373                 {
5374                     _ASSERTE(!"Bogus FuncEval handle in IPC block.");
5375                     // Bogus handle in IPC block.
5376                     break;
5377                 }
5378             }
5379             _ASSERTE(pEval != NULL);
5380
5381             _ASSERTE(pThread != NULL);
5382             _ASSERTE(pAppDomain != NULL);
5383
5384             CONSISTENCY_CHECK_MSGF(pEval->m_DbgAppDomainStarted == pAppDomain,
5385                 ("AppDomain changed from Func-Eval. Eval=%p, Started=%p, Now=%p\n",
5386                 pEval, pEval->m_DbgAppDomainStarted, (void*) pAppDomain));
5387
5388             // Hold the data about the result in the CordbEval for later.
5389             pEval->m_complete       = true;
5390             pEval->m_successful     = !!pEvent->FuncEvalComplete.successful;
5391             pEval->m_aborted        = !!pEvent->FuncEvalComplete.aborted;
5392             pEval->m_resultAddr     = pEvent->FuncEvalComplete.resultAddr;
5393             pEval->m_vmObjectHandle = pEvent->FuncEvalComplete.vmObjectHandle;
5394             pEval->m_resultType     = pEvent->FuncEvalComplete.resultType;
5395             pEval->m_resultAppDomainToken = pEvent->FuncEvalComplete.vmAppDomain;
5396
5397             CordbAppDomain *pResultAppDomain = LookupOrCreateAppDomain(pEvent->FuncEvalComplete.vmAppDomain);
5398
5399             _ASSERTE(OutstandingEvalCount() > 0);
5400             DecrementOutstandingEvalCount();
5401
5402             CONSISTENCY_CHECK_MSGF(pEval->m_DbgAppDomainStarted == pAppDomain,
5403                 ("AppDomain changed from Func-Eval. Eval=%p, Started=%p, Now=%p\n",
5404                 pEval, pEval->m_DbgAppDomainStarted, (void*) pAppDomain));
5405
5406             // If we did this func eval with this thread stopped at an excpetion, then we need to pretend as if we
5407             // really didn't continue from the exception, since, of course, we really didn't on the Left Side.
5408             if (pEval->IsEvalDuringException())
5409             {
5410                 pThread->SetExInfo(pEval->m_vmThreadOldExceptionHandle);
5411             }
5412
5413             bool fEvalCompleted = pEval->m_successful || pEval->m_aborted;
5414
5415             // If a CallFunction() is aborted, the LHS may not complete the abort
5416             // immediately and hence we cant do a SendCleanup() at that point. Also,
5417             // the debugger may (incorrectly) release the CordbEval before this
5418             // DB_IPCE_FUNC_EVAL_COMPLETE event is received. Hence, we maintain an
5419             // extra ref-count to determine when this can be done.
5420             // Note that this can cause a two-way DB_IPCE_FUNC_EVAL_CLEANUP event
5421             // to be sent. Hence, it has to be done before the Continue (see issue 102745).
5422
5423
5424             // Note that if the debugger has already (incorrectly) released the CordbEval,
5425             // pEval will be pointing to garbage and should not be used by the debugger.
5426             if (fEvalCompleted)
5427             {
5428                 PUBLIC_CALLBACK_IN_THIS_SCOPE2(this, pLockHolder, pEvent, "thread=0x%p, eval=0x%p. (Complete)", pThread, pEval);
5429                 pCallback1->EvalComplete(pResultAppDomain, pThread, pEval);
5430             }
5431             else
5432             {
5433                 PUBLIC_CALLBACK_IN_THIS_SCOPE2(this, pLockHolder, pEvent, "pThread=0x%p, eval=0x%p. (Exception)", pThread, pEval);
5434                 pCallback1->EvalException(pResultAppDomain, pThread, pEval);
5435             }
5436
5437             // This release may send an DB_IPCE_FUNC_EVAL_CLEANUP IPC event. That's ok b/c
5438             // we're still synced even if if Continue was called inside the callback.
5439             // That's because the StopContinueHolder bumped up the stopcount.
5440             // Corresponding AddRef() in CallFunction().
5441             // @todo - this is leaked if we don't get an EvalComplete event (eg, process exits with
5442             // in middle of func-eval).
5443             pEval->Release();
5444         }
5445         break;
5446
5447
5448     case DB_IPCE_NAME_CHANGE:
5449         {
5450             LOG((LF_CORDB, LL_INFO1000, "RCET::HRCE: Name Change %d  0x%p\n",
5451                  dwVolatileThreadId,
5452                  VmPtrToCookie(pEvent->NameChange.vmAppDomain)));
5453
5454             pThread = NULL;
5455             pAppDomain.Clear();
5456             if (pEvent->NameChange.eventType == THREAD_NAME_CHANGE)
5457             {
5458                 // Lookup the CordbThread that matches this runtime thread.
5459                 if (!pEvent->NameChange.vmThread.IsNull())
5460                 {
5461                     pThread = LookupOrCreateThread(pEvent->NameChange.vmThread);
5462                 }
5463             }
5464             else
5465             {
5466                 _ASSERTE (pEvent->NameChange.eventType == APP_DOMAIN_NAME_CHANGE);
5467                 pAppDomain.Assign(LookupOrCreateAppDomain(pEvent->NameChange.vmAppDomain));
5468                 if (pAppDomain)
5469                 {
5470                     pAppDomain->InvalidateName();
5471                 }
5472             }
5473
5474             if (pThread || pAppDomain)
5475             {
5476                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5477                 pCallback1->NameChange(pAppDomain, pThread);
5478             }
5479         }
5480
5481         break;
5482
5483     case DB_IPCE_UPDATE_MODULE_SYMS:
5484         {
5485             RSExtSmartPtr<IStream> pStream;
5486
5487             // Find the app domain the module lives in.
5488             _ASSERTE (pAppDomain != NULL);
5489
5490             // Find the Right Side module for this module.
5491             CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->UpdateModuleSymsData.vmDomainFile);
5492             _ASSERTE(pModule != NULL);
5493
5494             // This is a legacy event notification for updated PDBs.
5495             // Creates a new IStream object. Ownership is handed off via callback.
5496             IDacDbiInterface::SymbolFormat symFormat = pModule->GetInMemorySymbolStream(&pStream);
5497
5498             // We shouldn't get this event if there aren't PDB symbols waiting.  Specifically we don't want
5499             // to incur the cost of copying over ILDB symbols here without the debugger asking for them.
5500             // Eventually we may remove this callback as well and always rely on explicit requests.
5501             _ASSERTE(symFormat == IDacDbiInterface::kSymbolFormatPDB);
5502
5503             if (symFormat == IDacDbiInterface::kSymbolFormatPDB)
5504             {
5505                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5506                 
5507                 _ASSERTE(pStream != NULL); // Shouldn't send the event if we don't have a stream.
5508
5509                 pCallback1->UpdateModuleSymbols(pAppDomain, pModule, pStream);
5510             }
5511
5512         }
5513         break;
5514
5515     case DB_IPCE_MDA_NOTIFICATION:
5516         {
5517             RSInitHolder<CordbMDA> pMDA(new CordbMDA(this, &pEvent->MDANotification)); // throws
5518
5519             // Ctor leaves both internal + ext Ref at 0, adding to neuter list bumps int-ref up to 1.
5520             // Neutering will dump it back down to zero.
5521             this->AddToNeuterOnExitList(pMDA);
5522
5523             // We bump up and down the external ref so that even if the callback doensn't touch the refs,
5524             // our Ext-Release here will still cause a 1->0 ext-ref transition, which will get it
5525             // swept on the neuter list.
5526             RSExtSmartPtr<ICorDebugMDA> pExternalMDARef;
5527             pMDA.TransferOwnershipExternal(&pExternalMDARef);
5528             {
5529                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5530
5531                 pCallback2->MDANotification(
5532                     this, 
5533                     pThread, // may be null
5534                     pExternalMDARef);
5535
5536                 // pExternalMDARef's dtor will do an external release,
5537                 // which is very significant because it may be the one that does the 1->0 ext ref transition,
5538                 // which may mean cause the "NeuterAtWill" bit to get flipped on this CordbMDA object.
5539                 // Since this is an external release, do it in the PUBLIC_CALLBACK scope.
5540                 pExternalMDARef.Clear();
5541             }
5542
5543             break;
5544         }
5545
5546     case DB_IPCE_CONTROL_C_EVENT:
5547         {
5548             hr = S_FALSE;
5549
5550             {
5551                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5552                 hr = pCallback1->ControlCTrap((ICorDebugProcess*) this);
5553             }
5554
5555             {
5556                 RSLockHolder ch(this->GetStopGoLock());
5557
5558                 DebuggerIPCEvent eventControlCResult;
5559
5560                 InitIPCEvent(&eventControlCResult,
5561                              DB_IPCE_CONTROL_C_EVENT_RESULT,
5562                              false,
5563                              VMPTR_AppDomain::NullPtr());
5564
5565                 // Indicate whether the debugger has handled the event.
5566                 eventControlCResult.hr = hr;
5567
5568                 // Send the reply to the LS.
5569                 SendIPCEvent(&eventControlCResult, sizeof(eventControlCResult));
5570             } // release SG lock
5571
5572         }
5573         break;
5574
5575         // EnC Remap opportunity
5576         case DB_IPCE_ENC_REMAP:
5577         {
5578             LOG((LF_CORDB, LL_INFO1000, "[%x] RCET::DRCE: EnC Remap!.\n",
5579                  GetCurrentThreadId()));
5580
5581             _ASSERTE(NULL != pAppDomain);
5582
5583             CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->EnCRemap.vmDomainFile);
5584             PREFIX_ASSUME(pModule != NULL);
5585
5586             CordbFunction * pCurFunction    = NULL;
5587             CordbFunction * pResumeFunction = NULL;
5588
5589             // lookup the version of the function that we are mapping from
5590             // this is the one that is currently running
5591             pCurFunction = pModule->LookupOrCreateFunction(
5592                 pEvent->EnCRemap.funcMetadataToken, pEvent->EnCRemap.currentVersionNumber);
5593
5594             // lookup the version of the function that we are mapping to
5595             // it will always be the most recent
5596             pResumeFunction = pModule->LookupOrCreateFunction(
5597                     pEvent->EnCRemap.funcMetadataToken, pEvent->EnCRemap.resumeVersionNumber);
5598
5599             _ASSERTE(pCurFunction->GetEnCVersionNumber() < pResumeFunction->GetEnCVersionNumber());
5600
5601             RSSmartPtr<CordbFunction> pRefCurFunction(pCurFunction);
5602             RSSmartPtr<CordbFunction> pRefResumeFunction(pResumeFunction);
5603
5604             // Verify we're not about to overwrite an outstanding remap IP
5605             // This should only be set while a remap opportunity is being handled,
5606             // and cleared (by CordbThread::MarkStackFramesDirty) on Continue.
5607             // We want to be absolutely sure we don't accidentally keep a stale pointer
5608             // around because it would point to arbitrary stack space in the CLR potentially
5609             // leading to stack corruption.
5610             _ASSERTE( pThread->m_EnCRemapFunctionIP == NULL );
5611
5612             // Stash the address of the remap IP buffer.  This indicates that calling
5613             // RemapFunction is valid and provides a communications channel between the RS
5614             // and LS for the remap IL offset.
5615             pThread->m_EnCRemapFunctionIP = pEvent->EnCRemap.resumeILOffset;
5616
5617             {
5618                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5619                 pCallback2->FunctionRemapOpportunity(
5620                     pAppDomain,
5621                     pThread,
5622                     pCurFunction,
5623                     pResumeFunction,
5624                     (ULONG32)pEvent->EnCRemap.currentILOffset);
5625             }
5626
5627             // Implicit release on pCurFunction and pResumeFunction.
5628         }
5629         break;
5630
5631         // EnC Remap complete
5632         case DB_IPCE_ENC_REMAP_COMPLETE:
5633         {
5634             LOG((LF_CORDB, LL_INFO1000, "[%x] RCET::DRCE: EnC Remap Complete!.\n",
5635                  GetCurrentThreadId()));
5636
5637             _ASSERTE(NULL != pAppDomain);
5638
5639             CordbModule* pModule = pAppDomain->LookupOrCreateModule(pEvent->EnCRemap.vmDomainFile);
5640             PREFIX_ASSUME(pModule != NULL);
5641
5642             // Find the function we're remapping to, which must be the latest version
5643             CordbFunction *pRemapFunction=
5644                 pModule->LookupFunctionLatestVersion(pEvent->EnCRemapComplete.funcMetadataToken);
5645             PREFIX_ASSUME(pRemapFunction != NULL);
5646
5647             // Dispatch the FunctionRemapComplete callback
5648             RSSmartPtr<CordbFunction> pRef(pRemapFunction);
5649             {
5650                 PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
5651                 pCallback2->FunctionRemapComplete(pAppDomain, pThread, pRemapFunction);
5652             }
5653             // Implicit release on pRemapFunction via holder
5654         }
5655         break;
5656
5657         case DB_IPCE_BREAKPOINT_SET_ERROR:
5658         {
5659             LOG((LF_CORDB, LL_INFO1000, "RCET::DRCE: breakpoint set error.\n"));
5660
5661             RSSmartPtr<CordbBreakpoint> pRef;
5662
5663             _ASSERTE(pThread != NULL);
5664             _ASSERTE(pAppDomain != NULL);
5665
5666             // Find the breakpoint object on this side.
5667             CordbBreakpoint * pBreakpoint = NULL;
5668
5669
5670             if (pThread == NULL)
5671             {
5672                 // We've found cases out in the wild where we get this event on a thread we don't recognize.
5673                 // We're not sure how this happens. Add a runtime check to protect ourselves to avoid the 
5674                 // an AV. We still assert because this should not be happening.
5675                 // It likely means theres some issue where we failed to send a CreateThread notification.
5676                 STRESS_LOG1(LF_CORDB, LL_INFO1000, "BreakpointSetError on unrecognized thread. %p\n", pBreakpoint);                
5677
5678                 _ASSERTE(!"Missing thread on bp set error");
5679                 break;
5680             }   
5681             
5682             pBreakpoint = pAppDomain->m_breakpoints.GetBase(LsPtrToCookie(pEvent->BreakpointSetErrorData.breakpointToken));
5683
5684             if (pBreakpoint != NULL)
5685             {
5686                 ICorDebugBreakpoint * pIBreakpoint = CordbBreakpointToInterface(pBreakpoint);
5687                 _ASSERTE(pIBreakpoint != NULL);            
5688             {
5689                     PUBLIC_CALLBACK_IN_THIS_SCOPE2(this, pLockHolder, pEvent, "thread=0x%p, bp=0x%p", pThread, pBreakpoint);
5690                     pCallback1->BreakpointSetError(pAppDomain, pThread, pIBreakpoint, 0);
5691             }
5692             }
5693             // Implicit release on pRef.
5694         }
5695         break;
5696
5697
5698     case DB_IPCE_EXCEPTION_CALLBACK2:
5699         {
5700             STRESS_LOG4(LF_CORDB, LL_INFO100,
5701                 "RCET::DRCE: Exception2 0x%p 0x%X 0x%X 0x%X\n",
5702                  pEvent->ExceptionCallback2.framePointer.GetSPValue(),
5703                  pEvent->ExceptionCallback2.nOffset,
5704                  pEvent->ExceptionCallback2.eventType,
5705                  pEvent->ExceptionCallback2.dwFlags
5706                  );
5707
5708             if (pThread == NULL)
5709             {
5710                 // We've got an exception on a thread we don't know about.  This could be a thread that 
5711                 // has never run any managed code, so let's just ignore the exception.  We should have 
5712                 // already sent a log message about this situation for the EXCEPTION callback above.
5713                 _ASSERTE( pEvent->ExceptionCallback2.eventType == DEBUG_EXCEPTION_UNHANDLED );
5714                 break;
5715             }
5716
5717             pThread->SetExInfo(pEvent->ExceptionCallback2.vmExceptionHandle);
5718
5719             //
5720             // Send all the information back to the debugger.
5721             //
5722             RSSmartPtr<CordbFrame> pFrame;
5723
5724             FramePointer fp = pEvent->ExceptionCallback2.framePointer;
5725             if (fp != LEAF_MOST_FRAME)
5726             {
5727                 // The interface forces us to to pass a FramePointer via an ICorDebugFrame.
5728                 // However, we can't get a real ICDFrame without a stackwalk, and we don't
5729                 // want to do a stackwalk now. so pass a netuered proxy frame. The shim 
5730                 // can map this to a real frame.
5731                 // See comments at CordbPlaceHolderFrame class for details.
5732                 pFrame.Assign(new CordbPlaceholderFrame(this, fp));
5733             }
5734            
5735             CorDebugExceptionCallbackType type = pEvent->ExceptionCallback2.eventType;
5736             {
5737                 PUBLIC_CALLBACK_IN_THIS_SCOPE3(this, pLockHolder, pEvent, "pThread=0x%p, frame=%p, type=%d", pThread, (ICorDebugFrame*) pFrame, type);
5738                 hr = pCallback2->Exception(
5739                     pThread->m_pAppDomain,
5740                     pThread,
5741                     pFrame,
5742                     (ULONG32)(pEvent->ExceptionCallback2.nOffset),
5743                     type,
5744                     pEvent->ExceptionCallback2.dwFlags);
5745             }
5746         }
5747         break;
5748
5749     case DB_IPCE_EXCEPTION_UNWIND:
5750         {
5751             STRESS_LOG2(LF_CORDB, LL_INFO100,
5752                 "RCET::DRCE: Exception Unwind 0x%X 0x%X\n",
5753                  pEvent->ExceptionCallback2.eventType,
5754                  pEvent->ExceptionCallback2.dwFlags
5755                  );
5756
5757             if (pThread == NULL)
5758             {
5759                 // We've got an exception on a thread we don't know about.  This probably should never
5760                 // happen (if it's unwinding, then we expect a managed frame on the stack, and so we should
5761                 // know about the thread), but if it does fall back to ignoring the exception.
5762                 _ASSERTE( !"Got unwind event for unknown exception" );
5763                 break;
5764             }
5765
5766             //
5767             // Send all the information back to the debugger.
5768             //
5769             {
5770                 PUBLIC_CALLBACK_IN_THIS_SCOPE1(this, pLockHolder, pEvent, "pThread=0x%p", pThread);
5771                 hr = pCallback2->ExceptionUnwind(
5772                     pThread->m_pAppDomain,
5773                     pThread,
5774                     pEvent->ExceptionUnwind.eventType,
5775                     pEvent->ExceptionUnwind.dwFlags);
5776             }
5777         }
5778         break;
5779
5780
5781     case DB_IPCE_INTERCEPT_EXCEPTION_COMPLETE:
5782         {
5783             STRESS_LOG0(LF_CORDB, LL_INFO100, "RCET::DRCE: Exception Interception Complete.\n");
5784
5785             if (pThread == NULL)
5786             {
5787                 // We've got an exception on a thread we don't know about.  This probably should never
5788                 // happen (if it's unwinding, then we expect a managed frame on the stack, and so we should
5789                 // know about the thread), but if it does fall back to ignoring the exception.
5790                 _ASSERTE( !"Got complete event for unknown exception" );
5791                 break;
5792             }
5793
5794             //
5795             // Tell the debugger that the exception has been intercepted.  This is similar to the 
5796             // notification we give when we start unwinding for a non-intercepted exception, except that the
5797             // interception has been completed at this point, which means that we are conceptually at the end
5798             // of the second pass.
5799             //
5800             {
5801                 PUBLIC_CALLBACK_IN_THIS_SCOPE1(this, pLockHolder, pEvent, "pThread=0x%p", pThread);
5802                 hr = pCallback2->ExceptionUnwind(
5803                     pThread->m_pAppDomain, 
5804                     pThread, 
5805                     DEBUG_EXCEPTION_INTERCEPTED, 
5806                     0);
5807             }
5808         }
5809         break;
5810 #ifdef TEST_DATA_CONSISTENCY
5811     case DB_IPCE_TEST_CRST:
5812         {
5813             EX_TRY
5814             {
5815                 // the left side has signaled that we should test whether pEvent->TestCrstData.vmCrst is held
5816                 GetDAC()->TestCrst(pEvent->TestCrstData.vmCrst);
5817             }
5818             EX_CATCH_HRESULT(hr);
5819
5820             if (pEvent->TestCrstData.fOkToTake)
5821             {
5822                 _ASSERTE(hr == S_OK);
5823                 if (hr != S_OK)
5824                 {
5825                     // we want to catch this in retail builds too
5826                     ThrowHR(E_FAIL);
5827                 }
5828             }
5829             else // the lock was already held
5830             {
5831                 // see if we threw because the lock was held 
5832                 _ASSERTE(hr == CORDBG_E_PROCESS_NOT_SYNCHRONIZED);
5833                 if (hr != CORDBG_E_PROCESS_NOT_SYNCHRONIZED)
5834                 {
5835                     // we want to catch this in retail builds too
5836                     ThrowHR(E_FAIL);
5837                 }
5838             }
5839
5840         }
5841         break;
5842         
5843     case DB_IPCE_TEST_RWLOCK:
5844         {
5845             EX_TRY
5846             {
5847                 // the left side has signaled that we should test whether pEvent->TestRWLockData.vmRWLock is held
5848                 GetDAC()->TestRWLock(pEvent->TestRWLockData.vmRWLock);
5849             }
5850             EX_CATCH_HRESULT(hr);
5851
5852             if (pEvent->TestRWLockData.fOkToTake)
5853             {
5854                 _ASSERTE(hr == S_OK);
5855                 if (hr != S_OK)
5856                 {
5857                     // we want to catch this in retail builds too
5858                     ThrowHR(E_FAIL);
5859                 }
5860             }
5861             else // the lock was already held
5862             {
5863                 // see if we threw because the lock was held 
5864                 _ASSERTE(hr == CORDBG_E_PROCESS_NOT_SYNCHRONIZED);
5865                 if (hr != CORDBG_E_PROCESS_NOT_SYNCHRONIZED)
5866                 {
5867                     // we want to catch this in retail builds too
5868                     ThrowHR(E_FAIL);
5869                 }
5870             }
5871         }
5872         break;
5873 #endif
5874
5875     default:
5876         _ASSERTE(!"Unknown event");
5877         LOG((LF_CORDB, LL_INFO1000,
5878              "[%x] RCET::HRCE: Unknown event: 0x%08x\n",
5879              GetCurrentThreadId(), pEvent->type));
5880     }
5881
5882
5883     FinishEventDispatch();
5884 }
5885 #ifdef _PREFAST_
5886 #pragma warning(pop)
5887 #endif
5888
5889 //---------------------------------------------------------------------------------------
5890 // Callback for prepopulating threads.
5891 // 
5892 // Arugments:
5893 //    vmThread - thread as part of the eunmeration.
5894 //    pUserData - data supplied with callback. It's a CordbProcess* object.
5895 //
5896
5897 // static
5898 void CordbProcess::ThreadEnumerationCallback(VMPTR_Thread vmThread, void * pUserData)
5899 {
5900     CordbProcess * pThis = reinterpret_cast<CordbProcess *> (pUserData);
5901     INTERNAL_DAC_CALLBACK(pThis);
5902
5903     STRESS_LOG0(LF_CORDB, LL_INFO1000, "ThreadEnumerationCallback()\n");
5904
5905     // Do lookup / lazy-create.
5906     pThis->LookupOrCreateThread(vmThread);
5907 }
5908
5909 //---------------------------------------------------------------------------------------
5910 // Fully build up the CordbThread cache to match VM state.
5911 void CordbProcess::PrepopulateThreadsOrThrow()
5912 {
5913     RSLockHolder lockHolder(GetProcessLock());
5914     if (IsDacInitialized())
5915     {
5916         STRESS_LOG0(LF_CORDB, LL_INFO1000, "PrepopulateThreadsOrThrow()\n");
5917         GetDAC()->EnumerateThreads(ThreadEnumerationCallback, this);
5918     }
5919 }
5920
5921 //---------------------------------------------------------------------------------------
5922 // Create a Thread enumerator
5923 // 
5924 // Arguments:
5925 //     pOwnerObj - object (a CordbProcess or CordbThread) that will own the enumerator.
5926 //     pOwnerList - the neuter list that the enumerator will live on
5927 //     pHolder - an outparameter for the enumerator to be initialized.
5928 //
5929 void CordbProcess::BuildThreadEnum(CordbBase * pOwnerObj, NeuterList * pOwnerList, RSInitHolder<CordbHashTableEnum> * pHolder)
5930 {
5931     CordbHashTableEnum::BuildOrThrow(
5932         pOwnerObj, 
5933         pOwnerList, 
5934         &m_userThreads,
5935         IID_ICorDebugThreadEnum,
5936         pHolder);
5937 }
5938
5939 // Public implementation of ICorDebugProcess::EnumerateThreads
5940 HRESULT CordbProcess::EnumerateThreads(ICorDebugThreadEnum **ppThreads)
5941 {
5942     HRESULT hr = S_OK;
5943     PUBLIC_API_BEGIN(this);
5944     {
5945         if (m_detached)
5946         {
5947             // #Detach_Check:
5948             // 
5949             // FUTURE: Consider adding this IF block to the PUBLIC_API macros so that
5950             // typical public APIs fail quickly if we're trying to do a detach.  For
5951             // now, I'm hand-adding this check only to the few problematic APIs that get
5952             // called while queuing the fake attach events.  In these cases, it is not
5953             // enough to check if CordbProcess::IsNeutered(), as the detaching thread
5954             // may have begun the detaching and neutering process, but not be
5955             // finished--in which case m_detached is true, but
5956             // CordbProcess::IsNeutered() is still false.
5957             ThrowHR(CORDBG_E_PROCESS_DETACHED);
5958         }
5959
5960         ValidateOrThrow(ppThreads);
5961
5962         RSInitHolder<CordbHashTableEnum> pEnum;
5963         InternalEnumerateThreads(pEnum.GetAddr());
5964
5965         pEnum.TransferOwnershipExternal(ppThreads);
5966     }
5967     PUBLIC_API_END(hr);
5968     return hr;
5969 }
5970
5971 // Internal implementation of EnumerateThreads
5972 VOID CordbProcess::InternalEnumerateThreads(RSInitHolder<CordbHashTableEnum> *ppThreads)
5973 {
5974     INTERNAL_API_ENTRY(this);
5975     // Needs to prepopulate
5976     PrepopulateThreadsOrThrow();
5977     BuildThreadEnum(this, this->GetContinueNeuterList(), ppThreads);
5978 }
5979
5980 // Implementation of ICorDebugProcess::GetThread
5981 HRESULT CordbProcess::GetThread(DWORD dwThreadId, ICorDebugThread **ppThread)
5982 {
5983     PUBLIC_API_ENTRY(this);
5984     VALIDATE_POINTER_TO_OBJECT(ppThread, ICorDebugThread **);
5985
5986     // No good pre-existing ATT_* contract for this.
5987     // Because for legacy, we have to allow this on the win32 event thread.
5988     *ppThread = NULL;
5989
5990     HRESULT hr = S_OK;
5991     EX_TRY
5992     {
5993         RSLockHolder lockHolder(GetProcessLock());
5994         if (m_detached)
5995         {
5996             // See code:CordbProcess::EnumerateThreads#Detach_Check
5997             ThrowHR(CORDBG_E_PROCESS_DETACHED);
5998         }
5999         CordbThread * pThread = TryLookupOrCreateThreadByVolatileOSId(dwThreadId); 
6000         if (pThread == NULL)
6001         {
6002             // This is a common case because we may be looking up an unmanaged thread.
6003             hr = E_INVALIDARG;
6004         }
6005         else
6006         {
6007             *ppThread = static_cast<ICorDebugThread*> (pThread);
6008             pThread->ExternalAddRef();
6009         }
6010     }
6011     EX_CATCH_HRESULT(hr);
6012
6013     LOG((LF_CORDB, LL_INFO10000, "CP::GT returns id=0x%x hr=0x%x ppThread=0x%p",
6014              dwThreadId, hr, *ppThread));
6015     return hr;
6016 }
6017
6018 HRESULT CordbProcess::ThreadForFiberCookie(DWORD fiberCookie,
6019                                            ICorDebugThread **ppThread)
6020 {
6021     return E_NOTIMPL;
6022 }
6023
6024 HRESULT CordbProcess::GetHelperThreadID(DWORD *pThreadID)
6025 {
6026     PUBLIC_API_ENTRY(this);
6027     FAIL_IF_NEUTERED(this);
6028
6029     _ASSERTE(m_pShim != NULL);
6030     if (pThreadID == NULL)
6031     {
6032         return (E_INVALIDARG);
6033     }
6034
6035     HRESULT hr = S_OK;
6036     // Return the ID of the current helper thread. There may be no thread in the process, or there may be a true helper
6037     // thread.
6038     if ((m_helperThreadId != 0) && !m_helperThreadDead)
6039     {
6040         *pThreadID = m_helperThreadId;
6041     }
6042     else if ((GetDCB() != NULL) && (GetDCB()->m_helperThreadId != 0))
6043     {
6044         EX_TRY
6045         {
6046             // be sure we have the latest information
6047             UpdateRightSideDCB();
6048             *pThreadID = GetDCB()->m_helperThreadId;
6049         }
6050         EX_CATCH_HRESULT(hr);
6051
6052     }
6053     else
6054     {
6055         *pThreadID = 0;
6056     }
6057
6058     return hr;
6059 }
6060
6061 //---------------------------------------------------------------------------------------
6062 //
6063 // Sends IPC event to set all the managed threads, except for the one given, to the given state
6064 //
6065 // Arguments:
6066 //     state - The state to set the threads to.
6067 //     pExceptThread - The thread to not set.  This is usually the thread that is currently
6068 //         sending an IPC event to the RS, and should be excluded.
6069 //
6070 // Return Value:
6071 //     Typical HRESULT symantics, nothing abnormal.
6072 //
6073 HRESULT CordbProcess::SetAllThreadsDebugState(CorDebugThreadState state,
6074                                               ICorDebugThread * pExceptThread)
6075 {
6076     PUBLIC_REENTRANT_API_ENTRY(this);
6077     FAIL_IF_NEUTERED(this);
6078     VALIDATE_POINTER_TO_OBJECT_OR_NULL(pExceptThread, ICorDebugThread *);
6079     ATT_REQUIRE_STOPPED_MAY_FAIL(this);
6080
6081     if (GetShim() == NULL)
6082     {
6083         return E_NOTIMPL;
6084     }
6085     CordbThread * pCordbExceptThread = static_cast<CordbThread *> (pExceptThread);
6086
6087     LOG((LF_CORDB, LL_INFO1000, "CP::SATDS: except thread=0x%08x 0x%x\n", 
6088          pExceptThread, 
6089          (pCordbExceptThread != NULL) ? pCordbExceptThread->m_id : 0));
6090
6091     // Send one event to the Left Side to twiddle each thread's state.
6092     DebuggerIPCEvent event;
6093     
6094     InitIPCEvent(&event, DB_IPCE_SET_ALL_DEBUG_STATE, true, VMPTR_AppDomain::NullPtr());
6095     
6096     event.SetAllDebugState.vmThreadToken = ((pCordbExceptThread != NULL) ? 
6097                                             pCordbExceptThread->m_vmThreadToken : VMPTR_Thread::NullPtr());
6098     
6099     event.SetAllDebugState.debugState = state;
6100
6101     HRESULT hr = SendIPCEvent(&event, sizeof(DebuggerIPCEvent));
6102     
6103     hr = WORST_HR(hr, event.hr);
6104
6105     // If that worked, then loop over all the threads on this side and set their states.
6106     if (SUCCEEDED(hr))
6107     {
6108         RSLockHolder lockHolder(GetProcessLock());
6109         HASHFIND hashFind;
6110         CordbThread * pThread;
6111
6112         // We don't need to prepopulate here (to collect LS state) because we're just updating RS state.
6113         for (pThread = m_userThreads.FindFirst(&hashFind); 
6114               pThread != NULL; 
6115               pThread = m_userThreads.FindNext(&hashFind))
6116         {
6117             if (pThread != pCordbExceptThread)
6118             {
6119                 pThread->m_debugState = state;
6120             }
6121         }
6122     }
6123
6124     return hr;
6125 }
6126
6127
6128 HRESULT CordbProcess::EnumerateObjects(ICorDebugObjectEnum **ppObjects)
6129 {
6130     /* !!! */
6131     PUBLIC_API_ENTRY(this);
6132     FAIL_IF_NEUTERED(this);
6133     VALIDATE_POINTER_TO_OBJECT(ppObjects, ICorDebugObjectEnum **);
6134
6135     return E_NOTIMPL;
6136 }
6137
6138 //---------------------------------------------------------------------------------------
6139 //
6140 // Determines if the target address is a "CLR transition stub". 
6141 //
6142 // Arguments:
6143 //     address - The address of an instruction to check in the target address space.
6144 //     pfTransitionStub - Space to store the result, TRUE if the address belongs to a
6145 //         transition stub, FALSE if not.  Only valid if this method returns a success code.
6146 //
6147 // Return Value:
6148 //     Typical HRESULT symantics, nothing abnormal.
6149 //
6150 //---------------------------------------------------------------------------------------
6151 HRESULT CordbProcess::IsTransitionStub(CORDB_ADDRESS address, BOOL *pfTransitionStub)
6152 {
6153     PUBLIC_API_ENTRY(this);
6154     FAIL_IF_NEUTERED(this);
6155     VALIDATE_POINTER_TO_OBJECT(pfTransitionStub, BOOL *);
6156
6157     // Default to FALSE
6158     *pfTransitionStub = FALSE;
6159
6160     if (this->m_helperThreadDead)
6161     {
6162         return S_OK;
6163     }
6164
6165     // If we're not initialized, then it can't be a stub...
6166     if (!m_initialized)
6167     {
6168         return S_OK;
6169     }
6170
6171     ATT_REQUIRE_STOPPED_MAY_FAIL(this);
6172
6173     HRESULT hr = S_OK;
6174     EX_TRY
6175     {
6176         DebuggerIPCEvent eventData;
6177
6178         InitIPCEvent(&eventData, DB_IPCE_IS_TRANSITION_STUB, true, VMPTR_AppDomain::NullPtr());
6179
6180         eventData.IsTransitionStub.address = CORDB_ADDRESS_TO_PTR(address);
6181
6182         hr = SendIPCEvent(&eventData, sizeof(eventData));
6183         hr = WORST_HR(hr, eventData.hr);
6184         IfFailThrow(hr);
6185
6186         _ASSERTE(eventData.type == DB_IPCE_IS_TRANSITION_STUB_RESULT);
6187
6188         *pfTransitionStub = eventData.IsTransitionStubResult.isStub;
6189         LOG((LF_CORDB, LL_INFO1000, "CP::ITS: addr=0x%p result=%d\n", address, *pfTransitionStub));
6190         // @todo - beware that IsTransitionStub has a very important sideeffect - it synchronizes the runtime!
6191         // This for example covers an OS bug where SetThreadContext may silently fail if we're not synchronized.
6192         // (See IMDArocess::SetThreadContext for details on that bug).
6193         // If we ever stop using IPC events here and only use DAC; we need to be aware of that.
6194
6195         // Check against DAC primitives
6196         {
6197             BOOL fIsStub2 = GetDAC()->IsTransitionStub(address);            
6198             (void)fIsStub2; //prevent "unused variable" error from GCC
6199             CONSISTENCY_CHECK_MSGF(*pfTransitionStub == fIsStub2, ("IsStub2 failed, DAC2:%d, IPC:%d, addr:0x%p", (int) fIsStub2, (int) *pfTransitionStub, CORDB_ADDRESS_TO_PTR(address)));
6200
6201         }
6202     }
6203     EX_CATCH_HRESULT(hr);
6204     if(FAILED(hr))
6205     {
6206         LOG((LF_CORDB, LL_INFO1000, "CP::ITS: FAILED hr=0x%x\n", hr));
6207     }
6208     return hr;
6209 }
6210
6211
6212 HRESULT CordbProcess::SetStopState(DWORD threadID, CorDebugThreadState state)
6213 {
6214     PUBLIC_API_ENTRY(this);
6215     FAIL_IF_NEUTERED(this);
6216     return E_NOTIMPL;
6217 }
6218
6219 HRESULT CordbProcess::IsOSSuspended(DWORD threadID, BOOL *pbSuspended)
6220 {
6221     PUBLIC_API_ENTRY(this);
6222     // Gotta have a place for the result!
6223     if (!pbSuspended)
6224         return E_INVALIDARG;
6225
6226     FAIL_IF_NEUTERED(this);
6227
6228 #ifdef FEATURE_INTEROP_DEBUGGING
6229     RSLockHolder lockHolder(GetProcessLock());
6230
6231     // Have we seen this thread?
6232     CordbUnmanagedThread *ut = GetUnmanagedThread(threadID);
6233
6234     // If we have, and if we've suspended it, then say so.
6235     if (ut && ut->IsSuspended())
6236     {
6237         *pbSuspended = TRUE;
6238     }
6239     else
6240     {
6241         *pbSuspended = FALSE;
6242     }
6243 #else
6244     // Not interop-debugging, we never OS suspend.
6245     *pbSuspended = FALSE;
6246 #endif
6247     return S_OK;
6248 }
6249
6250 //
6251 // This routine reads a thread context from the process being debugged, taking into account the fact that the context
6252 // record may be a different size than the one we compiled with. On systems < NT5, then OS doesn't usually allocate
6253 // space for the extended registers. However, the CONTEXT struct that we compile with does have this space.
6254 //
6255 HRESULT CordbProcess::SafeReadThreadContext(LSPTR_CONTEXT pContext, DT_CONTEXT * pCtx)
6256 {
6257     HRESULT hr = S_OK;
6258
6259     INTERNAL_API_ENTRY(this);
6260     FAIL_IF_NEUTERED(this);
6261
6262     EX_TRY
6263     {
6264
6265         void *pRemoteContext = pContext.UnsafeGet();
6266         TargetBuffer tbFull(pRemoteContext, sizeof(DT_CONTEXT));
6267
6268         // The context may have 2 parts:
6269         // 1. Base register, which are always present.
6270         // 2. Optional extended registers, which are only present if CONTEXT_EXTENDED_REGISTERS is set
6271         //    in the flags.
6272
6273         // At a minimum we have room for a whole context up to the extended registers.
6274     #if defined(DT_CONTEXT_EXTENDED_REGISTERS)
6275         ULONG32 minContextSize = offsetof(DT_CONTEXT, ExtendedRegisters);    
6276     #else
6277         ULONG32 minContextSize = sizeof(DT_CONTEXT);
6278     #endif
6279
6280         // Read the minimum part.
6281         TargetBuffer tbMin = tbFull.SubBuffer(0, minContextSize);
6282         SafeReadBuffer(tbMin, (BYTE*) pCtx);
6283         
6284     #if defined(DT_CONTEXT_EXTENDED_REGISTERS)
6285         void *pCurExtReg = (void*)((UINT_PTR)pCtx + minContextSize);
6286         TargetBuffer tbExtended = tbFull.SubBuffer(minContextSize);
6287
6288         // Now, read the extended registers if the context contains them. If the context does not have extended registers,
6289         // just set them to zero.
6290         if (SUCCEEDED(hr) && (pCtx->ContextFlags & CONTEXT_EXTENDED_REGISTERS) == CONTEXT_EXTENDED_REGISTERS)
6291         {
6292             SafeReadBuffer(tbExtended, (BYTE*) pCurExtReg);
6293         }
6294         else
6295         {
6296             memset(pCurExtReg, 0, tbExtended.cbSize);
6297         }
6298     #endif
6299
6300     }
6301     EX_CATCH_HRESULT(hr);
6302     return hr;
6303 }
6304
6305 //
6306 // This routine writes a thread context to the process being debugged, taking into account the fact that the context
6307 // record may be a different size than the one we compiled with. On systems < NT5, then OS doesn't usually allocate
6308 // space for the extended registers. However, the CONTEXT struct that we compile with does have this space.
6309 //
6310 HRESULT CordbProcess::SafeWriteThreadContext(LSPTR_CONTEXT pContext, const DT_CONTEXT * pCtx)
6311 {
6312     INTERNAL_API_ENTRY(this);
6313     FAIL_IF_NEUTERED(this);
6314
6315     HRESULT hr = S_OK;
6316     DWORD sizeToWrite = sizeof(DT_CONTEXT);
6317
6318     BYTE * pRemoteContext = (BYTE*) pContext.UnsafeGet();
6319     BYTE * pCtxSource = (BYTE*) pCtx;
6320
6321
6322 #if defined(DT_CONTEXT_EXTENDED_REGISTERS)
6323     // If our context has extended registers, then write the whole thing. Otherwise, just write the minimum part.
6324     if ((pCtx->ContextFlags & DT_CONTEXT_EXTENDED_REGISTERS) != DT_CONTEXT_EXTENDED_REGISTERS)
6325     {
6326         sizeToWrite = offsetof(DT_CONTEXT, ExtendedRegisters);
6327     }
6328 #endif
6329
6330 // 64 bit windows puts space for the first 6 stack parameters in the CONTEXT structure so that 
6331 // kernel to usermode transitions don't have to allocate a CONTEXT and do a seperate sub rsp
6332 // to allocate stack spill space for the arguments. This means that writing to P1Home - P6Home
6333 // will overwrite the arguments of some function higher on the stack, very bad. Conceptually you
6334 // can think of these members as not being part of the context, ie they don't represent something
6335 // which gets saved or restored on context switches. They are just space we shouldn't overwrite.
6336 // See issue 630276 for more details.
6337 #if defined DBG_TARGET_AMD64
6338     pRemoteContext += offsetof(CONTEXT, ContextFlags); // immediately follows the 6 parameters P1-P6
6339     pCtxSource += offsetof(CONTEXT, ContextFlags);
6340     sizeToWrite -= offsetof(CONTEXT, ContextFlags);
6341 #endif
6342
6343     EX_TRY
6344     {
6345         // Write the context.
6346         TargetBuffer tb(pRemoteContext, sizeToWrite);
6347         SafeWriteBuffer(tb, (const BYTE*) pCtxSource);
6348     }
6349     EX_CATCH_HRESULT(hr);
6350     
6351     return hr;
6352 }
6353
6354
6355 HRESULT CordbProcess::GetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE context[])
6356 {
6357     PUBLIC_REENTRANT_API_ENTRY(this);
6358     FAIL_IF_NEUTERED(this);
6359     FAIL_IF_MANAGED_ONLY(this);
6360
6361     DT_CONTEXT * pContext;
6362     LOG((LF_CORDB, LL_INFO10000, "CP::GTC: thread=0x%x\n", threadID));
6363
6364     RSLockHolder lockHolder(GetProcessLock());
6365
6366     if (contextSize != sizeof(DT_CONTEXT))
6367     {
6368         LOG((LF_CORDB, LL_INFO10000, "CP::GTC: thread=0x%x, context size is invalid.\n", threadID));
6369         return E_INVALIDARG;
6370     }
6371
6372     pContext = reinterpret_cast<DT_CONTEXT *>(context);
6373
6374     VALIDATE_POINTER_TO_OBJECT_ARRAY(context, BYTE, contextSize, true, true);
6375
6376 #if !defined(FEATURE_INTEROP_DEBUGGING)
6377     return E_NOTIMPL;
6378 #else
6379     // Find the unmanaged thread
6380     CordbUnmanagedThread *ut = GetUnmanagedThread(threadID);
6381
6382     if (ut == NULL)
6383     {
6384         LOG((LF_CORDB, LL_INFO10000, "CP::GTC: thread=0x%x, thread id is invalid.\n", threadID));
6385
6386         return E_INVALIDARG;
6387     }
6388
6389     return ut->GetThreadContext((DT_CONTEXT*)context);
6390 #endif // FEATURE_INTEROP_DEBUGGING
6391 }
6392
6393 // Public implementation of ICorDebugProcess::SetThreadContext.
6394 // @dbgtodo interop-debugging: this should go away in V3. Use the data-target instead. This is 
6395 // interop-debugging aware (and cooperates with hijacks)
6396 HRESULT CordbProcess::SetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE context[])
6397 {
6398     PUBLIC_REENTRANT_API_ENTRY(this);
6399     FAIL_IF_MANAGED_ONLY(this);
6400
6401 #if !defined(FEATURE_INTEROP_DEBUGGING)
6402     return E_NOTIMPL;
6403 #else
6404     HRESULT hr = S_OK;
6405
6406     RSLockHolder lockHolder(GetProcessLock());
6407
6408     CordbUnmanagedThread *ut = NULL;
6409
6410     if (contextSize != sizeof(DT_CONTEXT))
6411     {
6412         LOG((LF_CORDB, LL_INFO10000, "CP::STC: thread=0x%x, context size is invalid.\n", threadID));
6413         hr = E_INVALIDARG;
6414         goto Label_Done;
6415     }
6416
6417     // @todo -  could we look at the context flags and return E_INVALIDARG if they're bad?
6418     FAIL_IF_NEUTERED(this);
6419     VALIDATE_POINTER_TO_OBJECT_ARRAY(context, BYTE, contextSize, true, true);
6420
6421     // Find the unmanaged thread
6422     ut = GetUnmanagedThread(threadID);
6423
6424     if (ut == NULL)
6425     {
6426         LOG((LF_CORDB, LL_INFO10000, "CP::STC: thread=0x%x, thread is invalid.\n", threadID));
6427         hr = E_INVALIDARG;
6428         goto Label_Done;
6429     }
6430
6431     hr = ut->SetThreadContext((DT_CONTEXT*)context);
6432
6433
6434     // Update the register set for the leaf-unmanaged chain so that it's consistent w/ the context.
6435     // We may not necessarily be synchronized, and so these frames may be stale. Even so, no harm done.
6436     if (SUCCEEDED(hr))
6437     {
6438         // @dbgtodo stackwalk: this should all disappear with V3 stackwalker and getting rid of SetThreadContext.
6439         EX_TRY
6440         {
6441             // Find the managed thread.  Returns NULL if thread is not managed.
6442             // If we don't have a thread prveiously cached, then there's no state to update.
6443             CordbThread * pThread = TryLookupThreadByVolatileOSId(threadID); 
6444             
6445             if (pThread != NULL)
6446             {
6447                 // In V2, we used to update the CONTEXT of the leaf chain if the chain is an unmanaged chain.
6448                 // In Arrowhead, we just force a cleanup of the stackwalk cache.  This is a more correct
6449                 // thing to do anyway, since the CONTEXT being set could be anything.
6450                 pThread->CleanupStack();
6451             }
6452         }
6453         EX_CATCH_HRESULT(hr);
6454     }
6455
6456 Label_Done:
6457     return ErrWrapper(hr);
6458
6459 #endif // FEATURE_INTEROP_DEBUGGING
6460 }
6461
6462
6463 // @dbgtodo  ICDProcess - When we DACize this function, we should use code:DacReplacePatches
6464 HRESULT CordbProcess::ReadMemory(CORDB_ADDRESS address,
6465                                  DWORD size,
6466                                  BYTE buffer[],
6467                                  SIZE_T *read)
6468 {
6469     PUBLIC_REENTRANT_API_ENTRY(this);
6470     FAIL_IF_NEUTERED(this);
6471
6472     // A read of 0 bytes is okay.
6473     if (size == 0)
6474         return S_OK;
6475
6476     VALIDATE_POINTER_TO_OBJECT_ARRAY(buffer, BYTE, size, true, true);
6477     VALIDATE_POINTER_TO_OBJECT(buffer, SIZE_T *);
6478
6479     if (address == NULL)
6480         return E_INVALIDARG;
6481
6482     // If no read parameter is supplied, we ignore it. This matches the semantics of kernel32!ReadProcessMemory.
6483     SIZE_T dummyRead;
6484     if (read == NULL)
6485     {
6486         read = &dummyRead;
6487     }
6488     *read = 0;
6489
6490     HRESULT hr = S_OK;
6491
6492     CORDBRequireProcessStateOK(this);
6493
6494     // Grab the memory we want to read
6495     // Note that this will return success on a partial read
6496     ULONG32 cbRead;
6497     hr = GetDataTarget()->ReadVirtual(address, buffer, size, &cbRead);
6498     if (FAILED(hr))
6499     {
6500         hr = CORDBG_E_READVIRTUAL_FAILURE;
6501         goto LExit;
6502     }
6503
6504     // Read at least one byte
6505     *read = (SIZE_T) cbRead;
6506
6507     // There seem to be strange cases where ReadProcessMemory will return a seemingly negative number into *read, which
6508     // is an unsigned value. So we check the sanity of *read by ensuring that its no bigger than the size we tried to
6509     // read.
6510     if ((*read > 0) && (*read <= size))
6511     {
6512         LOG((LF_CORDB, LL_INFO100000, "CP::RM: read %d bytes from 0x%08x, first byte is 0x%x\n",
6513              *read, (DWORD)address, buffer[0]));
6514
6515         if (m_initialized)
6516         {
6517             RSLockHolder ch(&this->m_processMutex);
6518
6519             // If m_pPatchTable is NULL, then it's been cleaned out b/c of a Continue for the left side.  Get the table
6520             // again. Only do this, of course, if the managed state of the process is initialized.
6521             if (m_pPatchTable == NULL)
6522             {
6523                 hr = RefreshPatchTable(address, *read, buffer);
6524             }
6525             else
6526             {
6527                 // The previously fetched table is still good, so run through it & see if any patches are applicable
6528                 hr = AdjustBuffer(address, *read, buffer, NULL, AB_READ);
6529             }
6530         }
6531     }
6532
6533 LExit:
6534     if (FAILED(hr))
6535     {
6536         RSLockHolder ch(&this->m_processMutex);
6537         ClearPatchTable();
6538     }
6539     else if (*read < size)
6540     {
6541         // Unlike the DT api, our API is supposed to return an error on partial read
6542         hr = HRESULT_FROM_WIN32(ERROR_PARTIAL_COPY);
6543     }
6544     return hr;
6545 }
6546
6547 // Update patches & buffer to make the left-side's usage of patches transparent
6548 // to our client.  Behavior depends on AB_MODE:
6549 // AB_READ:
6550 // - use the RS patch table structure to replace patch opcodes in buffer.
6551 // AB_WRITE:
6552 // - update the RS patch table structure w/ new replace-opcode values
6553 // if we've written over them. And put the int3 back in for write-memory.
6554 //
6555 // Note: If we're writing memory over top of a patch, then it must be JITted or stub code.
6556 // Writing over JITed or Stub code can be dangerous since the CLR may not expect it 
6557 // (eg. JIT data structures about the code layout may be incorrect), but in certain
6558 // narrow cases it may be safe (eg. replacing a constant).  VS says they wouldn't expect 
6559 // this to work, but we'll keep the support in for legacy reasons.
6560 //
6561 // address, size - describe buffer in LS memory
6562 // buffer - local copy of buffer that will be read/written from/to LS.
6563 // bufferCopy - for writeprocessmemory, copy of original buffer (w/o injected patches)
6564 // pbUpdatePatchTable - flag if patchtable got dirty and needs to be updated.
6565 HRESULT CordbProcess::AdjustBuffer( CORDB_ADDRESS address,
6566                                     SIZE_T size,
6567                                     BYTE buffer[],
6568                                     BYTE **bufferCopy,
6569                                     AB_MODE mode,
6570                                     BOOL *pbUpdatePatchTable)
6571 {
6572     INTERNAL_API_ENTRY(this);
6573
6574     _ASSERTE(m_initialized);
6575     _ASSERTE(this->ThreadHoldsProcessLock());
6576
6577     if (    address == NULL
6578          || size == NULL
6579          || buffer == NULL
6580          || (mode != AB_READ && mode != AB_WRITE) )
6581         return E_INVALIDARG;
6582
6583     if (pbUpdatePatchTable != NULL )
6584         *pbUpdatePatchTable = FALSE;
6585
6586     // If we don't have a patch table loaded, then return S_OK since there are no patches to adjust
6587     if (m_pPatchTable == NULL)
6588         return S_OK;
6589
6590     //is the requested memory completely out-of-range?
6591     if ((m_minPatchAddr > (address + (size - 1))) ||
6592         (m_maxPatchAddr < address))
6593     {
6594         return S_OK;
6595     }
6596
6597     // Without runtime offsets, we can't adjust - this should only ever happen on dumps, where there's
6598     // no W32ET to get the offsets, and so they stay zeroed
6599     if (!m_runtimeOffsetsInitialized)
6600         return S_OK;
6601
6602     LOG((LF_CORDB,LL_INFO10000, "CordbProcess::AdjustBuffer at addr 0x%p\n", address));
6603
6604     if (mode == AB_WRITE)
6605     {
6606         // We don't want to mess up the original copy of the buffer, so
6607         // for right now, just copy it wholesale.
6608         (*bufferCopy) = new (nothrow) BYTE[size];
6609         if (NULL == (*bufferCopy))
6610             return E_OUTOFMEMORY;
6611
6612         memmove((*bufferCopy), buffer, size);
6613     }
6614
6615     ULONG iNextFree = m_iFirstPatch;
6616     while( iNextFree != DPT_TERMINATING_INDEX )
6617     {
6618         BYTE *DebuggerControllerPatch = m_pPatchTable + m_runtimeOffsets.m_cbPatch*iNextFree;
6619         PRD_TYPE opcode = *(PRD_TYPE *)(DebuggerControllerPatch + m_runtimeOffsets.m_offOpcode);
6620         CORDB_ADDRESS patchAddress = PTR_TO_CORDB_ADDRESS(*(BYTE**)(DebuggerControllerPatch + m_runtimeOffsets.m_offAddr));
6621
6622         if (IsPatchInRequestedRange(address, size, patchAddress))
6623         {
6624             if (mode == AB_READ)
6625             {
6626                 CORDbgSetInstructionEx(buffer, address, patchAddress, opcode, size);
6627             }
6628             else if (mode == AB_WRITE)
6629             {
6630                 _ASSERTE( pbUpdatePatchTable != NULL );
6631                 _ASSERTE( bufferCopy != NULL );
6632
6633                 //There can be multiple patches at the same address: we don't want 2nd+ patches to get the 
6634                 // break opcode, so we read from the unmodified copy.
6635                 m_rgUncommitedOpcode[iNextFree] =
6636                     CORDbgGetInstructionEx(*bufferCopy, address, patchAddress, opcode, size);
6637
6638                 //put the breakpoint into the memory itself
6639                 CORDbgInsertBreakpointEx(buffer, address, patchAddress, opcode, size);
6640
6641                 *pbUpdatePatchTable = TRUE;
6642             }
6643             else
6644                 _ASSERTE( !"CordbProcess::AdjustBuffergiven non(Read|Write) mode!" );
6645         }
6646
6647         iNextFree = m_rgNextPatch[iNextFree];
6648     }
6649
6650     // If we created a copy of the buffer but didn't modify it, then free it now.
6651     if( ( mode == AB_WRITE ) && ( !*pbUpdatePatchTable ) )
6652     {
6653         delete [] *bufferCopy;
6654         *bufferCopy = NULL;
6655     }
6656     
6657     return S_OK;
6658 }
6659
6660
6661 void CordbProcess::CommitBufferAdjustments( CORDB_ADDRESS start,
6662                                             CORDB_ADDRESS end )
6663 {
6664     INTERNAL_API_ENTRY(this);
6665
6666     _ASSERTE(m_initialized);
6667     _ASSERTE(this->ThreadHoldsProcessLock());
6668     _ASSERTE(m_runtimeOffsetsInitialized);
6669
6670     ULONG iPatch = m_iFirstPatch;
6671     while( iPatch != DPT_TERMINATING_INDEX )
6672     {
6673         BYTE *DebuggerControllerPatch = m_pPatchTable +
6674             m_runtimeOffsets.m_cbPatch*iPatch;
6675
6676         BYTE *patchAddress = *(BYTE**)(DebuggerControllerPatch + m_runtimeOffsets.m_offAddr);
6677
6678         if (IsPatchInRequestedRange(start, (SIZE_T)(end - start), PTR_TO_CORDB_ADDRESS(patchAddress)) &&
6679             !PRDIsBreakInst(&(m_rgUncommitedOpcode[iPatch])))
6680         {
6681             //copy this back to the copy of the patch table
6682             *(PRD_TYPE *)(DebuggerControllerPatch + m_runtimeOffsets.m_offOpcode) =
6683                 m_rgUncommitedOpcode[iPatch];
6684         }
6685
6686         iPatch = m_rgNextPatch[iPatch];
6687     }
6688 }
6689
6690 void CordbProcess::ClearBufferAdjustments( )
6691 {
6692     INTERNAL_API_ENTRY(this);
6693     _ASSERTE(this->ThreadHoldsProcessLock());
6694
6695     ULONG iPatch = m_iFirstPatch;
6696     while( iPatch != DPT_TERMINATING_INDEX )
6697     {
6698         InitializePRDToBreakInst(&(m_rgUncommitedOpcode[iPatch]));
6699         iPatch = m_rgNextPatch[iPatch];
6700     }
6701 }
6702
6703 void CordbProcess::ClearPatchTable(void )
6704 {
6705     INTERNAL_API_ENTRY(this);
6706     _ASSERTE(this->ThreadHoldsProcessLock());
6707
6708     if (m_pPatchTable != NULL )
6709     {
6710         delete [] m_pPatchTable;
6711         m_pPatchTable = NULL;
6712
6713         delete [] m_rgNextPatch;
6714         m_rgNextPatch = NULL;
6715
6716         delete [] m_rgUncommitedOpcode;
6717         m_rgUncommitedOpcode = NULL;
6718
6719         m_iFirstPatch = DPT_TERMINATING_INDEX;
6720         m_minPatchAddr = MAX_ADDRESS;
6721         m_maxPatchAddr = MIN_ADDRESS;
6722         m_rgData = NULL;
6723         m_cPatch = 0;
6724     }
6725 }
6726
6727 HRESULT CordbProcess::RefreshPatchTable(CORDB_ADDRESS address, SIZE_T size, BYTE buffer[])
6728 {
6729     CONTRACTL
6730     {
6731         NOTHROW;
6732     }
6733     CONTRACTL_END;
6734
6735     INTERNAL_API_ENTRY(this);
6736     _ASSERTE(m_initialized);
6737     _ASSERTE(this->ThreadHoldsProcessLock());
6738
6739     HRESULT hr = S_OK;
6740     BYTE *rgb = NULL;
6741
6742     // All of m_runtimeOffsets will be zeroed out if there's been no call to code:CordbProcess::GetRuntimeOffsets.
6743     // Thus for things to work, we'd have to have a live target that went and got the real values.
6744     // For dumps, things are still all zeroed out because we don't have any events sent to the W32ET, don't
6745     // have a live process to investigate, etc.
6746     if (!m_runtimeOffsetsInitialized)
6747         return S_OK;
6748
6749     _ASSERTE( m_runtimeOffsets.m_cbOpcode == sizeof(PRD_TYPE) );
6750
6751     CORDBRequireProcessStateOK(this);
6752
6753     if (m_pPatchTable == NULL )
6754     {
6755         // First, check to be sure the patch table is valid on the Left Side. If its not, then we won't read it.
6756         BOOL fPatchTableValid = FALSE;
6757
6758         hr = SafeReadStruct(PTR_TO_CORDB_ADDRESS(m_runtimeOffsets.m_pPatchTableValid), &fPatchTableValid);
6759         if (FAILED(hr) || !fPatchTableValid)
6760         {
6761             LOG((LF_CORDB, LL_INFO10000, "Wont refresh patch table because its not valid now.\n"));
6762             return S_OK;
6763         }
6764
6765         SIZE_T offStart = 0;
6766         SIZE_T offEnd = 0;
6767         UINT cbTableSlice = 0;
6768
6769         // Grab the patch table info
6770         offStart = min(m_runtimeOffsets.m_offRgData, m_runtimeOffsets.m_offCData);
6771         offEnd   = max(m_runtimeOffsets.m_offRgData, m_runtimeOffsets.m_offCData) + sizeof(SIZE_T);
6772         cbTableSlice = (UINT)(offEnd - offStart);
6773
6774         if (cbTableSlice == 0)
6775         {
6776             LOG((LF_CORDB, LL_INFO10000, "Wont refresh patch table because its not valid now.\n"));
6777             return S_OK;
6778         }
6779         
6780         EX_TRY
6781         {
6782             rgb = new BYTE[cbTableSlice]; // throws
6783
6784             TargetBuffer tbSlice((BYTE*)m_runtimeOffsets.m_pPatches + offStart, cbTableSlice);
6785             this->SafeReadBuffer(tbSlice, rgb); // Throws;
6786             
6787             // Note that rgData is a pointer in the left side address space
6788             m_rgData = *(BYTE**)(rgb + m_runtimeOffsets.m_offRgData - offStart);
6789             m_cPatch = *(ULONG*)(rgb + m_runtimeOffsets.m_offCData - offStart);
6790
6791             // Grab the patch table
6792             UINT cbPatchTable = (UINT)(m_cPatch * m_runtimeOffsets.m_cbPatch);
6793
6794             if (cbPatchTable == 0)
6795             {
6796                 LOG((LF_CORDB, LL_INFO10000, "Wont refresh patch table because its not valid now.\n"));
6797                 _ASSERTE(hr == S_OK);
6798                 goto LExit; // can't return since we're in a Try/Catch
6799             }
6800
6801             // Throwing news
6802             m_pPatchTable = new BYTE[ cbPatchTable ];
6803             m_rgNextPatch = new ULONG[m_cPatch];
6804             m_rgUncommitedOpcode = new PRD_TYPE[m_cPatch];
6805
6806             TargetBuffer tb(m_rgData, cbPatchTable);
6807             this->SafeReadBuffer(tb, m_pPatchTable); // Throws
6808             
6809             //As we go through the patch table we do a number of things:
6810             //
6811             // 1. collect min,max address seen for quick fail check
6812             //
6813             // 2. Link all valid entries into a linked list, the first entry of which is m_iFirstPatch
6814             //
6815             // 3. Initialize m_rgUncommitedOpcode, so that we can undo local patch table changes if WriteMemory can't write
6816             // atomically.
6817             //
6818             // 4. If the patch is in the memory we grabbed, unapply it.
6819
6820             ULONG iDebuggerControllerPatchPrev = DPT_TERMINATING_INDEX;
6821
6822             m_minPatchAddr = MAX_ADDRESS;
6823             m_maxPatchAddr = MIN_ADDRESS;
6824             m_iFirstPatch = DPT_TERMINATING_INDEX;
6825
6826             for (ULONG iPatch = 0; iPatch < m_cPatch;iPatch++)
6827             {
6828                 // <REVISIT_TODO>@todo port: we're making assumptions about the size of opcodes,address pointers, etc</REVISIT_TODO>
6829                 BYTE *DebuggerControllerPatch = m_pPatchTable + m_runtimeOffsets.m_cbPatch * iPatch;
6830                 PRD_TYPE opcode = *(PRD_TYPE*)(DebuggerControllerPatch + m_runtimeOffsets.m_offOpcode);
6831                 CORDB_ADDRESS patchAddress = PTR_TO_CORDB_ADDRESS(*(BYTE**)(DebuggerControllerPatch + m_runtimeOffsets.m_offAddr));
6832
6833                 // A non-zero opcode indicates to us that this patch is valid.
6834                 if (!PRDIsEmpty(opcode))
6835                 {
6836                     _ASSERTE( patchAddress != 0 );
6837
6838                     // (1), above
6839                     // Note that GetPatchEndAddr() returns the address immediately AFTER the patch,
6840                     // so we have to subtract 1 from it below.
6841                     if (m_minPatchAddr > patchAddress )
6842                         m_minPatchAddr = patchAddress;
6843                     if (m_maxPatchAddr < patchAddress )
6844                         m_maxPatchAddr = GetPatchEndAddr(patchAddress) - 1;
6845
6846                     // (2), above
6847                     if ( m_iFirstPatch == DPT_TERMINATING_INDEX)
6848                     {
6849                         m_iFirstPatch = iPatch;
6850                         _ASSERTE( iPatch != DPT_TERMINATING_INDEX);
6851                     }
6852
6853                     if (iDebuggerControllerPatchPrev != DPT_TERMINATING_INDEX)
6854                     {
6855                         m_rgNextPatch[iDebuggerControllerPatchPrev] = iPatch;
6856                     }
6857
6858                     iDebuggerControllerPatchPrev = iPatch;
6859
6860                     // (3), above
6861                     InitializePRDToBreakInst(&(m_rgUncommitedOpcode[iPatch]));
6862
6863                     // (4), above
6864                     if (IsPatchInRequestedRange(address, size, patchAddress))
6865                     {
6866                         _ASSERTE( buffer != NULL );
6867                         _ASSERTE( size != NULL );
6868
6869
6870                         //unapply the patch here.
6871                         CORDbgSetInstructionEx(buffer, address, patchAddress, opcode, size);
6872                     }
6873
6874                 }
6875             }
6876
6877             if (iDebuggerControllerPatchPrev != DPT_TERMINATING_INDEX)
6878             {
6879                 m_rgNextPatch[iDebuggerControllerPatchPrev] = DPT_TERMINATING_INDEX;
6880             }
6881         }
6882 LExit:
6883     ;
6884         EX_CATCH_HRESULT(hr);
6885     }
6886
6887  
6888     if (rgb != NULL )
6889     {
6890         delete [] rgb;
6891     }
6892
6893     if (FAILED( hr ) )
6894     {
6895         ClearPatchTable();
6896     }
6897
6898     return hr;
6899 }
6900
6901 //---------------------------------------------------------------------------------------
6902 //
6903 // Given an address, see if there is a patch in the patch table that matches it and return 
6904 // if its an unmanaged patch or not.
6905 //
6906 // Arguments:
6907 //     address - The address of an instruction to check in the target address space.
6908 //     pfPatchFound - Space to store the result, TRUE if the address belongs to a
6909 //         patch, FALSE if not.  Only valid if this method returns a success code.
6910 //     pfPatchIsUnmanaged - Space to store the result, TRUE if the address is a patch
6911 //         and the patch is unmanaged, FALSE if not.  Only valid if this method returns a 
6912 //         success code.
6913 //
6914 // Return Value:
6915 //     Typical HRESULT symantics, nothing abnormal.
6916 //
6917 // Note: this method is pretty in-efficient. It refreshes the patch table, then scans it. 
6918 //     Refreshing the patch table involves a scan, too, so this method could be folded 
6919 //     with that.
6920 //
6921 //---------------------------------------------------------------------------------------
6922 HRESULT CordbProcess::FindPatchByAddress(CORDB_ADDRESS address, bool *pfPatchFound, bool *pfPatchIsUnmanaged)
6923 {
6924     INTERNAL_API_ENTRY(this);
6925     _ASSERTE(ThreadHoldsProcessLock());
6926     _ASSERTE((pfPatchFound != NULL) && (pfPatchIsUnmanaged != NULL));
6927     _ASSERTE(m_runtimeOffsetsInitialized);
6928     FAIL_IF_NEUTERED(this);
6929
6930     *pfPatchFound = false;
6931     *pfPatchIsUnmanaged = false;
6932
6933     // First things first. If the process isn't initialized, then there can be no patch table, so we know the breakpoint
6934     // doesn't belong to the Runtime.
6935     if (!m_initialized)
6936     {
6937         return S_OK;
6938     }
6939
6940     // This method is called from the main loop of the win32 event thread in response to a first chance breakpoint event
6941     // that we know is not a flare. The process has been runnning, and it may have invalidated the patch table, so we'll
6942     // flush it here before refreshing it to make sure we've got the right thing.
6943     //
6944     // Note: we really should have the Left Side mark the patch table dirty to help optimize this.
6945     ClearPatchTable();
6946
6947     // Refresh the patch table.
6948     HRESULT hr = RefreshPatchTable();
6949
6950     if (FAILED(hr))
6951     {
6952         LOG((LF_CORDB, LL_INFO1000, "CP::FPBA: failed to refresh the patch table\n"));
6953         return hr;
6954     }
6955
6956     // If there is no patch table yet, then we know there is no patch at the given address, so return S_OK with
6957     // *patchFound = false.
6958     if (m_pPatchTable == NULL)
6959     {
6960         LOG((LF_CORDB, LL_INFO1000, "CP::FPBA: no patch table\n"));
6961         return S_OK;
6962     }
6963
6964     // Scan the patch table for a matching patch.
6965     for (ULONG iNextPatch = m_iFirstPatch; iNextPatch != DPT_TERMINATING_INDEX; iNextPatch = m_rgNextPatch[iNextPatch])
6966     {
6967         BYTE *patch = m_pPatchTable + (m_runtimeOffsets.m_cbPatch * iNextPatch);
6968         BYTE *patchAddress = *(BYTE**)(patch + m_runtimeOffsets.m_offAddr);
6969         DWORD traceType = *(DWORD*)(patch + m_runtimeOffsets.m_offTraceType);
6970
6971         if (address == PTR_TO_CORDB_ADDRESS(patchAddress))
6972         {
6973             *pfPatchFound = true;
6974
6975             if (traceType == m_runtimeOffsets.m_traceTypeUnmanaged)
6976             {
6977                 *pfPatchIsUnmanaged = true;
6978
6979 #if defined(_DEBUG)
6980                 HRESULT hrDac = S_OK;
6981                 EX_TRY
6982                 {
6983                     // We should be able to double check w/ DAC that this really is outside of the runtime.
6984                     IDacDbiInterface::AddressType addrType = GetDAC()->GetAddressType(address);
6985                     CONSISTENCY_CHECK_MSGF(addrType == IDacDbiInterface::kAddressUnrecognized, ("Bad address type = %d", addrType));
6986                 }
6987                 EX_CATCH_HRESULT(hrDac);
6988                 CONSISTENCY_CHECK_MSGF(SUCCEEDED(hrDac), ("DAC::GetAddressType failed, hr=0x%08x", hrDac));
6989 #endif
6990             }
6991
6992             break;
6993         }
6994     }
6995
6996     // If we didn't find a patch, its actually still possible that this breakpoint exception belongs to us. There are
6997     // races with very large numbers of threads entering the Runtime through the same managed function. We will have
6998     // multiple threads adding and removing ref counts to an int 3 in the code stream. Sometimes, this count will go to
6999     // zero and the int 3 will be removed, then it will come back up and the int 3 will be replaced. The in-process
7000     // logic takes pains to ensure that such cases are handled properly, therefore we need to perform the same check
7001     // here to make the correct decision. Basically, the check is to see if there is indeed an int 3 at the exception
7002     // address. If there is _not_ an int 3 there, then we've hit this race. We will lie and say a managed patch was
7003     // found to cover this case. This is tracking the logic in DebuggerController::ScanForTriggers, where we call
7004     // IsPatched.
7005     if (*pfPatchFound == false)
7006     {
7007         // Read one instruction from the faulting address...
7008 #if defined(DBG_TARGET_ARM) || defined(DBG_TARGET_ARM64)
7009         PRD_TYPE TrapCheck = 0;
7010 #else
7011         BYTE TrapCheck = 0;
7012 #endif
7013
7014         HRESULT hr2 = SafeReadStruct(address, &TrapCheck);
7015
7016         if (SUCCEEDED(hr2) && (TrapCheck != CORDbg_BREAK_INSTRUCTION))
7017         {
7018             LOG((LF_CORDB, LL_INFO1000, "CP::FPBA: patchFound=true based on odd missing int 3 case.\n"));
7019
7020             *pfPatchFound = true;
7021         }
7022     }
7023
7024     LOG((LF_CORDB, LL_INFO1000, "CP::FPBA: patchFound=%d, patchIsUnmanaged=%d\n", *pfPatchFound, *pfPatchIsUnmanaged));
7025
7026     return S_OK;
7027 }
7028
7029 HRESULT CordbProcess::WriteMemory(CORDB_ADDRESS address, DWORD size,
7030                                   BYTE buffer[], SIZE_T *written)
7031 {
7032     PUBLIC_REENTRANT_API_ENTRY(this);
7033     FAIL_IF_NEUTERED(this);
7034     CORDBRequireProcessStateOK(this);
7035     _ASSERTE(m_runtimeOffsetsInitialized);
7036
7037
7038     if (size == 0 || address == NULL)
7039         return E_INVALIDARG;
7040
7041     VALIDATE_POINTER_TO_OBJECT_ARRAY(buffer, BYTE, size, true, true);
7042     VALIDATE_POINTER_TO_OBJECT(written, SIZE_T *);
7043
7044
7045 #if defined(_DEBUG) && defined(FEATURE_INTEROP_DEBUGGING)
7046     // Shouldn't be using this to write int3. Use UM BP API instead.
7047     // This is technically legal (what if the '0xcc' is data or something), so we can't fail in retail.
7048     // But we can add this debug-only check to help VS migrate to the new API.
7049     static ConfigDWORD configCheckInt3;
7050     DWORD fCheckInt3 = configCheckInt3.val(CLRConfig::INTERNAL_DbgCheckInt3);
7051     if (fCheckInt3)
7052     {
7053 #if defined(DBG_TARGET_X86) || defined(DBG_TARGET_AMD64)
7054         if (size == 1 && buffer[0] == 0xCC)
7055         {
7056             CONSISTENCY_CHECK_MSGF(false,
7057                 ("You're using ICorDebugProcess::WriteMemory() to write an 'int3' (1 byte 0xCC) at address 0x%p.\n"
7058                 "If you're trying to set a breakpoint, you should be using ICorDebugProcess::SetUnmanagedBreakpoint() instead.\n"
7059                 "(This assert is only enabled under the COM+ knob DbgCheckInt3.)\n",
7060                 CORDB_ADDRESS_TO_PTR(address)));
7061         }
7062 #endif // DBG_TARGET_X86 || DBG_TARGET_AMD64   
7063
7064         // check if we're replaced an opcode.
7065         if (size == 1)
7066         {
7067             RSLockHolder ch(&this->m_processMutex);
7068             
7069             NativePatch * p = GetNativePatch(CORDB_ADDRESS_TO_PTR(address));
7070             if (p != NULL)
7071             {
7072             CONSISTENCY_CHECK_MSGF(false,
7073                 ("You're using ICorDebugProcess::WriteMemory() to write an 'opcode (0x%x)' at address 0x%p.\n"
7074                 "There's already a native patch at that address from ICorDebugProcess::SetUnmanagedBreakpoint().\n"
7075                 "If you're trying to remove the breakpoint, use ICDProcess::ClearUnmanagedBreakpoint() instead.\n"
7076                 "(This assert is only enabled under the COM+ knob DbgCheckInt3.)\n",
7077                 (DWORD) (buffer[0]), CORDB_ADDRESS_TO_PTR(address)));
7078             }
7079         }
7080     }
7081 #endif // _DEBUG && FEATURE_INTEROP_DEBUGGING
7082
7083
7084     *written = 0;
7085
7086     HRESULT hr = S_OK;
7087     HRESULT hrSaved = hr; // this will hold the 'real' hresult in case of a
7088                           // partially completed operation
7089     HRESULT hrPartialCopy = HRESULT_FROM_WIN32(ERROR_PARTIAL_COPY);
7090
7091     BOOL bUpdateOriginalPatchTable = FALSE;
7092     BYTE *bufferCopy = NULL;
7093
7094     // Only update the patch table if the managed state of the process
7095     // is initialized.
7096     if (m_initialized)
7097     {
7098         RSLockHolder ch(&this->m_processMutex);
7099         
7100         if (m_pPatchTable == NULL )
7101         {
7102             if (!SUCCEEDED( hr = RefreshPatchTable() ) )
7103             {
7104                 goto LExit;
7105             }
7106         }
7107
7108         if ( !SUCCEEDED( hr = AdjustBuffer( address,
7109                                             size,
7110                                             buffer,
7111                                             &bufferCopy,
7112                                             AB_WRITE,
7113                                             &bUpdateOriginalPatchTable)))
7114         {
7115             goto LExit;
7116         }
7117     }
7118
7119     //conveniently enough, SafeWriteBuffer will throw if it can't complete the entire operation
7120     EX_TRY
7121     {
7122         TargetBuffer tb(address, size);
7123         SafeWriteBuffer(tb, buffer); // throws
7124         *written = tb.cbSize; // DT's Write does everything or fails.
7125     }
7126     EX_CATCH_HRESULT(hr);
7127
7128     if (FAILED(hr))
7129     {
7130         if(hr != hrPartialCopy)
7131             goto LExit;
7132         else
7133             hrSaved = hr;
7134     }
7135     
7136
7137     LOG((LF_CORDB, LL_INFO100000, "CP::WM: wrote %d bytes at 0x%08x, first byte is 0x%x\n",
7138          *written, (DWORD)address, buffer[0]));
7139
7140     if (bUpdateOriginalPatchTable == TRUE )
7141     {
7142         {
7143             RSLockHolder ch(&this->m_processMutex);
7144
7145             //don't tweak patch table for stuff that isn't written to LeftSide
7146             CommitBufferAdjustments(address, address + *written);
7147         }
7148
7149         // The only way this should be able to fail is if
7150         //someone else fiddles with the memory protections on the
7151         //left side while it's frozen
7152         EX_TRY
7153         {
7154             TargetBuffer tb(m_rgData, (ULONG) (m_cPatch*m_runtimeOffsets.m_cbPatch));
7155             SafeWriteBuffer(tb, m_pPatchTable);
7156         }
7157         EX_CATCH_HRESULT(hr);
7158         SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr);
7159     }
7160
7161     // Since we may have
7162     // overwritten anything (objects, code, etc), we should mark
7163     // everything as needing to be re-cached.
7164     m_continueCounter++;
7165
7166  LExit:
7167     if (m_initialized)
7168     {
7169         RSLockHolder ch(&this->m_processMutex);
7170         ClearBufferAdjustments( );
7171     }
7172
7173     //we messed up our local copy, so get a clean copy the next time
7174     //we need it
7175     if (bUpdateOriginalPatchTable==TRUE)
7176     {
7177         if (bufferCopy != NULL)
7178         {
7179             memmove(buffer, bufferCopy, size);
7180             delete bufferCopy;
7181         }
7182     }
7183
7184     if (FAILED( hr ))
7185     {
7186         //we messed up our local copy, so get a clean copy the next time
7187         //we need it
7188         if (bUpdateOriginalPatchTable==TRUE)
7189         {
7190             RSLockHolder ch(&this->m_processMutex);
7191             ClearPatchTable();
7192         }
7193     }
7194     else if( FAILED(hrSaved) )
7195     {
7196         hr = hrSaved;
7197     }
7198
7199     return hr;
7200 }
7201
7202 HRESULT CordbProcess::ClearCurrentException(DWORD threadID)
7203 {
7204 #ifndef FEATURE_INTEROP_DEBUGGING
7205     return E_INVALIDARG;
7206 #else
7207     PUBLIC_API_ENTRY(this);
7208
7209     RSLockHolder lockHolder(GetProcessLock());
7210
7211     // There's something wrong if you're calling this an there are no queued unmanaged events.
7212     if ((m_unmanagedEventQueue == NULL) && (m_outOfBandEventQueue == NULL))
7213         return E_INVALIDARG;
7214
7215     // Grab the unmanaged thread object.
7216     CordbUnmanagedThread *pUThread = GetUnmanagedThread(threadID);
7217
7218     if (pUThread == NULL)
7219         return E_INVALIDARG;
7220
7221     LOG((LF_CORDB, LL_INFO1000, "CP::CCE: tid=0x%x\n", threadID));
7222
7223     // We clear both the IB and OOB event.
7224     if (pUThread->HasIBEvent() && !pUThread->IBEvent()->IsEventUserContinued())
7225     {
7226         pUThread->IBEvent()->SetState(CUES_ExceptionCleared);
7227     }
7228
7229     if (pUThread->HasOOBEvent())
7230     {
7231         // must decide exception status _before_ we continue the event.
7232         _ASSERTE(!pUThread->OOBEvent()->IsEventContinuedUnhijacked());
7233         pUThread->OOBEvent()->SetState(CUES_ExceptionCleared);
7234     }
7235
7236     // If the thread is hijacked, then set the thread's debugger word to 0 to indicate to it that the
7237     // exception has been cleared.
7238     if (pUThread->IsGenericHijacked())
7239     {
7240         HRESULT hr = pUThread->SetEEDebuggerWord(0);
7241         _ASSERTE(SUCCEEDED(hr));
7242     }
7243
7244     return S_OK;
7245 #endif // FEATURE_INTEROP_DEBUGGING
7246 }
7247
7248 #ifdef FEATURE_INTEROP_DEBUGGING
7249 CordbUnmanagedThread *CordbProcess::HandleUnmanagedCreateThread(DWORD dwThreadId, HANDLE hThread, void *lpThreadLocalBase)
7250 {
7251     INTERNAL_API_ENTRY(this);
7252     CordbUnmanagedThread *ut = new (nothrow) CordbUnmanagedThread(this, dwThreadId, hThread, lpThreadLocalBase);
7253
7254     if (ut != NULL)
7255     {
7256         HRESULT hr = m_unmanagedThreads.AddBase(ut); // InternalAddRef, release on EXIT_THREAD events.
7257
7258         if (!SUCCEEDED(hr))
7259         {
7260             delete ut;
7261             ut = NULL;
7262
7263             LOG((LF_CORDB, LL_INFO10000, "Failed adding unmanaged thread to process!\n"));
7264             CORDBSetUnrecoverableError(this, hr, 0);
7265         }
7266     }
7267     else
7268     {
7269         LOG((LF_CORDB, LL_INFO10000, "New CordbThread failed!\n"));
7270         CORDBSetUnrecoverableError(this, E_OUTOFMEMORY, 0);
7271     }
7272
7273     return ut;
7274 }
7275 #endif // FEATURE_INTEROP_DEBUGGING
7276
7277
7278 //-----------------------------------------------------------------------------
7279 // Initializes the DAC
7280 // Arguments: none--initializes the DAC for this CordbProcess instance
7281 // Note: Throws on error
7282 //-----------------------------------------------------------------------------
7283 void CordbProcess::InitDac()
7284 {        
7285     // Go-Go DAC power!!
7286     HRESULT hr = S_OK;
7287     EX_TRY
7288     {
7289         InitializeDac();
7290     }
7291     EX_CATCH_HRESULT(hr);
7292
7293     // We Need DAC to debug for both Managed & Interop.
7294     if (FAILED(hr))
7295     {
7296         // We assert here b/c we're trying to be friendly. Most likely, the cause is either:
7297         // - a bad installation
7298         // - a CLR dev built mscorwks but didn't build DAC.
7299         SIMPLIFYING_ASSUMPTION_MSGF(false, ("Failed to load DAC while for debugging. hr=0x%08x", hr));
7300         ThrowHR(hr);
7301     }   
7302 } //CordbProcess::InitDac
7303
7304 // Update the entire RS copy of the debugger control block by reading the LS copy. The RS copy is treated as
7305 // a throw-away temporary buffer, rather than a true cache. That is, we make no assumptions about the
7306 // validity of the information over time. Thus, before using any of the values, we need to update it. We
7307 // update everything for simplicity; any perf hit we take by doing this instead of updating the individual
7308 // fields we want at any given point isn't significant, particularly if we are updating multiple fields.
7309
7310 // Arguments: 
7311 //     none, but reads process memory from the LS debugger control block 
7312 // Return Value: none (copies from LS DCB to RS buffer GetDCB())
7313 // Note: throws if SafeReadBuffer fails
7314 void CordbProcess::UpdateRightSideDCB()
7315 {
7316     IfFailThrow(m_pEventChannel->UpdateRightSideDCB());
7317 } // CordbProcess::UpdateRightSideDCB
7318
7319 // Update a single field with a value stored in the RS copy of the DCB. We can't update the entire LS DCB
7320 // because in some cases, the LS and RS are simultaneously initializing the DCB. If we initialize a field on
7321 // the RS and write back the whole thing, we may overwrite something the LS has initialized in the interim. 
7322
7323 // Arguments:
7324 //     input: rsFieldAddr - the address of the field in the RS copy of the DCB that we want to write back to
7325 //                          the LS DCB. We use this to compute the offset of the field from the beginning of the
7326 //                          DCB and then add this offset to the starting address of the LS DCB to get the LS
7327 //                          address of the field we are updating
7328 //            size        - the size of the field we're updating.
7329 // Return value: none
7330 // Note: throws if SafeWriteBuffer fails
7331 void CordbProcess::UpdateLeftSideDCBField(void * rsFieldAddr, SIZE_T size)
7332 {
7333     IfFailThrow(m_pEventChannel->UpdateLeftSideDCBField(rsFieldAddr, size));
7334 } // CordbProcess::UpdateRightSideDCB
7335
7336
7337 //-----------------------------------------------------------------------------
7338 // Gets the remote address of the event block for the Target and verifies that it's valid.
7339 // We use this address when we need to read from or write to the debugger control block.
7340 // Also allocates the RS buffer used for temporary storage for information from the DCB and 
7341 // copies the LS DCB into the RS buffer.
7342 // Arguments:
7343 //     output: pfBlockExists - true iff the LS DCB has been successfully allocated.  Note that
7344 //             we need this information even if the function throws, so we can't simply send it back 
7345 //             as a return value.
7346 // Return value:
7347 //     None, but allocates GetDCB() on success. If the LS DCB has not  
7348 //     been successfully initialized or if this throws, GetDCB() will be NULL. 
7349 //
7350 // Notes:
7351 //     Throws on error
7352 //
7353 //-----------------------------------------------------------------------------
7354 void CordbProcess::GetEventBlock(BOOL * pfBlockExists)
7355 {    
7356     if (GetDCB() == NULL) // we only need to do this once
7357     {
7358         _ASSERTE(m_pShim != NULL);
7359         _ASSERTE(ThreadHoldsProcessLock());
7360
7361         // This will Initialize the DAC/DBI interface.     
7362         BOOL fDacReady = TryInitializeDac();
7363
7364         if (fDacReady)
7365         {
7366             // Ensure that we have a DAC interface.
7367             _ASSERTE(m_pDacPrimitives != NULL);
7368
7369             // This is not technically necessary for Mac debugging.  The event channel doesn't rely on
7370             // knowing the target address of the DCB on the LS.
7371             CORDB_ADDRESS pLeftSideDCB = NULL;
7372             pLeftSideDCB = (GetDAC()->GetDebuggerControlBlockAddress());
7373             if (pLeftSideDCB == NULL)
7374             {
7375                 *pfBlockExists = false;
7376                 ThrowHR(CORDBG_E_DEBUGGING_NOT_POSSIBLE); 
7377             }
7378
7379             IfFailThrow(NewEventChannelForThisPlatform(pLeftSideDCB, 
7380                                                        m_pMutableDataTarget, 
7381                                                        GetPid(),
7382                                                        m_pShim->GetMachineInfo(),
7383                                                        &m_pEventChannel));
7384             _ASSERTE(m_pEventChannel != NULL);
7385
7386             // copy information from left side DCB
7387             UpdateRightSideDCB();
7388
7389             // Verify that the control block is valid.
7390             // This  will throw on error. 
7391             VerifyControlBlock();   
7392             
7393             *pfBlockExists = true;
7394         }
7395         else 
7396         {
7397             // we can't initialize the DAC, so we can't get the block
7398             *pfBlockExists = false;
7399         }
7400     }
7401     else // we got the block before
7402     {
7403         *pfBlockExists = true;
7404     }
7405
7406 } // CordbProcess::GetEventBlock()
7407
7408
7409 //
7410 // Verify that the version info in the control block matches what we expect. The minimum supported protocol from the
7411 // Left Side must be greater or equal to the minimum required protocol of the Right Side. Note: its the Left Side's job
7412 // to conform to whatever protocol the Right Side requires, so long as minimum is supported.
7413 //
7414 void CordbProcess::VerifyControlBlock()
7415 {
7416     INTERNAL_API_ENTRY(this);
7417     _ASSERTE(m_pShim != NULL);
7418
7419     if (GetDCB()->m_DCBSize == 0)
7420     {
7421         // the LS is still initializing the DCB
7422         ThrowHR(CORDBG_E_DEBUGGING_NOT_POSSIBLE);
7423     }
7424
7425     // Fill in the protocol numbers for the Right Side and update the LS DCB.
7426     GetDCB()->m_rightSideProtocolCurrent = CorDB_RightSideProtocolCurrent;
7427     UpdateLeftSideDCBField(&(GetDCB()->m_rightSideProtocolCurrent), sizeof(GetDCB()->m_rightSideProtocolCurrent));
7428
7429     GetDCB()->m_rightSideProtocolMinSupported = CorDB_RightSideProtocolMinSupported;
7430     UpdateLeftSideDCBField(&(GetDCB()->m_rightSideProtocolMinSupported), 
7431                            sizeof(GetDCB()->m_rightSideProtocolMinSupported));
7432
7433     // For Telesto, Dbi and Wks have a more flexible versioning allowed, as described by the Debugger
7434     // Version Protocol String in DEBUGGER_PROTOCOL_STRING in DbgIpcEvents.h. This allows different build
7435     // numbers, but the other protocol numbers should still match.
7436
7437     // These assertions verify that the debug manager is behaving correctly.
7438     // An assertion failure here means that the runtime version of the debuggee is different from the runtime version of
7439     // the debugger is capable of debugging.
7440
7441     // The Debug Manager should properly match LS & RS, and thus guarantee that this assert should never fire.
7442     // But just in case the installation is corrupted, we'll check it.
7443     if (GetDCB()->m_DCBSize != sizeof(DebuggerIPCControlBlock))
7444     {
7445         CONSISTENCY_CHECK_MSGF(false, ("DCB in LS is %d bytes, in RS is %d bytes. Version mismatch!!\n", 
7446                                GetDCB()->m_DCBSize, sizeof(DebuggerIPCControlBlock)));
7447         ThrowHR(CORDBG_E_INCOMPATIBLE_PROTOCOL);
7448     }
7449
7450     // The Left Side has to support at least our minimum required protocol.
7451     if (GetDCB()->m_leftSideProtocolCurrent < GetDCB()->m_rightSideProtocolMinSupported)
7452     {
7453         _ASSERTE(GetDCB()->m_leftSideProtocolCurrent >= GetDCB()->m_rightSideProtocolMinSupported);
7454         ThrowHR(CORDBG_E_INCOMPATIBLE_PROTOCOL);
7455     }
7456
7457     // The Left Side has to be able to emulate at least our minimum required protocol.
7458     if (GetDCB()->m_leftSideProtocolMinSupported > GetDCB()->m_rightSideProtocolCurrent)
7459     {
7460         _ASSERTE(GetDCB()->m_leftSideProtocolMinSupported <= GetDCB()->m_rightSideProtocolCurrent);
7461         ThrowHR(CORDBG_E_INCOMPATIBLE_PROTOCOL);
7462     }
7463
7464 #ifdef _DEBUG
7465     char buf[MAX_LONGPATH];
7466     DWORD len = GetEnvironmentVariableA("CORDBG_NotCompatibleTest", buf, sizeof(buf));
7467     _ASSERTE(len < sizeof(buf));
7468
7469     if (len > 0)
7470         ThrowHR(CORDBG_E_INCOMPATIBLE_PROTOCOL);
7471 #endif
7472
7473     if (GetDCB()->m_bHostingInFiber)
7474     {
7475         ThrowHR(CORDBG_E_CANNOT_DEBUG_FIBER_PROCESS);
7476     }
7477
7478     _ASSERTE(!GetDCB()->m_rightSideShouldCreateHelperThread);
7479 } // CordbProcess::VerifyControlBlock
7480
7481 //-----------------------------------------------------------------------------
7482 // This is the CordbProcess objects chance to inspect the DCB and intialize stuff
7483 //
7484 // Return Value:
7485 //     Typical HRESULT return values, nothing abnormal.
7486 //     If succeeded, then the block exists and is valid.
7487 //
7488 //-----------------------------------------------------------------------------
7489 HRESULT CordbProcess::GetRuntimeOffsets()
7490 {
7491     INTERNAL_API_ENTRY(this);
7492
7493     _ASSERTE(m_pShim != NULL);
7494     UpdateRightSideDCB();
7495
7496     // Can't get a handle to the helper thread if the target is remote.
7497
7498     // If we got this far w/o failing, then we should be able to get the helper thread handle.
7499     // RS will handle not having the helper-thread handle, so we just make a best effort here.
7500     DWORD dwHelperTid = GetDCB()->m_realHelperThreadId;
7501     _ASSERTE(dwHelperTid != 0);
7502
7503
7504     {
7505 #if !defined FEATURE_CORESYSTEM
7506         // kernel32!OpenThread does not exist on all platforms (missing on Win98).
7507         // So we need to delay load it.
7508         typedef HANDLE (WINAPI *FPOPENTHREAD)(DWORD dwDesiredAccess,
7509                                               BOOL bInheritHandle,
7510                                               DWORD dwThreadId);
7511
7512
7513
7514         HMODULE mod = WszGetModuleHandle(W("kernel32.dll"));
7515
7516         _ASSERTE(mod != NULL); // can't fail since Kernel32.dll is already loaded.
7517
7518         const FPOPENTHREAD pfnOpenThread = (FPOPENTHREAD)GetProcAddress(mod, "OpenThread");
7519
7520         if (pfnOpenThread != NULL)
7521         {
7522             m_hHelperThread = pfnOpenThread(SYNCHRONIZE, FALSE, dwHelperTid);
7523             CONSISTENCY_CHECK_MSGF(m_hHelperThread != NULL, ("Failed to get helper-thread handle. tid=0x%x\n", dwHelperTid));
7524         }
7525 #elif FEATURE_PAL
7526         m_hHelperThread = NULL; //RS is supposed to be able to live without a helper thread handle.
7527 #else
7528         m_hHelperThread = OpenThread(SYNCHRONIZE, FALSE, dwHelperTid);
7529         CONSISTENCY_CHECK_MSGF(m_hHelperThread != NULL, ("Failed to get helper-thread handle. tid=0x%x\n", dwHelperTid));
7530 #endif
7531     }
7532
7533     // get the remote address of the runtime offsets structure and read the structure itself
7534     HRESULT hrRead = SafeReadStruct(PTR_TO_CORDB_ADDRESS(GetDCB()->m_pRuntimeOffsets), &m_runtimeOffsets);
7535     
7536     if (FAILED(hrRead))
7537     {
7538         return hrRead;
7539     }
7540
7541     LOG((LF_CORDB, LL_INFO10000, "CP::GRO: got runtime offsets: \n"));
7542
7543 #ifdef FEATURE_INTEROP_DEBUGGING
7544     LOG((LF_CORDB, LL_INFO10000, "    m_genericHijackFuncAddr=          0x%p\n",
7545          m_runtimeOffsets.m_genericHijackFuncAddr));
7546     LOG((LF_CORDB, LL_INFO10000, "    m_signalHijackStartedBPAddr=      0x%p\n",
7547          m_runtimeOffsets.m_signalHijackStartedBPAddr));
7548     LOG((LF_CORDB, LL_INFO10000, "    m_excepNotForRuntimeBPAddr=       0x%p\n",
7549          m_runtimeOffsets.m_excepNotForRuntimeBPAddr));
7550     LOG((LF_CORDB, LL_INFO10000, "    m_notifyRSOfSyncCompleteBPAddr=   0x%p\n",
7551          m_runtimeOffsets.m_notifyRSOfSyncCompleteBPAddr));
7552     LOG((LF_CORDB, LL_INFO10000, "    m_raiseException=                 0x%p\n",
7553          m_runtimeOffsets.m_raiseExceptionAddr));
7554 #endif // FEATURE_INTEROP_DEBUGGING
7555
7556     LOG((LF_CORDB, LL_INFO10000, "    m_TLSIndex=                       0x%08x\n",
7557          m_runtimeOffsets.m_TLSIndex));
7558     LOG((LF_CORDB, LL_INFO10000, "    m_EEThreadStateOffset=            0x%08x\n",
7559          m_runtimeOffsets.m_EEThreadStateOffset));
7560     LOG((LF_CORDB, LL_INFO10000, "    m_EEThreadStateNCOffset=          0x%08x\n",
7561          m_runtimeOffsets.m_EEThreadStateNCOffset));
7562     LOG((LF_CORDB, LL_INFO10000, "    m_EEThreadPGCDisabledOffset=      0x%08x\n",
7563          m_runtimeOffsets.m_EEThreadPGCDisabledOffset));
7564     LOG((LF_CORDB, LL_INFO10000, "    m_EEThreadPGCDisabledValue=       0x%08x\n",
7565          m_runtimeOffsets.m_EEThreadPGCDisabledValue));
7566     LOG((LF_CORDB, LL_INFO10000, "    m_EEThreadDebuggerWordOffset=     0x%08x\n",
7567          m_runtimeOffsets.m_EEThreadDebuggerWordOffset));
7568     LOG((LF_CORDB, LL_INFO10000, "    m_EEThreadFrameOffset=            0x%08x\n",
7569          m_runtimeOffsets.m_EEThreadFrameOffset));
7570     LOG((LF_CORDB, LL_INFO10000, "    m_EEThreadMaxNeededSize=          0x%08x\n",
7571          m_runtimeOffsets.m_EEThreadMaxNeededSize));
7572     LOG((LF_CORDB, LL_INFO10000, "    m_EEThreadSteppingStateMask=      0x%08x\n",
7573          m_runtimeOffsets.m_EEThreadSteppingStateMask));
7574     LOG((LF_CORDB, LL_INFO10000, "    m_EEMaxFrameValue=                0x%08x\n",
7575          m_runtimeOffsets.m_EEMaxFrameValue));
7576     LOG((LF_CORDB, LL_INFO10000, "    m_EEThreadDebuggerFilterContextOffset= 0x%08x\n",
7577          m_runtimeOffsets.m_EEThreadDebuggerFilterContextOffset));
7578     LOG((LF_CORDB, LL_INFO10000, "    m_EEThreadCantStopOffset=         0x%08x\n",
7579          m_runtimeOffsets.m_EEThreadCantStopOffset));
7580     LOG((LF_CORDB, LL_INFO10000, "    m_EEFrameNextOffset=              0x%08x\n",
7581          m_runtimeOffsets.m_EEFrameNextOffset));
7582     LOG((LF_CORDB, LL_INFO10000, "    m_EEIsManagedExceptionStateMask=  0x%08x\n",
7583          m_runtimeOffsets.m_EEIsManagedExceptionStateMask));
7584     LOG((LF_CORDB, LL_INFO10000, "    m_pPatches=                       0x%08x\n",
7585          m_runtimeOffsets.m_pPatches));
7586     LOG((LF_CORDB, LL_INFO10000, "    m_offRgData=                      0x%08x\n",
7587          m_runtimeOffsets.m_offRgData));
7588     LOG((LF_CORDB, LL_INFO10000, "    m_offCData=                       0x%08x\n",
7589          m_runtimeOffsets.m_offCData));
7590     LOG((LF_CORDB, LL_INFO10000, "    m_cbPatch=                        0x%08x\n",
7591          m_runtimeOffsets.m_cbPatch));
7592     LOG((LF_CORDB, LL_INFO10000, "    m_offAddr=                        0x%08x\n",
7593          m_runtimeOffsets.m_offAddr));
7594     LOG((LF_CORDB, LL_INFO10000, "    m_offOpcode=                      0x%08x\n",
7595          m_runtimeOffsets.m_offOpcode));
7596     LOG((LF_CORDB, LL_INFO10000, "    m_cbOpcode=                       0x%08x\n",
7597          m_runtimeOffsets.m_cbOpcode));
7598     LOG((LF_CORDB, LL_INFO10000, "    m_offTraceType=                   0x%08x\n",
7599          m_runtimeOffsets.m_offTraceType));
7600     LOG((LF_CORDB, LL_INFO10000, "    m_traceTypeUnmanaged=             0x%08x\n",
7601          m_runtimeOffsets.m_traceTypeUnmanaged));
7602
7603 #ifdef FEATURE_INTEROP_DEBUGGING
7604     // Flares are only used for interop debugging.
7605
7606     // Do check that the flares are all at unique offsets.
7607     // Since this is determined at link-time, we need a run-time check (an
7608     // assert isn't good enough, since this would only happen in a super
7609     // optimized / bbt run).
7610     {
7611         const void * flares[] = {
7612             m_runtimeOffsets.m_signalHijackStartedBPAddr,
7613             m_runtimeOffsets.m_excepForRuntimeHandoffStartBPAddr,
7614             m_runtimeOffsets.m_excepForRuntimeHandoffCompleteBPAddr,
7615             m_runtimeOffsets.m_signalHijackCompleteBPAddr,
7616             m_runtimeOffsets.m_excepNotForRuntimeBPAddr,
7617             m_runtimeOffsets.m_notifyRSOfSyncCompleteBPAddr,
7618         };
7619         
7620         const int NumFlares = NumItems(flares);
7621
7622         // Ensure that all of the flares are unique.
7623         for(int i = 0; i < NumFlares; i++)
7624         {
7625             for(int j = i+1; j < NumFlares; j++)
7626             {
7627                 if (flares[i] == flares[j])
7628                 {
7629                     // If we ever fail here, that means the LS build is busted.
7630
7631                     // This assert is useful if we drop a checked RS onto a retail
7632                     // LS (that's legal).
7633                     _ASSERTE(!"LS has matching Flares.");
7634                     LOG((LF_CORDB, LL_ALWAYS, "Failing because of matching flares.\n"));
7635                     return CORDBG_E_INCOMPATIBLE_PROTOCOL;
7636                 }
7637             }
7638         }
7639     }
7640
7641 #endif  // FEATURE_INTEROP_DEBUGGING
7642     m_runtimeOffsetsInitialized = true;
7643     return S_OK;
7644 }
7645
7646 #ifdef FEATURE_INTEROP_DEBUGGING
7647
7648 //-----------------------------------------------------------------------------
7649 // Resume hijacked threads.
7650 //-----------------------------------------------------------------------------
7651 void CordbProcess::ResumeHijackedThreads()
7652 {
7653     INTERNAL_API_ENTRY(this);
7654     _ASSERTE(m_pShim != NULL);
7655     _ASSERTE(ThreadHoldsProcessLock());
7656
7657     LOG((LF_CORDB, LL_INFO10000, "CP::RHT: entered\n"));
7658     if (this->m_state & (CordbProcess::PS_SOME_THREADS_SUSPENDED | CordbProcess::PS_HIJACKS_IN_PLACE))
7659     {
7660         // On XP, This will also resume the threads suspended for Sync.
7661         this->ResumeUnmanagedThreads();
7662     }
7663
7664     // Hijacks send their ownership flares and then wait on this event. By setting this
7665     // we let the hijacks run free.
7666     if (this->m_leftSideUnmanagedWaitEvent != NULL)
7667     {
7668         SetEvent(this->m_leftSideUnmanagedWaitEvent);
7669     }
7670     else
7671     {
7672         // Only reason we expect to not have this event is if the CLR hasn't been loaded yet.
7673         // In that case, we won't hijack, so nobody's listening for this event either.
7674         _ASSERTE(!m_initialized);
7675     }
7676 }
7677
7678 //-----------------------------------------------------------------------------
7679 // For debugging support, record the win32 events.
7680 // Note that although this is for debugging, we want it in retail because we'll
7681 // be debugging retail most of the time :(
7682 // pEvent - the win32 debug event we just received
7683 // pUThread - our unmanaged thread object for the event. We could look it up
7684 //           from pEvent->dwThreadId, but passed in for perf reasons.
7685 //-----------------------------------------------------------------------------
7686 void CordbProcess::DebugRecordWin32Event(const DEBUG_EVENT * pEvent, CordbUnmanagedThread * pUThread)
7687 {
7688     _ASSERTE(ThreadHoldsProcessLock());
7689
7690     // Although we could look up the Unmanaged thread, it's faster to have it just passed in.
7691     // So here we do a consistency check.
7692     _ASSERTE(pUThread != NULL);
7693     _ASSERTE(pUThread->m_id == pEvent->dwThreadId);
7694
7695     m_DbgSupport.m_TotalNativeEvents++; // bump up the counter.
7696
7697     MiniDebugEvent * pMiniEvent = &m_DbgSupport.m_DebugEventQueue[m_DbgSupport.m_DebugEventQueueIdx];
7698     pMiniEvent->code        = (BYTE) pEvent->dwDebugEventCode;
7699     pMiniEvent->pUThread    = pUThread;
7700
7701     DWORD tid = pEvent->dwThreadId;
7702
7703     // Record debug-event specific data.
7704     switch(pEvent->dwDebugEventCode)
7705     {
7706     case LOAD_DLL_DEBUG_EVENT:
7707         pMiniEvent->u.ModuleData.pBaseAddress = pEvent->u.LoadDll.lpBaseOfDll;
7708         STRESS_LOG2(LF_CORDB, LL_INFO1000, "Win32 Debug Event received: tid=0x%8x, Load Dll. Addr=%p\n",
7709             tid,
7710             pEvent->u.LoadDll.lpBaseOfDll);
7711         break;
7712     case UNLOAD_DLL_DEBUG_EVENT:
7713         pMiniEvent->u.ModuleData.pBaseAddress = pEvent->u.UnloadDll.lpBaseOfDll;
7714         STRESS_LOG2(LF_CORDB, LL_INFO1000, "Win32 Debug Event received: tid=0x%8x, Unload Dll. Addr=%p\n",
7715             tid,
7716             pEvent->u.UnloadDll.lpBaseOfDll);
7717         break;
7718     case EXCEPTION_DEBUG_EVENT:
7719         pMiniEvent->u.ExceptionData.pAddress = pEvent->u.Exception.ExceptionRecord.ExceptionAddress;
7720         pMiniEvent->u.ExceptionData.dwCode   = pEvent->u.Exception.ExceptionRecord.ExceptionCode;
7721
7722         STRESS_LOG3(LF_CORDB, LL_INFO1000, "Win32 Debug Event received: tid=%8x, (1) Exception. Code=0x%08x, Addr=%p\n",
7723             tid,
7724             pMiniEvent->u.ExceptionData.dwCode,
7725             pMiniEvent->u.ExceptionData.pAddress
7726         );
7727         break;
7728     default:
7729         STRESS_LOG2(LF_CORDB, LL_INFO1000, "Win32 Debug Event received tid=%8x, %d\n", tid, pEvent->dwDebugEventCode);
7730         break;
7731     }
7732
7733
7734     // Go to the next entry in the queue.
7735     m_DbgSupport.m_DebugEventQueueIdx = (m_DbgSupport.m_DebugEventQueueIdx + 1) % DEBUG_EVENTQUEUE_SIZE;
7736 }
7737
7738 void CordbProcess::QueueUnmanagedEvent(CordbUnmanagedThread *pUThread, const DEBUG_EVENT *pEvent)
7739 {
7740     INTERNAL_API_ENTRY(this);
7741     _ASSERTE(ThreadHoldsProcessLock());
7742     _ASSERTE(m_pShim != NULL);
7743
7744     LOG((LF_CORDB, LL_INFO10000, "CP::QUE: queued unmanaged event %d for thread 0x%x\n",
7745          pEvent->dwDebugEventCode, pUThread->m_id));
7746
7747
7748     _ASSERTE(pEvent->dwDebugEventCode == EXCEPTION_DEBUG_EVENT);
7749
7750     // Copy the event into the given thread
7751     CordbUnmanagedEvent *ue;
7752
7753     // Use the primary IB event slot unless this is the special stack overflow event case.
7754     if (!pUThread->HasSpecialStackOverflowCase())
7755         ue = pUThread->IBEvent();
7756     else
7757         ue = pUThread->IBEvent2();
7758
7759     if(pUThread->HasIBEvent() && !pUThread->HasSpecialStackOverflowCase())
7760     {
7761         // Any event being replaced should at least have been continued outside of the hijack
7762         // We don't track whether or not we expect the exception to retrigger but if we are replacing
7763         // the event then it did not.
7764         _ASSERTE(ue->IsEventContinuedUnhijacked());
7765         LOG((LF_CORDB, LL_INFO10000, "CP::QUE: A previously seen event is being discarded 0x%x 0x%p\n",
7766          ue->m_currentDebugEvent.u.Exception.ExceptionRecord.ExceptionCode, 
7767          ue->m_currentDebugEvent.u.Exception.ExceptionRecord.ExceptionAddress));
7768         DequeueUnmanagedEvent(ue->m_owner);
7769     }
7770
7771     memcpy(&(ue->m_currentDebugEvent), pEvent, sizeof(DEBUG_EVENT));
7772     ue->m_state = CUES_IsIBEvent;
7773     ue->m_next = NULL;
7774
7775     // Enqueue the event.
7776     pUThread->SetState(CUTS_HasIBEvent);
7777
7778     if (m_unmanagedEventQueue == NULL)
7779         m_unmanagedEventQueue = ue;
7780     else
7781         m_lastQueuedUnmanagedEvent->m_next = ue;
7782
7783     m_lastQueuedUnmanagedEvent = ue;
7784 }
7785
7786 void CordbProcess::DequeueUnmanagedEvent(CordbUnmanagedThread *ut)
7787 {
7788     INTERNAL_API_ENTRY(this);
7789
7790     _ASSERTE(m_unmanagedEventQueue != NULL);
7791     _ASSERTE(ut->HasIBEvent() || ut->HasSpecialStackOverflowCase());
7792     _ASSERTE(ThreadHoldsProcessLock());
7793
7794
7795     CordbUnmanagedEvent *ue;
7796
7797     if (ut->HasIBEvent())
7798         ue = ut->IBEvent();
7799     else
7800     {
7801         ue = ut->IBEvent2();
7802
7803         // Since we're dequeuing the special stack overflow event, we're no longer in the special stack overflow case.
7804         ut->ClearState(CUTS_HasSpecialStackOverflowCase);
7805     }
7806
7807     DWORD ec = ue->m_currentDebugEvent.dwDebugEventCode;
7808     LOG((LF_CORDB, LL_INFO10000, "CP::DUE: dequeue unmanaged event %d for thread 0x%x\n", ec, ut->m_id));
7809
7810     _ASSERTE(ec == EXCEPTION_DEBUG_EVENT);
7811
7812     CordbUnmanagedEvent **tmp = &m_unmanagedEventQueue;
7813     CordbUnmanagedEvent **prev = NULL;
7814
7815     // Note: this supports out-of-order dequeing of unmanaged events. This is necessary because we queue events even if
7816     // we're not clear on the ownership question. When we get the answer, and if the event belongs to the Runtime, we go
7817     // ahead and yank the event out of the queue, wherever it may be.
7818     while (*tmp && *tmp != ue)
7819     {
7820         prev = tmp;
7821         tmp = &((*tmp)->m_next);
7822     }
7823
7824     _ASSERTE(*tmp == ue);
7825
7826     *tmp = (*tmp)->m_next;
7827
7828     if (m_unmanagedEventQueue == NULL)
7829         m_lastQueuedUnmanagedEvent = NULL;
7830     else if (m_lastQueuedUnmanagedEvent == ue)
7831     {
7832         _ASSERTE(prev != NULL);
7833         m_lastQueuedUnmanagedEvent = *prev;
7834     }
7835
7836     ut->ClearState(CUTS_HasIBEvent);
7837
7838 }
7839
7840 void CordbProcess::QueueOOBUnmanagedEvent(CordbUnmanagedThread *pUThread, const DEBUG_EVENT * pEvent)
7841 {
7842     INTERNAL_API_ENTRY(this);
7843     _ASSERTE(ThreadHoldsProcessLock());
7844     _ASSERTE(!pUThread->HasOOBEvent());
7845     _ASSERTE(IsWin32EventThread());
7846     _ASSERTE(m_pShim != NULL);
7847
7848     LOG((LF_CORDB, LL_INFO10000, "CP::QUE: queued OOB unmanaged event %d for thread 0x%x\n",
7849          pEvent->dwDebugEventCode, pUThread->m_id));
7850
7851     // Copy the event into the given thread
7852     CordbUnmanagedEvent *ue = pUThread->OOBEvent();
7853     memcpy(&(ue->m_currentDebugEvent), pEvent, sizeof(DEBUG_EVENT));
7854     ue->m_state = CUES_None;
7855     ue->m_next = NULL;
7856
7857     // Enqueue the event.
7858     pUThread->SetState(CUTS_HasOOBEvent);
7859
7860     if (m_outOfBandEventQueue == NULL)
7861         m_outOfBandEventQueue = ue;
7862     else
7863         m_lastQueuedOOBEvent->m_next = ue;
7864
7865     m_lastQueuedOOBEvent = ue;
7866 }
7867
7868 void CordbProcess::DequeueOOBUnmanagedEvent(CordbUnmanagedThread *ut)
7869 {
7870     INTERNAL_API_ENTRY(this);
7871     _ASSERTE(m_outOfBandEventQueue != NULL);
7872     _ASSERTE(ut->HasOOBEvent());
7873     _ASSERTE(ThreadHoldsProcessLock());
7874
7875     CordbUnmanagedEvent *ue = ut->OOBEvent();
7876     DWORD ec = ue->m_currentDebugEvent.dwDebugEventCode;
7877
7878     LOG((LF_CORDB, LL_INFO10000, "CP::DUE: dequeue OOB unmanaged event %d for thread 0x%x\n", ec, ut->m_id));
7879
7880     CordbUnmanagedEvent **tmp = &m_outOfBandEventQueue;
7881     CordbUnmanagedEvent **prev = NULL;
7882
7883     // Note: this supports out-of-order dequeing of unmanaged events. This is necessary because we queue events even if
7884     // we're not clear on the ownership question. When we get the answer, and if the event belongs to the Runtime, we go
7885     // ahead and yank the event out of the queue, wherever it may be.
7886     while (*tmp && *tmp != ue)
7887     {
7888         prev = tmp;
7889         tmp = &((*tmp)->m_next);
7890     }
7891
7892     _ASSERTE(*tmp == ue);
7893
7894     *tmp = (*tmp)->m_next;
7895
7896     if (m_outOfBandEventQueue == NULL)
7897         m_lastQueuedOOBEvent = NULL;
7898     else if (m_lastQueuedOOBEvent == ue)
7899     {
7900         _ASSERTE(prev != NULL);
7901         m_lastQueuedOOBEvent = *prev;
7902     }
7903
7904     ut->ClearState(CUTS_HasOOBEvent);
7905 }
7906
7907 HRESULT CordbProcess::SuspendUnmanagedThreads()
7908 {
7909     INTERNAL_API_ENTRY(this);
7910
7911     _ASSERTE(ThreadHoldsProcessLock());
7912
7913     // Iterate over all unmanaged threads...
7914     CordbUnmanagedThread* ut;
7915     HASHFIND find;
7916
7917     for (ut =  m_unmanagedThreads.FindFirst(&find); ut != NULL; ut =  m_unmanagedThreads.FindNext(&find))
7918     {
7919
7920         // Don't suspend any thread in a can't stop region. This includes cooperative mode threads & preemptive
7921         // threads that haven't pushed a NativeTransitionFrame. The ultimate problem here is that a thread
7922         // in this state is effectively inside the runtime, and thus may take a lock  that blocks the helper thread.
7923         // IsCan'tStop also includes the helper thread & hijacked threads - which we shouldn't suspend anyways.
7924
7925         // Only suspend those unmanaged threads that aren't already suspended by us and that aren't already hijacked by
7926         // us.
7927
7928         if (!ut->IsSuspended() &&
7929             !ut->IsDeleted() &&
7930             !ut->IsCantStop() &&
7931             !ut->IsBlockingForSync()
7932         )
7933         {
7934             LOG((LF_CORDB, LL_INFO1000, "CP::SUT: suspending unmanaged thread 0x%x, handle 0x%x\n", ut->m_id, ut->m_handle));
7935
7936             DWORD succ = SuspendThread(ut->m_handle);
7937
7938             if (succ == 0xFFFFFFFF)
7939             {
7940                 // This is okay... the thread may be dying after an ExitThread event.
7941                 LOG((LF_CORDB, LL_INFO1000, "CP::SUT: failed to suspend thread 0x%x\n", ut->m_id));
7942             }
7943             else
7944             {
7945                 m_state |= PS_SOME_THREADS_SUSPENDED;
7946
7947                 ut->SetState(CUTS_Suspended);
7948             }
7949         }
7950     }
7951
7952     return S_OK;
7953 }
7954
7955 HRESULT CordbProcess::ResumeUnmanagedThreads()
7956 {
7957     INTERNAL_API_ENTRY(this);
7958     _ASSERTE(ThreadHoldsProcessLock());
7959     FAIL_IF_NEUTERED(this);
7960
7961     // Iterate over all unmanaged threads...
7962     CordbUnmanagedThread* ut;
7963     HASHFIND find;
7964
7965     for (ut =  m_unmanagedThreads.FindFirst(&find); ut != NULL; ut =  m_unmanagedThreads.FindNext(&find))
7966     {
7967         // Only resume those unmanaged threads that were suspended by us.
7968         if (ut->IsSuspended())
7969         {
7970             LOG((LF_CORDB, LL_INFO1000, "CP::RUT: resuming unmanaged thread 0x%x\n", ut->m_id));
7971
7972             DWORD succ = ResumeThread(ut->m_handle);
7973
7974             if (succ == 0xFFFFFFFF)
7975             {
7976                 LOG((LF_CORDB, LL_INFO1000, "CP::RUT: failed to resume thread 0x%x\n", ut->m_id));
7977             }
7978             else
7979                 ut->ClearState(CUTS_Suspended);
7980         }
7981     }
7982
7983     m_state &= ~PS_SOME_THREADS_SUSPENDED;
7984
7985     return S_OK;
7986 }
7987
7988 //-----------------------------------------------------------------------------
7989 // DispatchUnmanagedInBandEvent
7990 //
7991 // Handler for Win32 events already known to be Unmanaged and in-band.
7992 //-----------------------------------------------------------------------------
7993 void CordbProcess::DispatchUnmanagedInBandEvent()
7994 {
7995     INTERNAL_API_ENTRY(this);
7996     _ASSERTE(ThreadHoldsProcessLock());
7997
7998     // There should be no queued OOB events!!! If there are, then we have a breakdown in our protocol, since all OOB
7999     // events should be dispatched before attempting to really continue from any in-band event.
8000     _ASSERTE(m_outOfBandEventQueue == NULL);
8001     _ASSERTE(m_cordb != NULL);
8002     _ASSERTE(m_cordb->m_unmanagedCallback != NULL);
8003     _ASSERTE(!m_dispatchingUnmanagedEvent);
8004
8005     CordbUnmanagedThread * pUnmanagedThread = NULL;
8006     CordbUnmanagedEvent * pUnmanagedEvent = m_unmanagedEventQueue;
8007
8008     while (true)
8009     {
8010         // get the next queued event that isn't dispatched yet
8011         while(pUnmanagedEvent != NULL && pUnmanagedEvent->IsDispatched())
8012         {
8013             pUnmanagedEvent = pUnmanagedEvent->m_next;
8014         }
8015
8016         if(pUnmanagedEvent == NULL)
8017             break;
8018
8019         // Get the thread for this event
8020         _ASSERTE(pUnmanagedThread == NULL);
8021         pUnmanagedThread = pUnmanagedEvent->m_owner;
8022         _ASSERTE(pUnmanagedThread != NULL);
8023
8024         // We better not have dispatched it yet!
8025         _ASSERTE(!pUnmanagedEvent->IsDispatched());
8026
8027         // We shouldn't be dispatching IB events on a thread that has exited.
8028         // Though it's possible that the thread may exit *after* the IB event has been dispatched
8029         // if it gets hijacked.
8030         _ASSERTE(!pUnmanagedThread->IsDeleted());
8031
8032         // Make sure we keep the thread alive while we're playing with it.
8033         pUnmanagedThread->InternalAddRef();
8034
8035         LOG((LF_CORDB, LL_INFO10000, "CP::DUE: dispatching unmanaged event %d for thread 0x%x\n",
8036              pUnmanagedEvent->m_currentDebugEvent.dwDebugEventCode, pUnmanagedThread->m_id));
8037
8038         m_dispatchingUnmanagedEvent = true;
8039
8040         // Add/Remove a reference which is scoped to the time that m_lastDispatchedIBEvent
8041         // is set to pUnmanagedEvent (it is an interior pointer)
8042         // see DevDiv issue 818301 for more details
8043         if(m_lastDispatchedIBEvent != NULL)
8044         {
8045             m_lastDispatchedIBEvent->m_owner->InternalRelease();
8046             m_lastDispatchedIBEvent = NULL;
8047         }
8048         pUnmanagedThread->InternalAddRef();
8049         m_lastDispatchedIBEvent = pUnmanagedEvent;
8050         pUnmanagedEvent->SetState(CUES_Dispatched);
8051
8052         IncStopCount();
8053
8054         Unlock();
8055
8056         {
8057             // Interface is semantically const, but does not include const in signature.
8058             DEBUG_EVENT * pEvent = const_cast<DEBUG_EVENT *> (&(pUnmanagedEvent->m_currentDebugEvent));
8059             PUBLIC_WIN32_CALLBACK_IN_THIS_SCOPE(this,pEvent, FALSE);
8060             m_cordb->m_unmanagedCallback->DebugEvent(pEvent, FALSE);
8061         }
8062
8063         Lock();
8064
8065         // Calling IMDA::Continue() will set m_dispatchingUnmanagedEvent = false.
8066         // So if Continue() was called && we have more events, we'll loop and dispatch more events.
8067         // Else we'll break out of the while loop.
8068         if(m_dispatchingUnmanagedEvent)
8069             break;
8070
8071         // Continue was called in the dispatch callback, but that continue path just
8072         // clears the dispatch flag and returns. The continue right here is the logical
8073         // completion of the user's continue request
8074         // Note it is sometimes the case that these events have already been continued because
8075         // they had defered dispatching. At the time of deferal they were immediately continued.
8076         // If the event is already continued then this continue becomes a no-op.
8077         m_pShim->GetWin32EventThread()->DoDbgContinue(this, pUnmanagedEvent);
8078
8079         // Release our reference to the unmanaged thread that we dispatched
8080         // This event should have been continued long ago...
8081         _ASSERTE(!pUnmanagedThread->IBEvent()->IsEventWaitingForContinue());
8082         pUnmanagedThread->InternalRelease();
8083         pUnmanagedThread = NULL;
8084     }
8085
8086     m_dispatchingUnmanagedEvent = false;
8087
8088     // Release our reference to the last thread that we dispatched now...
8089     if(pUnmanagedThread)
8090     {
8091         pUnmanagedThread->InternalRelease();
8092         pUnmanagedThread = NULL;
8093     }
8094 }
8095
8096 //-----------------------------------------------------------------------------
8097 // DispatchUnmanagedOOBEvent
8098 //
8099 // Handler for Win32 events already known to be Unmanaged and out-of-band.
8100 //-----------------------------------------------------------------------------
8101 void CordbProcess::DispatchUnmanagedOOBEvent()
8102 {
8103     INTERNAL_API_ENTRY(this);
8104     _ASSERTE(ThreadHoldsProcessLock());
8105     _ASSERTE(IsWin32EventThread());
8106
8107     // There should be OOB events queued...
8108     _ASSERTE(m_outOfBandEventQueue != NULL);
8109     _ASSERTE(m_cordb->m_unmanagedCallback != NULL);
8110
8111     do
8112     {
8113         // Get the first event in the OOB Queue...
8114         CordbUnmanagedEvent * pUnmanagedEvent = m_outOfBandEventQueue;
8115         CordbUnmanagedThread * pUnmanagedThread = pUnmanagedEvent->m_owner;
8116
8117         // Make sure we keep the thread alive while we're playing with it.
8118         RSSmartPtr<CordbUnmanagedThread> pRef(pUnmanagedThread);
8119
8120         LOG((LF_CORDB, LL_INFO10000, "[%x] CP::DUE: dispatching OOB unmanaged event %d for thread 0x%x\n",
8121              GetCurrentThreadId(), pUnmanagedEvent->m_currentDebugEvent.dwDebugEventCode, pUnmanagedThread->m_id));
8122
8123         m_dispatchingOOBEvent = true;
8124         pUnmanagedEvent->SetState(CUES_Dispatched);
8125         Unlock();
8126
8127         {
8128             // Interface is semantically const, but does not include const in signature.
8129             DEBUG_EVENT * pEvent = const_cast<DEBUG_EVENT *> (&(pUnmanagedEvent->m_currentDebugEvent));
8130             PUBLIC_WIN32_CALLBACK_IN_THIS_SCOPE(this, pEvent, TRUE);
8131             m_cordb->m_unmanagedCallback->DebugEvent(pEvent, TRUE);
8132         }
8133
8134         Lock();
8135
8136         // If they called Continue from the callback, then continue the OOB event right now before dispatching the next
8137         // one.
8138         if (!m_dispatchingOOBEvent)
8139         {
8140             DequeueOOBUnmanagedEvent(pUnmanagedThread);
8141
8142             // Should not have continued from this debug event yet.
8143             _ASSERTE(pUnmanagedEvent->IsEventWaitingForContinue());
8144
8145             // Do a little extra work if that was an OOB exception event...
8146             HRESULT hr = pUnmanagedEvent->m_owner->FixupAfterOOBException(pUnmanagedEvent);
8147             _ASSERTE(SUCCEEDED(hr));
8148
8149             // Go ahead and continue now...
8150             this->m_pShim->GetWin32EventThread()->DoDbgContinue(this, pUnmanagedEvent);
8151         }
8152
8153         // Implicit release of pUnmanagedThread via pRef
8154     }
8155     while (!m_dispatchingOOBEvent && (m_outOfBandEventQueue != NULL));
8156
8157     m_dispatchingOOBEvent = false;
8158
8159     LOG((LF_CORDB, LL_INFO10000, "CP::DUE: done dispatching OOB events. Queue=0x%08x\n", m_outOfBandEventQueue));
8160 }
8161 #endif // FEATURE_INTEROP_DEBUGGING
8162
8163 //-----------------------------------------------------------------------------
8164 // StartSyncFromWin32Stop
8165 //
8166 // Get the process from a Fozen state or a Live state to a Synchronized State.
8167 // Note that Process Exit is considered to be synchronized.
8168 // This is a nop if we're not Interop Debugging.
8169 // If this function succeeds, we're in a synchronized state.
8170 //
8171 // Arguments:
8172 //    pfAsyncBreakSent - returns if this method sent an async-break or not.
8173 //
8174 // Return value:
8175 //    typical HRESULT return values, nothing sinister here.
8176 //-----------------------------------------------------------------------------
8177 HRESULT CordbProcess::StartSyncFromWin32Stop(BOOL * pfAsyncBreakSent)
8178 {
8179     INTERNAL_API_ENTRY(this);
8180     if (m_pShim == NULL) // This API is moved off to the shim
8181     {
8182         return E_NOTIMPL;
8183     }
8184
8185     HRESULT hr = S_OK;
8186
8187     // Caller should have taken the stop-go lock. This prevents us from racing w/ a continue.
8188     _ASSERTE(m_StopGoLock.HasLock());
8189
8190     // Process should be init before we try to sync it.
8191     _ASSERTE(this->m_initialized);
8192
8193     // If nobody's listening for an AsyncBreak, and we're not stopped, then our caller
8194     // doesn't know if we're sending an AsyncBreak or not; and thus we may not continue.
8195     // Failing this assert means that we're stopping but we don't think we're going to get a continue
8196     // down the road, and thus we're headed for a deadlock.
8197     _ASSERTE((pfAsyncBreakSent != NULL) || (m_stopCount > 0));
8198
8199     if (pfAsyncBreakSent)
8200     {
8201         *pfAsyncBreakSent = FALSE;
8202     }
8203
8204 #ifdef FEATURE_INTEROP_DEBUGGING
8205
8206     // If we're win32 stopped (but not out-of-band win32 stopped), or if we're running free on the Left Side but we're
8207     // just not synchronized (and we're win32 attached), then go ahead and do an internal continue and send an async
8208     // break event to get the Left Side sync'd up.
8209     //
8210     // The process can be running free as far as Win32 events are concerned, but still not synchronized as far as the
8211     // Runtime is concerned. This can happen in a lot of cases where we end up with the Runtime not sync'd but with the
8212     // process running free due to hijacking, etc...
8213     if (((m_state & CordbProcess::PS_WIN32_STOPPED) && (m_outOfBandEventQueue == NULL)) || 
8214         (!GetSynchronized() && IsInteropDebugging()))
8215     {
8216         Lock();
8217
8218         if (((m_state & CordbProcess::PS_WIN32_STOPPED) && (m_outOfBandEventQueue == NULL)) || 
8219             (!GetSynchronized() && IsInteropDebugging()))
8220         {
8221             // This can't be the win32 ET b/c we need that thread to be alive and pumping win32 DE so that
8222             // our Async Break can get across.
8223             // So nobody should ever be calling this on the w32 ET. But they could, since we do trickle in from
8224             // outside APIs. So we need a retail check.
8225             if (IsWin32EventThread())
8226             {
8227                 _ASSERTE(!"Don't call this API on the W32 Event Thread");
8228
8229                 Unlock();
8230                 return ErrWrapper(CORDBG_E_CANT_CALL_ON_THIS_THREAD);
8231             }
8232
8233             STRESS_LOG1(LF_CORDB, LL_INFO1000, "[%x] CP::SSFW32S: sending internal continue\n", GetCurrentThreadId());
8234
8235             // Can't do this on the win32 event thread.
8236             _ASSERTE(!this->IsWin32EventThread());
8237
8238             // If the helper thread is already dead, then we just return as if we sync'd the process.
8239             if (m_helperThreadDead)
8240             {
8241                 if (pfAsyncBreakSent)
8242                 {
8243                     *pfAsyncBreakSent = TRUE;
8244                 }
8245
8246                 // Mark the process as synchronized so no events will be dispatched until the thing is
8247                 // continued. However, the marking here is not a usual marking for synchronized. It has special
8248                 // semantics when we're interop debugging. We use m_oddSync to remember this so that we can take special
8249                 // action in Continue().
8250                 SetSynchronized(true);
8251                 m_oddSync = true;
8252
8253                 // Get the RC Event Thread to stop listening to the process.
8254                 m_cordb->ProcessStateChanged();
8255
8256                 Unlock();
8257
8258                 return S_OK;
8259             }
8260
8261             m_stopRequested = true;
8262
8263             // See ::Stop for why we defer this. The delayed events will be dispatched when some one calls continue.
8264             // And we know they'll call continue b/c (stopCount > 0) || (our caller knows we're sending an AsyncBreak).
8265             m_specialDeferment = true;
8266
8267             Unlock();
8268
8269             // If the process gets synchronized between the Unlock() and here, then SendUnmanagedContinue() will end up
8270             // not doing anything at all since a) it holds the process lock when working and b) it gates everything on
8271             // if the process is sync'd or not. This is exactly what we want.
8272             hr = this->m_pShim->GetWin32EventThread()->SendUnmanagedContinue(this, cInternalUMContinue);
8273
8274             LOG((LF_CORDB, LL_INFO1000, "[%x] CP::SSFW32S: internal continue returned\n", GetCurrentThreadId()));
8275
8276             // Send an async break to the left side now that its running.
8277             DebuggerIPCEvent * pEvent = (DebuggerIPCEvent *) _alloca(CorDBIPC_BUFFER_SIZE);
8278             InitIPCEvent(pEvent, DB_IPCE_ASYNC_BREAK, false, VMPTR_AppDomain::NullPtr());
8279
8280             LOG((LF_CORDB, LL_INFO1000, "[%x] CP::SSFW32S: sending async stop\n", GetCurrentThreadId()));
8281
8282             // If the process gets synchronized between the Unlock() and here, then this message will do nothing (Left
8283             // Side catches it) and we'll never get a response, and it won't hurt anything.
8284             hr = m_cordb->SendIPCEvent(this, pEvent, CorDBIPC_BUFFER_SIZE);
8285             // @Todo- how do we handle a failure here?
8286
8287             // If the send returns with the helper thread being dead, then we know we don't need to wait for the process
8288             // to sync.
8289             if (!m_helperThreadDead)
8290             {
8291                 STRESS_LOG1(LF_CORDB, LL_INFO1000, "[%x] CP::SSFW32S: sent async stop, waiting for event\n", GetCurrentThreadId());
8292
8293                 // If we got synchronized between the Unlock() and here its okay since m_stopWaitEvent is still high
8294                 // from the last sync.
8295                 DWORD dwWaitResult = SafeWaitForSingleObject(this, m_stopWaitEvent, INFINITE);
8296
8297                 STRESS_LOG2(LF_CORDB, LL_INFO1000, "[%x] CP::SSFW32S: got event, %d\n", GetCurrentThreadId(), dwWaitResult);
8298
8299                 _ASSERTE(dwWaitResult == WAIT_OBJECT_0);
8300             }
8301
8302             Lock();
8303
8304             m_specialDeferment = false;
8305
8306             if (pfAsyncBreakSent)
8307             {
8308                 *pfAsyncBreakSent = TRUE;
8309             }
8310
8311             // If the helper thread died while we were trying to send an event to it, then we just do the same odd sync
8312             // logic we do above.
8313             if (m_helperThreadDead)
8314             {
8315                 SetSynchronized(true);
8316                 m_oddSync = true;
8317                 hr = S_OK;
8318             }
8319
8320             m_stopRequested = false;
8321             m_cordb->ProcessStateChanged();
8322         }
8323
8324         Unlock();
8325     }
8326 #endif // FEATURE_INTEROP_DEBUGGING
8327
8328     return hr;
8329 }
8330
8331 // Check if the left side has exited. If so, get the right-side
8332 // into shutdown mode. Only use this to avert us from going into
8333 // an unrecoverable error.
8334 bool CordbProcess::CheckIfLSExited()
8335 {
8336 // Check by waiting on the handle with no timeout.
8337     if (WaitForSingleObject(m_handle, 0) == WAIT_OBJECT_0)
8338     {
8339         Lock();
8340         m_terminated = true;
8341         m_exiting = true;
8342         Unlock();
8343     }
8344
8345     LOG((LF_CORDB, LL_INFO10, "CP::IsLSExited() returning '%s'\n",
8346         m_exiting ? "true" : "false"));
8347
8348     return m_exiting;
8349 }
8350
8351 // Call this if something really bad happened and we can't do
8352 // anything meaningful with the CordbProcess.
8353 void CordbProcess::UnrecoverableError(HRESULT errorHR,
8354                                       unsigned int errorCode,
8355                                       const char *errorFile,
8356                                       unsigned int errorLine)
8357 {
8358     LOG((LF_CORDB, LL_INFO10, "[%x] CP::UE: unrecoverable error 0x%08x "
8359          "(%d) %s:%d\n",
8360          GetCurrentThreadId(),
8361          errorHR, errorCode, errorFile, errorLine));
8362
8363     // We definitely want to know about any of these.
8364     STRESS_LOG3(LF_CORDB, LL_EVERYTHING, "Unrecoverable Error:0x%08x, File=%s, line=%d\n", errorHR, errorFile, errorLine);
8365
8366     // It's possible for an unrecoverable error to occur if the user detaches the
8367     // debugger while inside CordbProcess::DispatchRCEvent() (as that function deliberately
8368     // calls Unlock() while calling into the Shim).  Detect such cases here & bail before we
8369     // try to access invalid fields on this CordbProcess.
8370     // 
8371     // Normally, we'd need to take the cordb process lock around the IsNeutered check
8372     // (and the code that follows).  And perhaps this is a good thing to do in the
8373     // future.  But for now we're not for two reasons:
8374     // 
8375     // 1) It's scary.  We're in UnrecoverableError() for gosh sake.  I don't know all
8376     // the possible bad states we can be in to get here.  Will taking the process lock
8377     // have ordering issues?  Will the process lock even be valid to take here (or might
8378     // we AV)?  Since this is error handling, we should probably be as light as we can
8379     // not to cause more errors.
8380     // 
8381     // 2) It's unnecessary.  For the Watson dump I investigated that caused this fix in
8382     // the first place, we already detached before entering UnrecoverableError()
8383     // (indeed, the only reason we're in UnrecoverableError is that we already detached
8384     // and that caused a prior API to fail).  Thus, there's no timing issue (in that
8385     // case, anyway), wrt to entering UnrecoverableError() and detaching / neutering.
8386     if (IsNeutered())
8387         return;
8388
8389 #ifdef _DEBUG
8390     // Ping our error trapping logic
8391     HRESULT hrDummy;
8392     hrDummy = ErrWrapper(errorHR);
8393 #endif
8394
8395     if (m_pShim == NULL)
8396     {
8397         // @dbgtodo - , shim: Once everything is hoisted, we can remove
8398         // this code.
8399         // In the v3 case, we should never get an unrecoverable error. Instead, the HR should be propogated
8400         // and returned at the top-level public API. 
8401         _ASSERTE(!"Unrecoverable error dispatched in V3 case.");
8402     }
8403
8404     CONSISTENCY_CHECK_MSGF(IsLegalFatalError(errorHR), ("Unrecoverable internal error: hr=0x%08x!", errorHR));
8405
8406     if (!IsLegalFatalError(errorHR) || (errorHR != CORDBG_E_CANNOT_DEBUG_FIBER_PROCESS))
8407     {
8408         // This will throw everything into a Zombie state. The ATT_ macros will check this and fail immediately.
8409         m_unrecoverableError = true;
8410
8411         //
8412         // Mark the process as no longer synchronized.
8413         //
8414         Lock();
8415         SetSynchronized(false);
8416         IncStopCount();
8417         Unlock();
8418     }
8419
8420     // Set the error flags in the process so that if parts of it are
8421     // still alive, it will realize that its in this mode and do the
8422     // right thing.
8423     if (GetDCB() != NULL)
8424     {
8425         GetDCB()->m_errorHR = errorHR;
8426         GetDCB()->m_errorCode = errorCode;
8427         EX_TRY
8428         {
8429             UpdateLeftSideDCBField(&(GetDCB()->m_errorHR), sizeof(GetDCB()->m_errorHR));
8430             UpdateLeftSideDCBField(&(GetDCB()->m_errorCode), sizeof(GetDCB()->m_errorCode));
8431         }
8432         EX_CATCH
8433         {
8434             _ASSERTE(!"Writing process memory failed, perhaps due to an unexpected disconnection from the target."); 
8435         }
8436         EX_END_CATCH(SwallowAllExceptions);
8437     }
8438
8439     //
8440     // Let the user know that we've hit an unrecoverable error.
8441     //
8442     if (m_cordb->m_managedCallback)
8443     {
8444         // We are about to send DebuggerError call back. The state of RS is undefined.
8445         // So we use the special Public Callback. We may be holding locks and stuff.
8446         // We may also be deeply nested within the RS.
8447         PUBLIC_CALLBACK_IN_THIS_SCOPE_DEBUGGERERROR(this);
8448         m_cordb->m_managedCallback->DebuggerError((ICorDebugProcess*) this,
8449                                                   errorHR,
8450                                                   errorCode);
8451     }
8452 }
8453
8454
8455 HRESULT CordbProcess::CheckForUnrecoverableError()
8456 {
8457     HRESULT hr = S_OK;
8458
8459     if (GetDCB() != NULL) 
8460     {
8461         // be sure we have the latest information
8462         UpdateRightSideDCB();
8463
8464         if (GetDCB()->m_errorHR != S_OK)
8465         {
8466             UnrecoverableError(GetDCB()->m_errorHR,
8467                                GetDCB()->m_errorCode,
8468                            __FILE__, __LINE__);
8469
8470             hr = GetDCB()->m_errorHR;
8471         }
8472     }
8473
8474     return hr;
8475 }
8476
8477
8478 /*
8479  * EnableLogMessages enables/disables sending of log messages to the
8480  * debugger for logging.
8481  */
8482 HRESULT CordbProcess::EnableLogMessages(BOOL fOnOff)
8483 {
8484     PUBLIC_API_ENTRY(this);
8485     FAIL_IF_NEUTERED(this);
8486     ATT_REQUIRE_STOPPED_MAY_FAIL(this);
8487     HRESULT hr = S_OK;
8488
8489     DebuggerIPCEvent *event = (DebuggerIPCEvent*) _alloca(CorDBIPC_BUFFER_SIZE);
8490     InitIPCEvent(event, DB_IPCE_ENABLE_LOG_MESSAGES, false, VMPTR_AppDomain::NullPtr());
8491     event->LogSwitchSettingMessage.iLevel = (int)fOnOff;
8492
8493     hr = m_cordb->SendIPCEvent(this, event, CorDBIPC_BUFFER_SIZE);
8494     hr = WORST_HR(hr, event->hr);
8495
8496     LOG((LF_CORDB, LL_INFO10000, "[%x] CP::EnableLogMessages: EnableLogMessages=%d sent.\n",
8497          GetCurrentThreadId(), fOnOff));
8498
8499     return hr;
8500 }
8501
8502 /*
8503  * ModifyLogSwitch modifies the specified switch's severity level.
8504  */
8505 COM_METHOD CordbProcess::ModifyLogSwitch(__in_z WCHAR *pLogSwitchName, LONG lLevel)
8506 {
8507     PUBLIC_API_ENTRY(this);
8508     FAIL_IF_NEUTERED(this);
8509     ATT_REQUIRE_STOPPED_MAY_FAIL(this);
8510
8511     HRESULT hr = S_OK;
8512
8513     _ASSERTE (pLogSwitchName != NULL);
8514
8515     DebuggerIPCEvent *event = (DebuggerIPCEvent*) _alloca(CorDBIPC_BUFFER_SIZE);
8516     InitIPCEvent(event, DB_IPCE_MODIFY_LOGSWITCH, false, VMPTR_AppDomain::NullPtr());
8517     event->LogSwitchSettingMessage.iLevel = lLevel;
8518     event->LogSwitchSettingMessage.szSwitchName.SetStringTruncate(pLogSwitchName);
8519
8520     hr = m_cordb->SendIPCEvent(this, event, CorDBIPC_BUFFER_SIZE);
8521     hr = WORST_HR(hr, event->hr);
8522
8523     LOG((LF_CORDB, LL_INFO10000, "[%x] CP::ModifyLogSwitch: ModifyLogSwitch sent.\n",
8524          GetCurrentThreadId()));
8525
8526     return hr;
8527 }
8528
8529 //-----------------------------------------------------------------------------
8530 // Writes a buffer from the target and performs checks similar to SafeWriteStruct
8531 //
8532 // Arguments:
8533 //    tb - TargetBuffer which represents the target memory we want to write to
8534 //    pLocalBuffer - local pointer into source buffer
8535 //    cbSize - the size of local buffer
8536 //
8537 // Exceptions
8538 //    On error throws the result of WriteVirtual unless a short write is performed, 
8539 //    in which case throws ERROR_PARTIAL_COPY
8540 //
8541 void CordbProcess::SafeWriteBuffer(TargetBuffer tb, 
8542                                    const BYTE * pLocalBuffer) 
8543 {
8544     _ASSERTE(m_pMutableDataTarget != NULL);
8545     HRESULT hr = m_pMutableDataTarget->WriteVirtual(tb.pAddress,
8546         pLocalBuffer,
8547         tb.cbSize);
8548     IfFailThrow(hr);
8549 }
8550
8551 //-----------------------------------------------------------------------------
8552 // Reads a buffer from the target and performs checks similar to SafeWriteStruct
8553 //
8554 // Arguments:
8555 //    tb - TargetBuffer which represents the target memory to read from
8556 //    pLocalBuffer - local pointer into source buffer
8557 //    cbSize - the size of the remote buffer
8558 //    throwOnError - determines whether the function throws exceptions or returns HRESULTs
8559 //                   in failure cases
8560 //
8561 // Exceptions:
8562 //    If throwOnError is TRUE
8563 //      On error always throws the special CORDBG_E_READVIRTUAL_FAILURE, unless a short write is performed
8564 //      in which case throws ERROR_PARTIAL_COPY
8565 //   If throwOnError is FALSE
8566 //      No exceptions are thrown, and instead the same error codes are returned as HRESULTs
8567 //
8568 HRESULT CordbProcess::SafeReadBuffer(TargetBuffer tb, BYTE * pLocalBuffer, BOOL throwOnError)
8569 {
8570     ULONG32 cbRead;
8571     HRESULT hr = m_pDACDataTarget->ReadVirtual(tb.pAddress,
8572         pLocalBuffer,
8573         tb.cbSize, 
8574         &cbRead);
8575
8576     if (FAILED(hr)) 
8577     {
8578         if (throwOnError)
8579             ThrowHR(CORDBG_E_READVIRTUAL_FAILURE);
8580         else
8581             return CORDBG_E_READVIRTUAL_FAILURE;
8582     }
8583
8584     if (cbRead != tb.cbSize)
8585     {
8586         if (throwOnError)
8587             ThrowWin32(ERROR_PARTIAL_COPY);
8588         else
8589             return HRESULT_FROM_WIN32(ERROR_PARTIAL_COPY);
8590     }
8591     return S_OK;
8592 }
8593
8594
8595 //---------------------------------------------------------------------------------------
8596 // Lookup or create an appdomain.
8597 //
8598 // Arguments:
8599 //     vmAppDomain - CLR appdomain to lookup
8600 //
8601 // Returns:
8602 //     Instance of CordbAppDomain for the given appdomain. This is a cached instance. 
8603 //     If the CordbAppDomain does not yet exist, it will be created and added to the cache. 
8604 //     Never returns NULL. Throw on error.
8605 CordbAppDomain * CordbProcess::LookupOrCreateAppDomain(VMPTR_AppDomain vmAppDomain)
8606 {
8607     CordbAppDomain * pAppDomain = m_appDomains.GetBase(VmPtrToCookie(vmAppDomain));    
8608     if (pAppDomain != NULL)
8609     {
8610         return pAppDomain;
8611     }
8612     return CacheAppDomain(vmAppDomain);
8613 }
8614
8615 CordbAppDomain * CordbProcess::GetSharedAppDomain()
8616 {
8617     if (m_sharedAppDomain == NULL)
8618     {
8619         CordbAppDomain *pAD = new CordbAppDomain(this, VMPTR_AppDomain::NullPtr());
8620         if (InterlockedCompareExchangeT<CordbAppDomain*>(&m_sharedAppDomain, pAD, NULL) != NULL)
8621         {
8622             delete pAD;
8623         }
8624                 m_sharedAppDomain->InternalAddRef();
8625     }
8626     
8627     return m_sharedAppDomain;
8628 }
8629
8630 //---------------------------------------------------------------------------------------
8631 //
8632 // Add a new appdomain to the cache.
8633 //
8634 // Arguments:
8635 //      vmAppDomain - appdomain to add.
8636 //
8637 // Return Value:
8638 //    Pointer to newly created appdomain, which should be the normal case. 
8639 //    Throws on failure. Never returns null.
8640 //
8641 // Assumptions:
8642 //    Caller ensure the appdomain is not already cached.
8643 //    Caller should have stop-go lock, which provides thread-safety. 
8644 //
8645 // Notes:
8646 //    This sets unrecoverable error on failure.
8647 //
8648 //---------------------------------------------------------------------------------------
8649 CordbAppDomain * CordbProcess::CacheAppDomain(VMPTR_AppDomain vmAppDomain)
8650 {
8651     INTERNAL_API_ENTRY(GetProcess());
8652
8653     _ASSERTE(GetProcessLock()->HasLock());
8654
8655     RSInitHolder<CordbAppDomain> pAppDomain;
8656     pAppDomain.Assign(new CordbAppDomain(this, vmAppDomain));  // throws
8657   
8658     // Add to the hash. This will addref the pAppDomain. 
8659     // Caller ensures we're not already cached.
8660     // The cache will take ownership.
8661     m_appDomains.AddBaseOrThrow(pAppDomain);
8662
8663     // see if this is the default AppDomain
8664     IDacDbiInterface * pDac = m_pProcess->GetDAC();
8665     BOOL               fIsDefaultDomain = FALSE;
8666
8667     fIsDefaultDomain = pDac->IsDefaultDomain(vmAppDomain); // throws
8668
8669     if (fIsDefaultDomain)
8670     {
8671         // If this assert fires, then it likely means the target is corrupted.
8672         TargetConsistencyCheck(m_pDefaultAppDomain == NULL);
8673         m_pDefaultAppDomain = pAppDomain;
8674     }
8675
8676     CordbAppDomain * pReturn = pAppDomain;
8677     pAppDomain.ClearAndMarkDontNeuter();
8678
8679     _ASSERTE(pReturn != NULL);
8680     return pReturn;
8681 }
8682
8683 //---------------------------------------------------------------------------------------
8684 //
8685 // Callback for Appdomain enumeration.
8686 //
8687 // Arguments:
8688 //      vmAppDomain - new appdomain to add to enumeration
8689 //      pUserData - data passed with callback (a 'this' ptr for CordbProcess)
8690 //
8691 //
8692 // Assumptions:
8693 //    Invoked as callback from code:CordbProcess::PrepopulateAppDomains 
8694 //
8695 //
8696 //---------------------------------------------------------------------------------------
8697
8698 // static
8699 void CordbProcess::AppDomainEnumerationCallback(VMPTR_AppDomain vmAppDomain, void * pUserData)
8700 {
8701     CONTRACTL
8702     {
8703         THROWS;
8704     }
8705     CONTRACTL_END;
8706
8707     CordbProcess * pProcess = static_cast<CordbProcess *> (pUserData);
8708     INTERNAL_DAC_CALLBACK(pProcess);
8709
8710     pProcess->LookupOrCreateAppDomain(vmAppDomain);
8711 }
8712
8713 //---------------------------------------------------------------------------------------
8714 //
8715 // Traverse appdomains in the target and build up our list.
8716 //
8717 // Arguments:
8718 //
8719 // Return Value:
8720 //    returns on success.
8721 //    Throws on error. AppDomain cache may be partially populated.
8722 //
8723 // Assumptions:
8724 //    This is an non-invasive inspection operation called when the debuggee is stopped.
8725 //
8726 // Notes:
8727 //    This can be called multiple times. If the list is non-empty, it will nop.
8728 //---------------------------------------------------------------------------------------
8729 void CordbProcess::PrepopulateAppDomainsOrThrow()
8730 {
8731     CONTRACTL
8732     {
8733         THROWS;
8734     }
8735     CONTRACTL_END;
8736
8737     INTERNAL_API_ENTRY(this);
8738     
8739     if (!IsDacInitialized()) 
8740     {
8741         return;
8742     }
8743
8744     // DD-primitive  that invokes a callback.  This may throw.
8745     GetDAC()->EnumerateAppDomains(
8746         CordbProcess::AppDomainEnumerationCallback,
8747         this);
8748 }
8749
8750 //---------------------------------------------------------------------------------------
8751 //
8752 // EnumerateAppDomains enumerates all app domains in the process.
8753 //
8754 // Arguments:
8755 //      ppAppDomains - get appdomain enumerator
8756 //
8757 // Return Value:
8758 //    S_OK on success.
8759 //
8760 // Assumptions:
8761 //    
8762 //
8763 // Notes:
8764 //    This operation is non-invasive target.
8765 //
8766 //---------------------------------------------------------------------------------------
8767 HRESULT CordbProcess::EnumerateAppDomains(ICorDebugAppDomainEnum **ppAppDomains)
8768 {
8769     HRESULT hr = S_OK;
8770     PUBLIC_API_BEGIN(this);
8771     {
8772         ValidateOrThrow(ppAppDomains);
8773
8774         // Ensure list is populated.
8775         PrepopulateAppDomainsOrThrow(); 
8776         
8777         RSInitHolder<CordbHashTableEnum> pEnum;
8778         CordbHashTableEnum::BuildOrThrow(
8779             this, 
8780             GetContinueNeuterList(), 
8781             &m_appDomains,
8782             IID_ICorDebugAppDomainEnum,
8783             pEnum.GetAddr());
8784         
8785         *ppAppDomains = static_cast<ICorDebugAppDomainEnum*> (pEnum);
8786         pEnum->ExternalAddRef();
8787
8788         pEnum.ClearAndMarkDontNeuter();
8789     }
8790     PUBLIC_API_END(hr);
8791     return hr;
8792 }
8793
8794 /*
8795  * GetObject returns the runtime process object.
8796  * Note: This method is not yet implemented.
8797  */
8798 HRESULT CordbProcess::GetObject(ICorDebugValue **ppObject)
8799 {
8800     PUBLIC_API_ENTRY(this);
8801     FAIL_IF_NEUTERED(this);
8802     VALIDATE_POINTER_TO_OBJECT(ppObject, ICorDebugObjectValue **);
8803
8804     return E_NOTIMPL;
8805 }
8806
8807
8808 //---------------------------------------------------------------------------------------
8809 //
8810 // Given a taskid, finding the corresponding thread. The function can fail if we do not 
8811 // find any thread with the given taskid
8812 //
8813 // Arguments:
8814 //     taskId - The task ID to look for.
8815 //     ppThread - OUT: Space for storing the thread corresponding to the taskId given.
8816 //
8817 // Return Value:
8818 //     Typical HRESULT symantics, nothing abnormal.
8819 //
8820 HRESULT CordbProcess::GetThreadForTaskID(TASKID taskId, ICorDebugThread2 ** ppThread)
8821 {
8822     PUBLIC_API_ENTRY(this);
8823     FAIL_IF_NEUTERED(this);
8824     ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
8825
8826     HRESULT hr = S_OK;
8827
8828     EX_TRY
8829     {
8830         RSLockHolder lockHolder(GetProcessLock());
8831
8832         if (ppThread == NULL)
8833         {
8834             ThrowHR(E_INVALIDARG);
8835         }
8836
8837         // On initialization, the task ID of every thread is INVALID_TASK_ID, unless a host is present and 
8838         // the host calls IClrTask::SetTaskIdentifier().  So we need to explicitly check for INVALID_TASK_ID
8839         // here and return NULL if necessary.  We return S_FALSE because that's the return value for the case
8840         // where we can't find a thread for the specified task ID.
8841         if (taskId == INVALID_TASK_ID)
8842         {
8843             *ppThread = NULL;
8844             hr = S_FALSE;
8845         }
8846         else
8847         {
8848             PrepopulateThreadsOrThrow();
8849             
8850             // now find the ICorDebugThread corresponding to it
8851             CordbThread * pThread;
8852             HASHFIND hashFind;
8853
8854             
8855             for (pThread  = m_userThreads.FindFirst(&hashFind);
8856                  pThread != NULL;
8857                  pThread  = m_userThreads.FindNext(&hashFind))
8858             {
8859                 if (pThread->GetTaskID() == taskId)
8860                 {
8861                     break;
8862                 }
8863             }    
8864
8865             if (pThread == NULL)
8866             {
8867                 *ppThread = NULL;
8868                 hr = S_FALSE;
8869             }
8870             else
8871             {
8872                 *ppThread = pThread;
8873                 pThread->ExternalAddRef();
8874             }
8875         }
8876     }
8877     EX_CATCH_HRESULT(hr);
8878     return hr;
8879 }   // CordbProcess::GetThreadForTaskid
8880
8881 HRESULT
8882 CordbProcess::GetVersion(COR_VERSION* pVersion)
8883 {
8884     if (NULL == pVersion)
8885     {
8886         return E_INVALIDARG;
8887     }
8888
8889     //
8890     // Because we require a matching version of mscordbi.dll to debug a certain version of the runtime,
8891     // we can just use constants found in this particular mscordbi.dll to determine the version of the left side.
8892     pVersion->dwMajor = VER_MAJORVERSION;
8893     pVersion->dwMinor = VER_MINORVERSION;
8894     pVersion->dwBuild = VER_PRODUCTBUILD;
8895     pVersion->dwSubBuild = VER_PRODUCTBUILD_QFE;
8896
8897     return S_OK;
8898 }
8899
8900 #ifdef FEATURE_INTEROP_DEBUGGING
8901 //-----------------------------------------------------------------------------
8902 // Search for a native patch given the address. Return null if not found.
8903 // Since we return an address, this is only valid until the table is disturbed.
8904 //-----------------------------------------------------------------------------
8905 NativePatch * CordbProcess::GetNativePatch(const void * pAddress)
8906 {
8907     _ASSERTE(ThreadHoldsProcessLock());
8908     
8909     int cTotal = m_NativePatchList.Count();
8910     NativePatch * pTable = m_NativePatchList.Table();
8911     if (pTable == NULL)
8912     {
8913         return NULL;
8914     }
8915
8916     for(int i = 0; i  < cTotal; i++)
8917     {
8918         if (pTable[i].pAddress == pAddress)
8919         {
8920             return &pTable[i];
8921         }
8922     }
8923     return NULL;
8924 }
8925
8926 //-----------------------------------------------------------------------------
8927 // Is there an break-opcode (int3 on x86) at the address in the debuggee?
8928 //-----------------------------------------------------------------------------
8929 bool CordbProcess::IsBreakOpcodeAtAddress(const void * address)
8930 {
8931     // There should have been an int3 there already. Since we already put it in there,
8932     // we should be able to safely read it out.
8933     BYTE opcodeTest = 0;
8934
8935     HRESULT hr = SafeReadStruct(PTR_TO_CORDB_ADDRESS(address), &opcodeTest);
8936     SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr); 
8937     
8938     return (opcodeTest == CORDbg_BREAK_INSTRUCTION);
8939 }
8940 #endif // FEATURE_INTEROP_DEBUGGING
8941
8942 //-----------------------------------------------------------------------------
8943 // CordbProcess::SetUnmanagedBreakpoint
8944 // Called by a native debugger to add breakpoints during Interop.
8945 // address - remote address into the debuggee
8946 // bufsize, buffer[] - initial size & buffer for the opcode that we're replacing.
8947 // buflen - size of the buffer that we write to.
8948 //-----------------------------------------------------------------------------
8949 HRESULT
8950 CordbProcess::SetUnmanagedBreakpoint(CORDB_ADDRESS address, ULONG32 bufsize, BYTE buffer[], ULONG32 * bufLen)
8951 {
8952     LOG((LF_CORDB, LL_INFO100, "CP::SetUnBP: pProcess=%x, address=%p.\n", this, CORDB_ADDRESS_TO_PTR(address)));
8953 #ifndef FEATURE_INTEROP_DEBUGGING
8954     return E_NOTIMPL;
8955 #else
8956     PUBLIC_API_ENTRY(this);
8957     FAIL_IF_NEUTERED(this);
8958     FAIL_IF_MANAGED_ONLY(this);
8959     _ASSERTE(!ThreadHoldsProcessLock());
8960     Lock();
8961     HRESULT hr = SetUnmanagedBreakpointInternal(address, bufsize, buffer, bufLen);
8962     Unlock();
8963     return hr;
8964 #endif
8965 }
8966
8967 //-----------------------------------------------------------------------------
8968 // CordbProcess::SetUnmanagedBreakpointInternal
8969 // The worker behind SetUnmanagedBreakpoint, this function can set both public
8970 // breakpoints used by the debugger and internal breakpoints used for utility
8971 // purposes in interop debugging.
8972 // address - remote address into the debuggee
8973 // bufsize, buffer[] - initial size & buffer for the opcode that we're replacing.
8974 // buflen - size of the buffer that we write to.
8975 //-----------------------------------------------------------------------------
8976 HRESULT
8977 CordbProcess::SetUnmanagedBreakpointInternal(CORDB_ADDRESS address, ULONG32 bufsize, BYTE buffer[], ULONG32 * bufLen)
8978 {
8979     LOG((LF_CORDB, LL_INFO100, "CP::SetUnBPI: pProcess=%x, address=%p.\n", this, CORDB_ADDRESS_TO_PTR(address)));
8980 #ifndef FEATURE_INTEROP_DEBUGGING
8981     return E_NOTIMPL;
8982 #else
8983
8984     INTERNAL_API_ENTRY(this);
8985     FAIL_IF_NEUTERED(this);
8986     FAIL_IF_MANAGED_ONLY(this);
8987     _ASSERTE(ThreadHoldsProcessLock());
8988
8989     HRESULT hr = S_OK;
8990
8991     NativePatch * p = NULL;
8992 #if defined(DBG_TARGET_X86) || defined(DBG_TARGET_AMD64)
8993     const BYTE patch = CORDbg_BREAK_INSTRUCTION;
8994     BYTE opcode;
8995
8996     // Make sure args are good
8997     if ((buffer == NULL) || (bufsize < sizeof(patch)) || (bufLen == NULL))
8998     {
8999         hr = E_INVALIDARG;
9000         goto ErrExit;
9001     }
9002
9003     // Fail if there's already a patch at this address.
9004     if (GetNativePatch(CORDB_ADDRESS_TO_PTR(address)) != NULL)
9005     {
9006         hr = CORDBG_E_NATIVE_PATCH_ALREADY_AT_ADDR;
9007         goto ErrExit;
9008     }
9009
9010     // Preallocate this now so that if are oom, we can fail before we get half-way through.
9011     p = m_NativePatchList.Append();
9012     if (p == NULL)
9013     {
9014         hr = E_OUTOFMEMORY;
9015         goto ErrExit;
9016     }
9017
9018
9019     // Read out opcode. 1 byte on x86
9020
9021     hr = ApplyRemotePatch(this, CORDB_ADDRESS_TO_PTR(address), &p->opcode);
9022     if (FAILED(hr))
9023         goto ErrExit;
9024
9025     // It's all successful, so now update our out-params & internal bookkeaping.
9026     opcode = (BYTE) p->opcode;
9027     buffer[0] = opcode;
9028     *bufLen = sizeof(opcode);
9029
9030     p->pAddress = CORDB_ADDRESS_TO_PTR(address);
9031     p->opcode = opcode;
9032
9033     _ASSERTE(SUCCEEDED(hr));
9034 #elif defined(DBG_TARGET_WIN64)
9035     PORTABILITY_ASSERT("NYI: CordbProcess::SetUnmanagedBreakpoint, interop debugging NYI on this platform");
9036     hr =  E_NOTIMPL;
9037     goto ErrExit;
9038 #else
9039     hr =  E_NOTIMPL;
9040     goto ErrExit;
9041 #endif // DBG_TARGET_X8_
9042
9043
9044 ErrExit:
9045     // If we failed, then free the patch
9046     if (FAILED(hr) && (p != NULL))
9047     {
9048         m_NativePatchList.Delete(*p);
9049     }
9050
9051     return hr;
9052
9053 #endif // FEATURE_INTEROP_DEBUGGING
9054 }
9055
9056
9057 //-----------------------------------------------------------------------------
9058 // CordbProcess::ClearUnmanagedBreakpoint
9059 // Called by a native debugger to remove breakpoints during Interop.
9060 // The patch is deleted even if the function fails.
9061 //-----------------------------------------------------------------------------
9062 HRESULT
9063 CordbProcess::ClearUnmanagedBreakpoint(CORDB_ADDRESS address)
9064 {
9065     LOG((LF_CORDB, LL_INFO100, "CP::ClearUnBP: pProcess=%x, address=%p.\n", this, CORDB_ADDRESS_TO_PTR(address)));
9066 #ifndef FEATURE_INTEROP_DEBUGGING
9067     return E_NOTIMPL;
9068 #else
9069     PUBLIC_API_ENTRY(this);
9070     FAIL_IF_NEUTERED(this);
9071     FAIL_IF_MANAGED_ONLY(this);
9072     
9073     _ASSERTE(!ThreadHoldsProcessLock());
9074
9075     HRESULT hr = S_OK;
9076     PRD_TYPE opcode;
9077
9078     Lock();
9079
9080     // Make sure this is a valid patch.
9081     int cTotal = m_NativePatchList.Count();
9082     NativePatch * pTable = m_NativePatchList.Table();
9083     if (pTable == NULL)
9084     {
9085         hr = CORDBG_E_NO_NATIVE_PATCH_AT_ADDR;
9086         goto ErrExit;
9087     }
9088
9089     int i;
9090     for(i = 0; i  < cTotal; i++)
9091     {
9092         if (pTable[i].pAddress == CORDB_ADDRESS_TO_PTR(address))
9093             break;
9094     }
9095
9096     if (i >= cTotal)
9097     {
9098         hr = CORDBG_E_NO_NATIVE_PATCH_AT_ADDR;
9099         goto ErrExit;
9100     }
9101
9102     // Found it! Remove it from our table. Note that this may shuffle table contents
9103     // around, so don't keep pointers into the table.
9104     opcode = pTable[i].opcode;
9105
9106     m_NativePatchList.Delete(pTable[i]);
9107     _ASSERTE(m_NativePatchList.Count() == cTotal - 1);
9108
9109     // Now remove the patch.
9110
9111
9112
9113     // Just call through to Write ProcessMemory
9114     hr = RemoveRemotePatch(this, CORDB_ADDRESS_TO_PTR(address), opcode);
9115     if (FAILED(hr))
9116         goto ErrExit;
9117
9118
9119     // Our internal bookeaping was already updated to remove the patch, so now we're done.
9120     // If we had a failure, we should have already bailed.
9121     _ASSERTE(SUCCEEDED(hr));
9122
9123 ErrExit:
9124     Unlock();
9125     return hr;
9126 #endif // FEATURE_INTEROP_DEBUGGING
9127 }
9128
9129
9130 //------------------------------------------------------------------------------------
9131 // StopCount, Sync, SyncReceived form our stop-status. This status is super-critical
9132 // to most hangs, so we stress log it.
9133 //------------------------------------------------------------------------------------
9134 void CordbProcess::SetSynchronized(bool fSynch)
9135 {
9136     _ASSERTE(ThreadHoldsProcessLock() || !"Must have process lock to toggle SyncStatus");
9137     STRESS_LOG1(LF_CORDB, LL_INFO1000, "CP:: set sync=%d\n", fSynch);
9138     m_synchronized = fSynch;
9139 }
9140
9141 bool CordbProcess::GetSynchronized()
9142 {
9143     // This can be accessed whether we're Locked or not. This means that the result
9144     // may change underneath us.
9145     return m_synchronized;
9146 }
9147
9148 void CordbProcess::IncStopCount()
9149 {
9150     _ASSERTE(ThreadHoldsProcessLock());
9151     m_stopCount++;
9152     STRESS_LOG1(LF_CORDB, LL_INFO1000, "CP:: Inc StopCount=%d\n", m_stopCount);
9153 }
9154 void CordbProcess::DecStopCount()
9155 {
9156     // We can inc w/ just the process lock (b/c we can dispatch events from the W32ET)
9157     // But decrementing (eg, Continue), requires the stop-go lock.
9158     // This if an operation takes the SG lock, it ensures we don't continue from underneath it.
9159     ASSERT_SINGLE_THREAD_ONLY(HoldsLock(&m_StopGoLock));
9160     _ASSERTE(ThreadHoldsProcessLock());
9161
9162     m_stopCount--;
9163     STRESS_LOG1(LF_CORDB, LL_INFO1000, "CP:: Dec StopCount=%d\n", m_stopCount);
9164 }
9165
9166 // Just gets whether we're stopped or not (m_stopped > 0).
9167 // You only need the StopGo lock for this.
9168 bool CordbProcess::IsStopped()
9169 {
9170     // We don't require the process-lock, just the SG-lock.
9171     // Holding the SG lock prevents another thread from continuing underneath you.
9172     // (see DecStopCount()).
9173     // But you could still be running free, and have another thread stop-underneath you.
9174     // Thus IsStopped() leans towards returning false.
9175     ASSERT_SINGLE_THREAD_ONLY(HoldsLock(&m_StopGoLock));
9176
9177     return (m_stopCount > 0);
9178 }
9179
9180 int CordbProcess::GetStopCount()
9181 {
9182     _ASSERTE(ThreadHoldsProcessLock());
9183     return m_stopCount;
9184 }
9185
9186 bool CordbProcess::GetSyncCompleteRecv()
9187 {
9188     _ASSERTE(ThreadHoldsProcessLock());
9189     return m_syncCompleteReceived;
9190 }
9191
9192 void CordbProcess::SetSyncCompleteRecv(bool fSyncRecv)
9193 {
9194     _ASSERTE(ThreadHoldsProcessLock());
9195     STRESS_LOG1(LF_CORDB, LL_INFO1000, "CP:: set syncRecv=%d\n", fSyncRecv);
9196     m_syncCompleteReceived = fSyncRecv;
9197 }
9198
9199 // This can be used if we ever need the RS to emulate old behavior of previous versions.
9200 // This can not be used in QIs to deny queries for new interfaces.
9201 // QIs must be consistent across the lifetime of an object. Say CordbThread used this in a QI 
9202 // do deny returning a ICorDebugThread2 interface when emulating v1.1. Once that Thread is neutered,
9203 // it no longer has a pointer to the process, and it no longer knows if it should be denying
9204 // the v2.0 query. An object's QI can't start returning new interfaces onces its neutered.
9205 bool CordbProcess::SupportsVersion(CorDebugInterfaceVersion featureVersion)
9206 {
9207     _ASSERTE(featureVersion == CorDebugVersion_2_0);
9208     return true;
9209 }
9210
9211
9212 //---------------------------------------------------------------------------------------
9213 // Add an object to the process's Left-Side resource cleanup list
9214 // 
9215 // Arguments:
9216 //    pObject - non-null object to be added
9217 //    
9218 // Notes:
9219 //    This list tracks objects with process-scope that hold left-side 
9220 //    resources (like func-eval).
9221 //    See code:CordbAppDomain::GetSweepableExitNeuterList for per-appdomain
9222 //    objects with left-side resources.
9223 void CordbProcess::AddToLeftSideResourceCleanupList(CordbBase * pObject)
9224 {
9225     INTERNAL_API_ENTRY(this);
9226     _ASSERTE(pObject != NULL);
9227     
9228     m_LeftSideResourceCleanupList.Add(this, pObject);
9229 }
9230
9231 // This list will get actively swept (looking for objects w/ external ref = 0) between continues.
9232 void CordbProcess::AddToNeuterOnExitList(CordbBase *pObject)
9233 {
9234     INTERNAL_API_ENTRY(this);
9235     _ASSERTE(pObject != NULL);
9236     
9237     HRESULT hr = S_OK;
9238     EX_TRY
9239     {
9240         this->m_ExitNeuterList.Add(this, pObject);
9241     } 
9242     EX_CATCH_HRESULT(hr);
9243     SetUnrecoverableIfFailed(GetProcess(), hr);
9244 }
9245
9246 // Mark that this object should be neutered the next time we Continue the process.
9247 void CordbProcess::AddToNeuterOnContinueList(CordbBase *pObject)
9248 {
9249     INTERNAL_API_ENTRY(this);
9250     _ASSERTE(pObject != NULL);
9251
9252     m_ContinueNeuterList.Add(this, pObject); // throws 
9253 }
9254
9255
9256 /* ------------------------------------------------------------------------- *
9257  * Runtime Controller Event Thread class
9258  * ------------------------------------------------------------------------- */
9259
9260 //
9261 // Constructor
9262 //
9263 CordbRCEventThread::CordbRCEventThread(Cordb* cordb)
9264 {
9265     _ASSERTE(cordb != NULL);
9266
9267     m_cordb.Assign(cordb);
9268     m_thread = NULL;
9269     m_threadId = 0;
9270     m_run = TRUE;
9271     m_threadControlEvent = NULL;
9272     m_processStateChanged = FALSE;
9273
9274     g_pRSDebuggingInfo->m_RCET = this;
9275 }
9276
9277
9278 //
9279 // Destructor. Cleans up all of the open handles and such.
9280 // This expects that the thread has been stopped and has terminated
9281 // before being called.
9282 //
9283 CordbRCEventThread::~CordbRCEventThread()
9284 {
9285     if (m_threadControlEvent != NULL)
9286         CloseHandle(m_threadControlEvent);
9287
9288     if (m_thread != NULL)
9289         CloseHandle(m_thread);
9290
9291     g_pRSDebuggingInfo->m_RCET = NULL;
9292 }
9293
9294 //
9295 // Init sets up all the objects that the thread will need to run.
9296 //
9297 HRESULT CordbRCEventThread::Init()
9298 {
9299     if (m_cordb == NULL)
9300         return E_INVALIDARG;
9301
9302     m_threadControlEvent = WszCreateEvent(NULL, FALSE, FALSE, NULL);
9303
9304     if (m_threadControlEvent == NULL)
9305         return HRESULT_FROM_GetLastError();
9306
9307     return S_OK;
9308 }
9309
9310
9311 #if defined(FEATURE_INTEROP_DEBUGGING)
9312 //
9313 // Helper to duplicate a handle or thorw
9314 //
9315 // Arguments:
9316 //     pLocalHandle - handle to duplicate into the remote process
9317 //     pRemoteHandle - RemoteHandle structure in IPC block to hold the remote handle.
9318 // Return value:
9319 //     None. Throws on error.
9320 //
9321 void CordbProcess::DuplicateHandleToLocalProcess(HANDLE * pLocalHandle, RemoteHANDLE * pRemoteHandle)
9322 {
9323     _ASSERTE(m_pShim != NULL);
9324
9325     // Dup RSEA and RSER into this process if we don't already have them.
9326     // On Launch, we don't have them yet, but on attach we do.
9327     if (*pLocalHandle == NULL)
9328     {
9329         BOOL fSuccess = pRemoteHandle->DuplicateToLocalProcess(m_handle, pLocalHandle);
9330         if (!fSuccess)
9331         {            
9332             ThrowLastError();
9333         }
9334     }
9335
9336 }
9337 #endif // FEATURE_INTEROP_DEBUGGING
9338
9339 // Public entry wrapper for code:CordbProcess::FinishInitializeIPCChannelWorker
9340 void CordbProcess::FinishInitializeIPCChannel()
9341 {
9342     // This is called directly from a shim callback.
9343     PUBLIC_API_ENTRY_FOR_SHIM(this);
9344     FinishInitializeIPCChannelWorker();
9345 }
9346
9347 //
9348 // Initialize the IPC channel. After this, IPC events can flow in both ways.
9349 //
9350 // Return value:
9351 //     Returns S_OK on success.
9352 //
9353 // Notes:
9354 //     This will dispatch an UnrecoverableError callback if it fails.
9355 //     This will also initialize key state in the CordbProcess object.
9356 //
9357 // @dbgtodo remove helper-thread: this should eventually go away once we get rid of IPC events.
9358 //
9359 void CordbProcess::FinishInitializeIPCChannelWorker()
9360 {
9361     CONTRACTL
9362     {
9363         THROWS;
9364     }
9365     CONTRACTL_END;
9366
9367     HRESULT hr = S_OK;
9368     _ASSERTE(m_pShim != NULL);
9369
9370     RSLockHolder lockHolder(&this->m_processMutex);
9371
9372     // If it's already initialized, then nothing left to do.
9373     // this protects us if this function is called multiple times.
9374     if (m_initialized)
9375     {
9376         _ASSERTE(GetDCB() != NULL);
9377         return;
9378     }
9379
9380     EX_TRY
9381     {
9382         LOG((LF_CORDB, LL_INFO1000, "[%x] RCET::HFRCE: first event..., process %p\n", GetCurrentThreadId(), this));
9383
9384         BOOL fBlockExists;
9385         GetEventBlock(&fBlockExists); // throws on error   
9386
9387         LOG((LF_CORDB, LL_EVERYTHING, "Size of CdbP is %d\n", sizeof(CordbProcess)));
9388
9389         m_pEventChannel->Init(m_handle);
9390
9391 #if defined(FEATURE_INTEROP_DEBUGGING)
9392         DuplicateHandleToLocalProcess(&m_leftSideUnmanagedWaitEvent, &GetDCB()->m_leftSideUnmanagedWaitEvent);
9393 #endif // FEATURE_INTEROP_DEBUGGING
9394         
9395         // Read the Runtime Offsets struct out of the debuggee.
9396         hr = GetRuntimeOffsets();
9397         IfFailThrow(hr);
9398
9399         // we need to be careful here. The LS will have a thread running free that may be initializing
9400         // fields of the DCB (specifically it may be setting up the helper thread), so we need to make sure
9401         // we don't overwrite any fields that the LS is writing. We need to be sure we only write to RS
9402         // status fields. 
9403         m_initialized = true;
9404         GetDCB()->m_rightSideIsWin32Debugger = IsInteropDebugging();
9405         UpdateLeftSideDCBField(&(GetDCB()->m_rightSideIsWin32Debugger), sizeof(GetDCB()->m_rightSideIsWin32Debugger));
9406             
9407         LOG((LF_CORDB, LL_INFO1000, "[%x] RCET::HFRCE: ...went fine\n", GetCurrentThreadId()));
9408         _ASSERTE(SUCCEEDED(hr));
9409
9410     } EX_CATCH_HRESULT(hr);
9411     if (SUCCEEDED(hr))
9412     {
9413         return;
9414     }
9415
9416     // We only land here on failure cases.
9417     // We must have jumped to this label. Maybe we didn't set HR, so check now.
9418     STRESS_LOG1(LF_CORDB, LL_INFO1000, "HFCR: FAILED hr=0x%08x\n", hr);
9419         
9420     CloseIPCHandles();
9421
9422     // Rethrow
9423     ThrowHR(hr);
9424 }
9425
9426
9427 //---------------------------------------------------------------------------------------
9428 // Marshals over a string buffer in a managed event
9429 //
9430 // Arguments:
9431 //    pTarget - data-target for read the buffer from the LeftSide.
9432 //
9433 // Throws on error
9434 void Ls_Rs_BaseBuffer::CopyLSDataToRSWorker(ICorDebugDataTarget * pTarget)
9435 {
9436     // 
9437     const DWORD cbCacheSize = m_cbSize;
9438     
9439     // SHOULD not happen for more than once in well-behaved case.    
9440     if (m_pbRS != NULL)
9441     {
9442         SIMPLIFYING_ASSUMPTION(!"m_pbRS is non-null; is this a corrupted event?");
9443         ThrowHR(E_INVALIDARG);
9444     }
9445
9446     NewHolder<BYTE> pData(new BYTE[cbCacheSize]);
9447     
9448     ULONG32 cbRead;
9449     HRESULT hrRead = pTarget->ReadVirtual(PTR_TO_CORDB_ADDRESS(m_pbLS), pData, cbCacheSize , &cbRead);
9450
9451     if(FAILED(hrRead))
9452     {
9453         hrRead = CORDBG_E_READVIRTUAL_FAILURE;
9454     }
9455     
9456     if (SUCCEEDED(hrRead) && (cbCacheSize != cbRead))
9457     {
9458         hrRead = HRESULT_FROM_WIN32(ERROR_PARTIAL_COPY);
9459     }
9460     IfFailThrow(hrRead);
9461
9462     // Now do Transfer
9463     m_pbRS = pData;
9464     pData.SuppressRelease();   
9465 }
9466
9467 //---------------------------------------------------------------------------------------
9468 // Marshals over a Byte buffer in a managed event
9469 //
9470 // Arguments:
9471 //    pTarget - data-target for read the buffer from the LeftSide.
9472 //
9473 // Throws on error
9474 void Ls_Rs_ByteBuffer::CopyLSDataToRS(ICorDebugDataTarget * pTarget)
9475 {
9476     CopyLSDataToRSWorker(pTarget);
9477 }
9478
9479 //---------------------------------------------------------------------------------------
9480 // Marshals over a string buffer in a managed event
9481 //
9482 // Arguments:
9483 //    pTarget - data-target for read the buffer from the LeftSide.
9484 //
9485 // Throws on error
9486 void Ls_Rs_StringBuffer::CopyLSDataToRS(ICorDebugDataTarget * pTarget)
9487 {        
9488     CopyLSDataToRSWorker(pTarget);
9489     
9490     // Ensure we're a valid, well-formed string.
9491     // @dbgtodo - this should only happen in corrupted scenarios. Perhaps a better HR here?
9492     // - null terminated.
9493     // - no embedded nulls.
9494     
9495     const WCHAR * pString = GetString();
9496     SIZE_T dwExpectedLenWithNull = m_cbSize / sizeof(WCHAR);
9497     
9498     // Should at least have 1 character for the null-terminator.
9499     if (dwExpectedLenWithNull == 0)
9500     {        
9501         ThrowHR(CORDBG_E_TARGET_INCONSISTENT);
9502     }
9503
9504     // Ensure that there's a null where we expect it to be.
9505     if (pString[dwExpectedLenWithNull-1] != 0)
9506     {
9507         ThrowHR(CORDBG_E_TARGET_INCONSISTENT);
9508     }
9509
9510     // Now we know it's safe to call wcslen. The buffer is local, so we know the pages are there.
9511     // And we know there's a null capping the max length of the string.
9512     SIZE_T dwActualLenWithNull = wcslen(pString) + 1;
9513     if (dwActualLenWithNull != dwExpectedLenWithNull)
9514     {
9515         ThrowHR(CORDBG_E_TARGET_INCONSISTENT);
9516     }
9517 }
9518
9519 //---------------------------------------------------------------------------------------
9520 // Marshals the arguments in a managed-debug event.
9521 //
9522 // Arguments:
9523 //    pManagedEvent - (IN/OUT) debug event to marshal. Events are not usable in the host process
9524 //       until they are marshalled. This will marshal the event in-place, and may convert
9525 //       some target addresses to host addresses.
9526 //
9527 // Return Value:
9528 //    S_OK on success. Else Error.
9529 //
9530 // Assumptions:
9531 //    Target is currently stopped and inspectable.
9532 //    After the event is marshalled, it has resources that must be cleaned up 
9533 //    by calling code:DeleteIPCEventHelper.
9534 // 
9535 // Notes:
9536 //     Call a Copy function (CopyManagedEventFromTarget, CopyRCEventFromIPCBlock)to
9537 //     get the event to marshal.
9538 //     This will marshal args from the target into the host.
9539 //     The debug event is fixed size. But since the debuggee is stopped, this can copy 
9540 //     arbitrary-length buffers out of of the debuggee. 
9541 //
9542 //     This could be rolled into code:CordbProcess::RawDispatchEvent 
9543 //---------------------------------------------------------------------------------------
9544 void CordbProcess::MarshalManagedEvent(DebuggerIPCEvent * pManagedEvent)
9545 {
9546     CONTRACTL
9547     {
9548         THROWS;
9549
9550         // Event has already been copied, now we do some quick Marshalling.
9551         // Thsi should be a private local copy, and not the one in the IPC block or Target.
9552         PRECONDITION(CheckPointer(pManagedEvent));
9553     }
9554     CONTRACTL_END;
9555
9556     IfFailThrow(pManagedEvent->hr);
9557
9558     // This may throw part way through marshalling. But that's ok because
9559     // code:DeleteIPCEventHelper can cleanup a partially-marshalled event.
9560
9561     // Do a pre-processing on the event
9562     switch (pManagedEvent->type & DB_IPCE_TYPE_MASK)
9563     {
9564         case DB_IPCE_MDA_NOTIFICATION:
9565         {
9566             pManagedEvent->MDANotification.szName.CopyLSDataToRS(this->m_pDACDataTarget);
9567             pManagedEvent->MDANotification.szDescription.CopyLSDataToRS(this->m_pDACDataTarget);
9568             pManagedEvent->MDANotification.szXml.CopyLSDataToRS(this->m_pDACDataTarget);
9569             break;
9570         }
9571
9572         case DB_IPCE_FIRST_LOG_MESSAGE:
9573         {
9574             pManagedEvent->FirstLogMessage.szContent.CopyLSDataToRS(this->m_pDACDataTarget);
9575             break;
9576         }
9577
9578         default:
9579             break;
9580     }
9581
9582     
9583 }
9584
9585
9586 //---------------------------------------------------------------------------------------
9587 // Copy a managed debug event from the target process into this local process
9588 //
9589 // Arguments:
9590 //    pRecord - native-debug event serving as the envelope for the managed event.
9591 //    pLocalManagedEvent - (dst) required local buffer to hold managed event.
9592 //
9593 // Return Value:
9594 //    * True if the event belongs to this runtime. This is very useful when multiple CLRs are
9595 //    loaded into the target and all sending events wit the same exception code.
9596 //    * False if this does not belong to this instance of ICorDebug. (perhaps it's an event
9597 //    intended for another instance of the CLR in the target, or some rogue user code happening
9598 //    to use our exception code).  
9599 //    In either case, the event can still be cleaned up via code:DeleteIPCEventHelper.
9600 //
9601 //    Throws on error. In the error case, the contents of pLocalManagedEvent are undefined.
9602 //    They may have been partially copied from the target. The local managed event does not own 
9603 //    any resources until it's marshalled, so the buffer can be ignored if this function fails.
9604 //
9605 // Assumptions:
9606 //
9607 // Notes:
9608 //    The events are sent form the target via code:Debugger::SendRawEvent
9609 //    This just does a raw Byte copy, but does not do any Marshalling. 
9610 //    This should always succeed in the well-behaved case. However, A bad debuggee can 
9611 //    always send a poor-formed debug event.
9612 //    We don't distinguish between a badly formed event and an event that's not ours.
9613 //    The event still needs to be Marshaled before being used. (see code:CordbProcess::MarshalManagedEvent)
9614 //
9615 //---------------------------------------------------------------------------------------
9616 #if defined(_MSC_VER) && defined(_TARGET_ARM_) 
9617 // This is a temporary workaround for an ARM specific MS C++ compiler bug (internal LKG build 18.1).
9618 // Branch < if (ptrRemoteManagedEvent == NULL) > was always taken and the function always returned false.
9619 // TODO: It should be removed once the bug is fixed.
9620 #pragma optimize("", off)
9621 #endif
9622 bool CordbProcess::CopyManagedEventFromTarget(
9623     const EXCEPTION_RECORD * pRecord, 
9624     DebuggerIPCEvent * pLocalManagedEvent)
9625 {
9626     _ASSERTE(pRecord != NULL);
9627     _ASSERTE(pLocalManagedEvent != NULL);
9628     
9629     // Initialize the event enough such backout code can call code:DeleteIPCEventHelper.
9630     pLocalManagedEvent->type = DB_IPCE_DEBUGGER_INVALID;
9631
9632     // Ensure we have a CLR instance ID by now.  Either we had one already, or we're in
9633     // V2 mode and this is the startup event, and so we'll set it now.
9634     HRESULT hr = EnsureClrInstanceIdSet();
9635     IfFailThrow(hr);
9636     _ASSERTE(m_clrInstanceId != 0);
9637
9638     // Determine if the event is really a debug event, and for our instance.
9639     CORDB_ADDRESS ptrRemoteManagedEvent = IsEventDebuggerNotification(pRecord, m_clrInstanceId);
9640
9641     if (ptrRemoteManagedEvent == NULL)
9642     {
9643         return false;
9644     }
9645
9646     // What we are doing on Windows here is dangerous.  Any buffer for IPC events must be at least
9647     // CorDBIPC_BUFFER_SIZE big, but here we are only copying sizeof(DebuggerIPCEvent).  Fortunately, the
9648     // only case where an IPC event is bigger than sizeof(DebuggerIPCEvent) is for the second category
9649     // described in the comment for code:IEventChannel.  In this case, we are just transferring the IPC
9650     // event from the native pipeline to the event channel, and the event channel will read it directly from
9651     // the send buffer on the LS.  See code:CordbRCEventThread::WaitForIPCEventFromProcess.
9652 #if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
9653     hr = SafeReadStruct(ptrRemoteManagedEvent, pLocalManagedEvent);
9654 #else
9655     // For Mac remote debugging the address returned above is actually a local address.
9656     // Also, we need to copy the entire buffer because once a debug event is read from the debugger
9657     // transport, it won't be available afterwards.
9658     memcpy(reinterpret_cast<BYTE *>(pLocalManagedEvent), 
9659            CORDB_ADDRESS_TO_PTR(ptrRemoteManagedEvent), 
9660            CorDBIPC_BUFFER_SIZE);
9661     hr = S_OK;
9662 #endif 
9663     SIMPLIFYING_ASSUMPTION(SUCCEEDED(hr)); 
9664     IfFailThrow(hr);
9665
9666     return true;
9667 }
9668 #if defined(_MSC_VER) && defined(_TARGET_ARM_) 
9669 #pragma optimize("", on)
9670 #endif
9671
9672 //---------------------------------------------------------------------------------------
9673 // EnsureClrInstanceIdSet - Ensure we have a CLR Instance ID to debug
9674 // 
9675 // In Arrowhead scenarios, the debugger is required to pass a valid CLR instance ID
9676 // to us in OpenVirtualProcess.  In V2 scenarios, for compatibility, we'll allow a 
9677 // CordbProcess object to exist for a process that doesn't yet have the CLR loaded.
9678 // In this case the CLR instance ID will start off as 0, but be filled in when we see the
9679 // startup exception indicating the CLR has been loaded.
9680 //
9681 // If we don't already have an instance ID, this function sets it to the only CLR in the
9682 // target process.  This requires that a CLR be loaded in the target process.
9683 // 
9684 // Return Value:
9685 //    S_OK - if m_clrInstanceId was already set, or is now set to a valid CLR instance ID
9686 //    an error HRESULT - if m_clrInstanceId was 0, and cannot be set to a valid value 
9687 //                       (i.e. because we cannot find a CLR in the target process).
9688 //    
9689 //    Note that we need to probe for this on attach, and it's common to attach before the 
9690 //    CLR has been loaded, so we avoid using exceptions for this common case.
9691 //    
9692 HRESULT CordbProcess::EnsureClrInstanceIdSet()
9693 {
9694     // If we didn't expect a specific CLR, then attempt to attach to any.
9695     if (m_clrInstanceId == 0)
9696     {
9697
9698 #ifdef FEATURE_CORESYSTEM
9699         if(m_cordb->GetTargetCLR() != 0)
9700         {
9701             m_clrInstanceId = PTR_TO_CORDB_ADDRESS(m_cordb->GetTargetCLR());
9702             return S_OK;
9703         }
9704 #endif
9705
9706         // The only case in which we're allowed to request the "default" CLR instance
9707         // ID is when we're running in V2 mode.  In V3, the client is required to pass
9708         // a non-zero value to OpenVirtualProcess.
9709         _ASSERTE(m_pShim != NULL);
9710
9711         HRESULT hr = m_pShim->FindLoadedCLR(&m_clrInstanceId);
9712         if (FAILED(hr))
9713         {
9714             // Couldn't find a loaded clr - no CLR instance ID yet
9715             _ASSERTE(m_clrInstanceId == 0);
9716             return hr;
9717         }
9718     }    
9719
9720     // We've (now) got a valid CLR instance id
9721     return S_OK;
9722 }
9723
9724 //---------------------------------------------------------------------------------------
9725 // // Copy event from IPC block into local.
9726 //
9727 // Arguments:
9728 //    pLocalManagedEvent - required local buffer to hold managed event.
9729 //
9730 // Return Value:
9731 //    None. Always succeeds.
9732 //
9733 // Assumptions:
9734 //    The IPC block has already been opened and filled in with an event.
9735 //
9736 // Notes:
9737 //    This is copying from a shared-memory block, which is treated as local memory.
9738 //    This just does a raw Byte copy, but does not do any Marshalling. 
9739 //    This does no validation on the event.
9740 //    The event still needs to be Marshaled before being used. (see code:CordbProcess::MarshalManagedEvent)
9741 //
9742 //---------------------------------------------------------------------------------------
9743 void inline CordbProcess::CopyRCEventFromIPCBlock(DebuggerIPCEvent * pLocalManagedEvent)
9744 {
9745     _ASSERTE(pLocalManagedEvent != NULL);
9746
9747     IfFailThrow(m_pEventChannel->GetEventFromLeftSide(pLocalManagedEvent));
9748 }
9749
9750 // Return true if this is the RCEvent thread, else false.
9751 bool CordbRCEventThread::IsRCEventThread()
9752 {
9753     return (m_threadId == GetCurrentThreadId());
9754 }
9755
9756 //---------------------------------------------------------------------------------------
9757 // Runtime assert, throws CORDBG_E_TARGET_INCONSISTENT if the expression is not true.
9758 // 
9759 // Arguments:
9760 //     fExpression - assert parameter. If true, this function is a nop. If false, 
9761 //             this will throw a CORDBG_E_TARGET_INCONSISTENT error.
9762 //
9763 // Notes:
9764 //     Use this for runtime checks to validate assumptions about the data-target.
9765 //     IcorDebug can't trust that data from the debugee is consistent (perhaps it's
9766 //     corrupted).
9767 void CordbProcess::TargetConsistencyCheck(bool fExpression)
9768 {
9769     if (!fExpression)
9770     {        
9771         STRESS_LOG0(LF_CORDB, LL_INFO10000, "Target consistency check failed");
9772
9773         // When debugging possibly corrupt targets, this failure may be expected.  For debugging purposes,
9774         // assert if we're not expecting any target inconsistencies.
9775         CONSISTENCY_CHECK_MSG( !m_fAssertOnTargetInconsistency, "Target consistency check failed unexpectedly");
9776
9777         ThrowHR(CORDBG_E_TARGET_INCONSISTENT);
9778     }
9779 }
9780
9781 //
9782 // SendIPCEvent -- send an IPC event to the runtime controller. All this
9783 // really does is copy the event into the process's send buffer and sets
9784 // the RSEA then waits on RSER.
9785 //
9786 // Note: when sending a two-way event (replyRequired = true), the
9787 // eventSize must be large enough for both the event sent and the
9788 // result event.
9789 //
9790 // Returns whether the event was sent successfully. This is different than event->eventHr.
9791 //
9792 HRESULT CordbRCEventThread::SendIPCEvent(CordbProcess* process,
9793                                          DebuggerIPCEvent* event,
9794                                          SIZE_T eventSize)
9795 {
9796
9797     _ASSERTE(process != NULL);
9798     _ASSERTE(event != NULL);
9799     _ASSERTE(process->GetShim() != NULL);
9800
9801 #ifdef _DEBUG
9802     // We need to be synchronized whenever we're sending an IPC Event.
9803     // This may require our callers' using a Stop-Continue holder.
9804     // Attach + AsyncBreak are the only (obvious) exceptions.
9805     // For continue, we set Sync-Status to false before sending, so we exclude that too.
9806     // Everybody else should only be sending events when synced. We should never ever ever
9807     // send an event from a CorbXYZ dtor (b/c that would be called at any random time). Instead,
9808     // use a NeuterList.
9809     switch (event->type)
9810     {
9811         case DB_IPCE_ATTACHING:
9812         case DB_IPCE_ASYNC_BREAK:
9813         case DB_IPCE_CONTINUE:
9814             break;
9815
9816         default:
9817             CONSISTENCY_CHECK_MSGF(process->GetSynchronized(), ("Must by synced while sending IPC event: %s (0x%x)",
9818                 IPCENames::GetName(event->type), event->type));
9819     }
9820 #endif
9821
9822
9823     LOG((LF_CORDB, LL_EVERYTHING, "SendIPCEvent in CordbRCEventThread called\n"));
9824
9825     // For simplicity sake, we have the following conservative invariants when sending IPC events:
9826     // - Always hold the Stop-Go lock.
9827     // - never on the W32ET.
9828     // - Never hold the Process-lock (this allows the w32et to take that lock to pump)
9829
9830     // Must have the stop-go lock to send an IPC event.
9831     CONSISTENCY_CHECK_MSGF(process->GetStopGoLock()->HasLock(), ("Must have stop-go lock to send event. proc=%p, event=%s",
9832         process, IPCENames::GetName(event->type)));
9833
9834     // The w32 ET will need to take the process lock. So if we're holding it here, then we'll
9835     // deadlock (since W32 ET is blocked on lock, which we would hold; and we're blocked on W32 ET
9836     // to keep pumping.
9837     _ASSERTE(!process->ThreadHoldsProcessLock() || !"Can't hold P-lock while sending blocking IPC event");
9838
9839
9840     // Can't be on the w32 ET, or we can't be pumping.
9841     // Although we can trickle in here from public APIs, our caller should have validated
9842     // that we weren't on the w32et, so the assert here is justified. But just in case there's something we missed,
9843     // we have a runtime check (as a final backstop against a deadlock).
9844     _ASSERTE(!process->IsWin32EventThread());
9845     CORDBFailIfOnWin32EventThread(process);
9846
9847
9848     // If this is an async event, then we expect it to be sent while the process is locked.
9849     if (event->asyncSend)
9850     {
9851         // This may be on the w32et, so we can't hold the stop-go lock.
9852         _ASSERTE(event->type == DB_IPCE_ATTACHING); // only async event should be attaching.
9853     }
9854
9855
9856     // This will catch us if we've detached or exited.
9857     // Note if we exited, then we should have been neutered and so shouldn't even be sending an IPC event,
9858     // but just in case, we'll check.
9859     CORDBRequireProcessStateOK(process);
9860
9861
9862 #ifdef _DEBUG
9863     // We should never send an Async Break on the RCET. This will deadlock.
9864     // - if we're on the RCET, we should be stopped, and thus Stop() should just bump up a stop count,
9865     //   and not actually send an AsyncBreak.
9866     // - Delayed-Continues help enforce this.
9867     // This is a special case of the deadlock check below.
9868     if (IsRCEventThread())
9869     {
9870         _ASSERTE(event->type != DB_IPCE_ASYNC_BREAK);
9871     }
9872 #endif
9873
9874 #ifdef _DEBUG
9875     // This assert protects us against a deadlock.
9876     // 1) (RCET) blocked on (This function): If we're on the RCET, then the RCET is blocked until we return (duh).
9877     // 2) (LS) blocked on (RCET): If the LS is not synchronized, then it may be sending an event to the RCET, and thus blocked on the RCET.
9878     // 3) (Helper thread) blocked on (LS): That LS thread may be holding a lock that the helper thread needs, thus blocking the helper thread.
9879     // 4) (This function) blocked on (Helper Thread): We block until the helper thread can process our IPC event.
9880     //     #4 is not true for async events.
9881     //
9882     // If we hit this assert, it means we may get the deadlock above and we're calling SendIPCEvent at a time we shouldn't.
9883     // Note this race is as old as dirt.
9884     if (IsRCEventThread() && !event->asyncSend)
9885     {
9886         // Note that w/ Continue & Attach, GetSynchronized() has a different meaning and the race above won't happen.
9887         BOOL fPossibleDeadlock = process->GetSynchronized() || (event->type == DB_IPCE_CONTINUE) || (event->type == DB_IPCE_ATTACHING);
9888         CONSISTENCY_CHECK_MSGF(fPossibleDeadlock, ("Possible deadlock while sending: '%s'\n", IPCENames::GetName(event->type)));
9889     }
9890 #endif
9891
9892
9893
9894     // Cache this process into the MRU so that we can find it if we're debugging in retail.
9895     g_pRSDebuggingInfo->m_MRUprocess = process;
9896
9897     HRESULT hr = S_OK;
9898     HRESULT hrEvent = S_OK;
9899     _ASSERTE(event != NULL);
9900
9901     // NOTE: the eventSize parameter is only so you can specify an event size that is SMALLER than the process send
9902     // buffer size!!
9903     if (eventSize > CorDBIPC_BUFFER_SIZE)
9904         return E_INVALIDARG;
9905
9906     STRESS_LOG4(LF_CORDB, LL_INFO1000, "CRCET::SIPCE: sending %s to AD 0x%x, proc 0x%x(%d)\n",
9907          IPCENames::GetName(event->type), VmPtrToCookie(event->vmAppDomain), process->m_id, process->m_id);
9908
9909     // For 2-way events, this check is unnecessary (since we already check for LS exit)
9910     // But for async events, we need this.
9911     // So just check it up here and make everyone's life easier.
9912     if (process->m_terminated)
9913     {
9914         STRESS_LOG0(LF_CORDB, LL_INFO10000, "CRCET::SIPCE: LS already terminated, shortcut exiting\n");
9915         return CORDBG_E_PROCESS_TERMINATED;
9916     }
9917
9918     // If the helper thread has died, we can't send an IPC event (and it's never coming back either). 
9919     // Although we do wait on the thread's handle, there are strange windows where the thread's handle
9920     // is not yet signaled even though we've continued from the exit-thread event for the helper.
9921     if (process->m_helperThreadDead)
9922     {
9923         STRESS_LOG0(LF_CORDB, LL_INFO10000, "CRCET::SIPCE: Helper-thread dead, shortcut exiting\n");
9924         return CORDBG_E_PROCESS_TERMINATED;
9925     }
9926
9927     BOOL fUnrecoverableError = TRUE;
9928     EX_TRY
9929     {
9930         hr = process->GetEventChannel()->SendEventToLeftSide(event, eventSize);
9931         fUnrecoverableError = FALSE;
9932     }
9933     EX_CATCH_HRESULT(hr);
9934
9935
9936     // If we're sending a Continue() event, then after this, the LS may run free.
9937     // If this is the last managed event before the LS exits, (which is the case
9938     // if we're responding to either an Exit-Thread or if we respond to a Detach)
9939     // the LS may exit at anytime from here on, so we need to be careful.
9940
9941
9942     if (fUnrecoverableError)
9943     {
9944         _ASSERTE(FAILED(hr));
9945         CORDBSetUnrecoverableError(process, hr, 0);
9946     }
9947     else
9948     {
9949         // Get a handle to the target process - this call always succeeds
9950         HANDLE hLSProcess = NULL;
9951         process->GetHandle(&hLSProcess);
9952
9953         // We take locks to ensure that the CordbProcess object is still alive,
9954         // even if the OS process exited.
9955         _ASSERTE(hLSProcess != NULL);
9956
9957         // Check if Sending the IPC event failed
9958         if (FAILED(hr))
9959         {
9960             // The failure to send an event may be due to the target process terminating
9961             // (especially, but not exclusively, in the case of async events).
9962             // There is a race here - we can't rely on any check above SendEventToLeftSide
9963             // to tell us whether the process has exited yet.
9964             // Check for that case and return an accurate hresult.
9965             DWORD ret = WaitForSingleObject(hLSProcess, 0);
9966             if (ret == WAIT_OBJECT_0)
9967             {
9968                 return CORDBG_E_PROCESS_TERMINATED;
9969             }
9970
9971             // Some other failure sending the IPC event - just return it.
9972             return hr;
9973         }
9974
9975         STRESS_LOG0(LF_CORDB, LL_INFO1000, "CRCET::SIPCE: sent...\n");
9976
9977         // If this is an async send, then don't wait for the left side to acknowledge that its read the event.
9978         _ASSERTE(!event->asyncSend || !event->replyRequired);
9979
9980         if (process->GetEventChannel()->NeedToWaitForAck(event))
9981         {
9982             STRESS_LOG0(LF_CORDB, LL_INFO1000,"CRCET::SIPCE: waiting for left side to read event. (on RSER)\n");
9983
9984             DWORD ret;
9985
9986             // Wait for either a reply (common case) or the left side to go away.
9987             // We can't detach while waiting for a reply (because detach needs to send events).
9988             // All of the outcomes from this wait are completely disjoint.
9989             // It's possible for the LS to reply and then exit normally (Thread_Detach, Process_Detach)
9990             // and so ExitProcess may have been called, but it doesn't matter.
9991
9992             enum {
9993                 ID_RSER = WAIT_OBJECT_0,
9994                 ID_LSPROCESS,
9995                 ID_HELPERTHREAD,
9996             };
9997
9998             // Only wait on the helper thread for cases where the process is stopped (and thus we don't expect it do exit on us).
9999             // If the process is running and we lose our helper thread, it ought to be during shutdown and we ough to
10000             // follow up with an exit.
10001             // This includes when we've dispatch Native events, and it includes the AsyncBreak sent to get us from a
10002             // win32 frozen state to a synchronized state).
10003             HANDLE hHelperThread = NULL;
10004             if (process->IsStopped())
10005             {
10006                 hHelperThread = process->GetHelperThreadHandle();
10007             }
10008
10009
10010             // Note that in case of a tie (multiple handles signaled), WaitForMultipleObjects gives
10011             // priority to the handle earlier in the array.
10012             HANDLE waitSet[] = { process->GetEventChannel()->GetRightSideEventAckHandle(), hLSProcess, hHelperThread};
10013             DWORD cWaitSet = NumItems(waitSet);
10014             if (hHelperThread == NULL)
10015             {
10016                 cWaitSet--;
10017             }
10018
10019             do
10020             {
10021                 ret = WaitForMultipleObjectsEx(cWaitSet, waitSet, FALSE, CordbGetWaitTimeout(), FALSE);
10022                 // If we timeout because we're waiting for an uncontinued OOB event, we need to just keep waiting.
10023             } while ((ret == WAIT_TIMEOUT) && process->IsWaitingForOOBEvent());
10024
10025             switch(ret)
10026             {
10027             case ID_RSER:
10028                 // Normal reply from LS.
10029                 // This is set iff the LS replied to our event. The LS may have exited since it replied
10030                 // but we don't care. We still have the reply and we'll pass it on.
10031                 STRESS_LOG0(LF_CORDB, LL_INFO1000, "CRCET::SIPCE: left side read the event.\n");
10032
10033                 // If this was a two-way event, then the result is already ready for us. Simply copy the result back
10034                 // over the original event that was sent. Otherwise, the left side has simply read the event and is
10035                 // processing it...
10036                 if (event->replyRequired)
10037                 {
10038                     process->GetEventChannel()->GetReplyFromLeftSide(event, eventSize);
10039                     hrEvent = event->hr;
10040                 }
10041                 break;
10042
10043             case ID_LSPROCESS:
10044                 // Left side exited on us.
10045                 // ExitProcess may or may not have been called here (since it's on a different thread).
10046                 STRESS_LOG0(LF_CORDB, LL_INFO1000, "CRCET::SIPCE: left side exiting while RS was waiting for reply.\n");
10047                 hr = CORDBG_E_PROCESS_TERMINATED;
10048                 break;
10049
10050             case ID_HELPERTHREAD:
10051                 // We can only send most IPC events while the LS is synchronized. We shouldn't lose our helper thread
10052                 // when synced under any sort of normal conditions.
10053                 // This won't fire if the process already exited, because LSPROCESS gets higher priority in the wait
10054                 // (since it was placed earlier).
10055                 // Thus the only "legitimate" window where this could happen would be in a shutdown scenario after
10056                 // the helper is dead but before the process has died. We shouldn't be synced in that scenario,
10057                 // so we shouldn't be sending IPC events during it.
10058                 STRESS_LOG0(LF_CORDB, LL_INFO1000, "CRCET::SIPCE: lost helper thread.\n");
10059
10060
10061                 // Assert because we want to know if we ever actually hit this in any detectable scenario.
10062                 // However, shutdown can occur in preemptive mode. Thus if the RS does an AsyncBreak late
10063                 // enough, then the LS will appear to be stopped but may still shutdown.
10064                 // Since the debuggee can exit asynchronously at any time (eg, suppose somebody forcefully
10065                 // kills it with taskman), this doesn't introduce a new case.
10066                 // That aside, it would be great to be able to assert this:
10067                 //_ASSERTE(!"Potential deadlock - Randomly Lost helper thread");
10068
10069                 // We'll piggy back this on the terminated case.
10070                 hr = CORDBG_E_PROCESS_TERMINATED;
10071                 break;
10072
10073             default:
10074                 {
10075                     // If we timed out/failed, check the left side to see if it is in the unrecoverable error mode. If it is,
10076                     // return the HR from the left side that caused the error.  Otherwise, return that we timed out and that
10077                     // we don't really know why.
10078                     HRESULT realHR = (ret == WAIT_FAILED) ? HRESULT_FROM_GetLastError() : ErrWrapper(CORDBG_E_TIMEOUT);
10079
10080                     hr = process->CheckForUnrecoverableError();
10081
10082                     if (hr == S_OK)
10083                     {
10084                         CORDBSetUnrecoverableError(process, realHR, 0);
10085                         hr = realHR;
10086                     }
10087
10088                     STRESS_LOG1(LF_CORDB, LL_INFO1000, "CRCET::SIPCE: left side timeout/fail while RS waiting for reply. hr = 0x%08x\n", hr);
10089                 }
10090                 break;
10091             }
10092
10093             // If the LS picked up RSEA, it will be reset (since it's an auto event).
10094             // But in the case that the wait failed or  that the LS exited, we need to explicitly reset RSEA
10095             if (hr != S_OK)
10096             {
10097                 process->GetEventChannel()->ClearEventForLeftSide();
10098             }
10099
10100             // Done waiting for reply.
10101
10102         }
10103     }
10104             
10105     process->ForceDacFlush();    
10106
10107     // The hr and hrEvent are 2 very different things.
10108     // hr tells us whether the event was sent successfully.
10109     // hrEvent tells us how the LS responded to it.
10110     // if FAILED(hr), then hrEvent is useless b/c the LS never got it.
10111     // But if SUCCEEDED(hr), then hrEvent may still have failed and that could be
10112     // valuable information.
10113
10114     return hr;
10115 }
10116
10117 //---------------------------------------------------------------------------------------
10118 // FlushQueuedEvents flushes a process's event queue.
10119 //
10120 // Arguments:
10121 //    pProcess - non-null process object whose queue will be drained
10122 //
10123 // Notes:
10124 //    @dbgtodo shim: this should be part of the shim.
10125 //    This dispatches events that are queued up. The queue is populated by
10126 //    the shim's proxy callback (see code:ShimProxyCallback). This will dispatch events
10127 //    to the 'real' callback supplied by the debugger. This will dispatch events
10128 //    as long as the debugger keeps calling continue.
10129 //
10130 //    This requires that the process lock be held, although it will toggle the lock.
10131 void CordbRCEventThread::FlushQueuedEvents(CordbProcess* process)
10132 {
10133     CONTRACTL
10134     {        
10135         NOTHROW; // This is happening on the RCET thread, so there's no place to propogate an error back up.
10136     }
10137     CONTRACTL_END;
10138
10139     STRESS_LOG0(LF_CORDB,LL_INFO10000, "CRCET::FQE: Beginning to flush queue\n");
10140
10141     _ASSERTE(process->GetShim() != NULL);
10142
10143     // We should only call this is we already have queued events
10144     _ASSERTE(!process->GetShim()->GetManagedEventQueue()->IsEmpty());
10145
10146     //
10147     // Dispatch queued events so long as they keep calling Continue()
10148     // before returning from their callback. If they call Continue(),
10149     // process->m_synchronized will be false again and we know to
10150     // loop around and dispatch the next event.
10151     //
10152     _ASSERTE(process->ThreadHoldsProcessLock());
10153
10154
10155     // Give shim a chance to queue any faked attach events.  Grab a pointer to the
10156     // ShimProcess now, while we still hold the process lock.  Once we release the lock,
10157     // GetShim() may not work.
10158     RSExtSmartPtr<ShimProcess> pShim(process->GetShim());
10159     
10160     // Release lock before we call out to shim to Queue fake events.
10161     {        
10162         RSInverseLockHolder inverseLockHolder(process->GetProcessLock());
10163         {
10164             PUBLIC_CALLBACK_IN_THIS_SCOPE0_NO_LOCK(pProcess);
10165
10166             // Because we've released the lock, at any point from here forward the
10167             // CorDbProcess may suddenly get neutered if the user detaches the debugger.
10168
10169             pShim->QueueFakeAttachEventsIfNeeded(false);
10170         }
10171     }
10172
10173     // Now that we're holding the process lock again, we can safely check whether
10174     // process has become neutered
10175     if (process->IsNeutered())
10176     {
10177         return;
10178     }
10179
10180     {
10181
10182         // Main dispatch loop here. DispatchRCEvent will take events out of the
10183         // queue and invoke callbacks
10184         do
10185         {
10186             // DispatchRCEvent will mark the process as stopped before dispatching.
10187             process->DispatchRCEvent();
10188
10189             LOG((LF_CORDB,LL_INFO10000, "CRCET::FQE: Finished w/ "
10190                  "DispatchRCEvent\n"));
10191         }
10192         while (process->GetSyncCompleteRecv() &&
10193                (process->GetSynchronized() == false) &&
10194                (process->GetShim() != NULL) && // may have lost Shim if we detached while dispatch
10195                (!process->GetShim()->GetManagedEventQueue()->IsEmpty()) &&
10196                (process->m_unrecoverableError == false));
10197     }
10198
10199     //
10200     // If they returned from a callback without calling Continue() then
10201     // the process is still synchronized, so let the rc event thread
10202     // know that it need to update its process list and remove the
10203     // process's event.
10204     //
10205     if (process->GetSynchronized())
10206     {
10207         ProcessStateChanged();
10208     }
10209
10210     LOG((LF_CORDB,LL_INFO10000, "CRCET::FQE: finished\n"));
10211 }
10212
10213 //---------------------------------------------------------------------------------------
10214 // Preliminary Handle an Notification event from the target. This may queue the event,
10215 // but does not actually dispatch the event.
10216 //
10217 // Arguments:
10218 //    pManagedEvent - local managed-event. On success, this function assumes ownership of the
10219 //        event and will delete its memory. Assumed that caller allocated via 'new'.
10220 //    pCallback - callback obecjt to dispatch events on.
10221 //
10222 // Return Value:
10223 //    None. Throws on error. On error, caller still owns the pManagedEvent and must free it.
10224 //
10225 // Assumptions:
10226 //    This should be called once a notification event is received from the target. 
10227 //
10228 // Notes:
10229 //    HandleRCEvent -- handle an IPC event received from the runtime controller.
10230 //    This will update ICorDebug state and immediately dispatch the event.
10231 //
10232 //---------------------------------------------------------------------------------------
10233 void CordbProcess::HandleRCEvent(
10234     DebuggerIPCEvent *         pManagedEvent, 
10235     RSLockHolder *             pLockHolder, 
10236     ICorDebugManagedCallback * pCallback)
10237 {
10238     CONTRACTL
10239     {
10240         THROWS;
10241         PRECONDITION(CheckPointer(pManagedEvent));
10242         PRECONDITION(CheckPointer(pCallback));
10243         PRECONDITION(ThreadHoldsProcessLock());
10244     }
10245     CONTRACTL_END;
10246
10247     if (!this->IsSafeToSendEvents() || this->m_exiting)
10248     {
10249         return;
10250     }
10251
10252     // Marshals over some standard data from event.
10253     MarshalManagedEvent(pManagedEvent);                    
10254
10255     STRESS_LOG4(LF_CORDB, LL_INFO1000, "RCET::TP: Got %s for AD 0x%x, proc 0x%x(%d)\n",
10256         IPCENames::GetName(pManagedEvent->type), VmPtrToCookie(pManagedEvent->vmAppDomain), this->m_id, this->m_id);
10257
10258     RSExtSmartPtr<ICorDebugManagedCallback2> pCallback2;
10259     pCallback->QueryInterface(IID_ICorDebugManagedCallback2, reinterpret_cast<void **> (&pCallback2));   
10260
10261     RSExtSmartPtr<ICorDebugManagedCallback3> pCallback3;
10262     pCallback->QueryInterface(IID_ICorDebugManagedCallback3, reinterpret_cast<void **> (&pCallback3));   
10263
10264     // Dispatch directly. May not necessarily dispatch an event.
10265     // Toggles the lock to dispatch callbacks.
10266     RawDispatchEvent(pManagedEvent, pLockHolder, pCallback, pCallback2, pCallback3);    
10267 }
10268
10269 //
10270 // ProcessStateChanged -- tell the rc event thread that the ICorDebug's
10271 // process list has changed by setting its flag and thread control event.
10272 // This will cause the rc event thread to update its set of handles to wait
10273 // on.
10274 //
10275 void CordbRCEventThread::ProcessStateChanged()
10276 {
10277     m_cordb->LockProcessList();
10278     STRESS_LOG0(LF_CORDB, LL_INFO100000, "CRCET::ProcessStateChanged\n");
10279     m_processStateChanged = TRUE;
10280     SetEvent(m_threadControlEvent);
10281     m_cordb->UnlockProcessList();
10282 }
10283
10284
10285 //---------------------------------------------------------------------------------------
10286 // Primary loop of the Runtime Controller event thread.  This routine loops during the 
10287 // debug session taking IPC events from the IPC block and calling out to process them.
10288 //
10289 // Arguments:
10290 //    None.
10291 //
10292 // Return Value:
10293 //    None.
10294 //
10295 // Notes:
10296 //    @dbgtodo shim: eventually hoist the entire RCET into the shim.
10297 //---------------------------------------------------------------------------------------
10298 void CordbRCEventThread::ThreadProc()
10299 {
10300     HANDLE         waitSet[MAXIMUM_WAIT_OBJECTS];
10301     CordbProcess * rgProcessSet[MAXIMUM_WAIT_OBJECTS];
10302     unsigned int   waitCount;
10303
10304 #ifdef _DEBUG
10305     memset(&rgProcessSet, NULL, MAXIMUM_WAIT_OBJECTS * sizeof(CordbProcess *));
10306     memset(&waitSet, NULL, MAXIMUM_WAIT_OBJECTS * sizeof(HANDLE));
10307 #endif
10308
10309
10310     // First event to wait on is always the thread control event.
10311     waitSet[0] = m_threadControlEvent;
10312     rgProcessSet[0] = NULL;
10313     waitCount = 1;
10314
10315     while (m_run)
10316     {
10317         DWORD dwStatus = WaitForMultipleObjectsEx(waitCount, waitSet, FALSE, 2000, FALSE);
10318
10319         if (dwStatus == WAIT_FAILED)
10320         {
10321             STRESS_LOG1(LF_CORDB, LL_INFO10000, "CordbRCEventThread::ThreadProc WaitFor"
10322                         "MultipleObjects failed: 0x%x\n", GetLastError());
10323         }
10324 #ifdef _DEBUG
10325         else if ((dwStatus >= WAIT_OBJECT_0) && (dwStatus < WAIT_OBJECT_0 + waitCount) && m_run)
10326         {
10327             // Got an event. Figure out which process it came from.
10328             unsigned int procNumber = dwStatus - WAIT_OBJECT_0;
10329
10330             if (procNumber != 0)
10331             {
10332                 // @dbgtodo shim: rip all of this out. Leave the assert in for now to verify that we're not accidentally
10333                 // going down this codepath. Once we rip this out, we can also simplify some of the code below.
10334                 // Notification events  (including Sync-complete) should be coming from Win32 event thread via
10335                 // V3 pipeline.
10336                 _ASSERTE(!"Shouldn't be here");
10337
10338             }
10339         }
10340 #endif
10341
10342         // Empty any queued work items.
10343         DrainWorkerQueue();
10344
10345         // Check a flag to see if we need to update our list of processes to wait on.
10346         if (m_processStateChanged)
10347         {
10348             STRESS_LOG0(LF_CORDB, LL_INFO1000, "RCET::TP: refreshing process list.\n");
10349
10350             unsigned int i;
10351
10352             //
10353             // free the old wait list
10354             //
10355             for (i = 1; i < waitCount; i++)
10356             {
10357                 rgProcessSet[i]->InternalRelease();
10358             }
10359
10360             // Pass 1: iterate the hash of all processes and collect the unsynchronized ones into the wait list.
10361             // Note that Stop / Continue can still be called on a different thread while we're doing this.
10362             m_cordb->LockProcessList();
10363             m_processStateChanged = FALSE;
10364
10365             waitCount = 1;
10366
10367             CordbSafeHashTable<CordbProcess> * pHashTable = m_cordb->GetProcessList();
10368             HASHFIND hashFind;
10369             CordbProcess * pProcess;
10370
10371             for (pProcess =  pHashTable->FindFirst(&hashFind); pProcess != NULL; pProcess = pHashTable->FindNext(&hashFind))
10372             {
10373                 _ASSERTE(waitCount < MAXIMUM_WAIT_OBJECTS);
10374                 
10375                 if( waitCount >= MAXIMUM_WAIT_OBJECTS )
10376                 {
10377                     break;
10378                 }
10379
10380                 // Only listen to unsynchronized processes. Processes that are synchronized will not send events without
10381                 // being asked by us first, so there is no need to async listen to them.
10382                 //
10383                 // Note: if a process is not synchronized then there is no way for it to transition to the syncrhonized
10384                 // state without this thread receiving an event and taking action. So there is no need to lock the
10385                 // per-process mutex when checking the process's synchronized flag here.
10386                 if (!pProcess->GetSynchronized() && pProcess->IsSafeToSendEvents())
10387                 {
10388                     STRESS_LOG2(LF_CORDB, LL_INFO1000, "RCET::TP: listening to process 0x%x(%d)\n", 
10389                                 pProcess->m_id, pProcess->m_id);
10390
10391                     waitSet[waitCount] = pProcess->m_leftSideEventAvailable;
10392                     rgProcessSet[waitCount] = pProcess;
10393                     rgProcessSet[waitCount]->InternalAddRef();
10394                     waitCount++;
10395                 }
10396             }
10397
10398             m_cordb->UnlockProcessList();
10399
10400             // Pass 2: for each process that we placed in the wait list, determine if there are any existing queued
10401             // events that need to be flushed.
10402
10403             // Start i at 1 to skip the control event...
10404             i = 1;
10405
10406             while(i < waitCount)
10407             {
10408                 pProcess = rgProcessSet[i];
10409
10410                 // Take the process lock so we can check the queue safely
10411                 pProcess->Lock();
10412
10413                 // Now that we've just locked the processes, we can safely inspect it and dispatch events.
10414                 // The process may have changed since when we first added it to the process list in Pass 1,
10415                 // so we can't make any assumptions about whether it's sync, live, or exiting.
10416
10417                 // Flush the queue if necessary. Note, we only do this if we've actually received a SyncComplete message
10418                 // from this process. If we haven't received a SyncComplete yet, then we don't attempt to drain any
10419                 // queued events yet. They'll be drained when the SyncComplete event is actually received.
10420                 if (pProcess->GetSyncCompleteRecv() && 
10421                     (pProcess->GetShim() != NULL) &&
10422                     !pProcess->GetSynchronized())
10423                 {
10424                     if (pProcess->GetShim()->GetManagedEventQueue()->IsEmpty())
10425                     {
10426                         // Effectively what we are doing here is to continue everything without actually
10427                         // handling an event.  We can get here if the event raised by the LS is a duplicate
10428                         // creation event, which the shim discards without adding it to the event queue.
10429                         // See code:ShimProcess::IsDuplicateCreationEvent.
10430                         // 
10431                         // To continue, we need to increment the stop count first.  Also, we can't call
10432                         // Continue() while holding the process lock.
10433                         pProcess->SetSynchronized(true);
10434                         pProcess->IncStopCount();
10435                         pProcess->Unlock();
10436                         pProcess->ContinueInternal(FALSE);
10437                         pProcess->Lock();
10438                     }
10439                     else
10440                     {
10441                         // This may toggle the process-lock
10442                         FlushQueuedEvents(pProcess);
10443                     }
10444                 }
10445
10446                 // Flushing could have left the process synchronized...
10447                 // Common case is if the callback didn't call Continue().
10448                 if (pProcess->GetSynchronized())
10449                 {
10450                     // remove the process from the wait list by moving all the other processes down one.
10451                     if ((i + 1) < waitCount)
10452                     {
10453                         memcpy(&rgProcessSet[i], &(rgProcessSet[i+1]), sizeof(rgProcessSet[0]) * (waitCount - i - 1));
10454                         memcpy(&waitSet[i], &waitSet[i+1], sizeof(waitSet[0]) * (waitCount - i - 1));
10455                     }
10456
10457                     // drop the count of processes to wait on
10458                     waitCount--;
10459
10460                     pProcess->Unlock();
10461
10462                     // make sure to release the reference we added when the process was added to the wait list.
10463                     pProcess->InternalRelease();
10464
10465                     // We don't have to increment i because we've copied the next element into
10466                     // the current value at i.
10467                 }
10468                 else
10469                 {
10470                     // Even after flushing, its still not syncd, so leave it in the wait list.
10471                     pProcess->Unlock();
10472
10473                     // Increment i normally.
10474                     i++;
10475                 }
10476             }
10477         } // end ProcessStateChanged
10478     }  // while (m_run)
10479
10480 #ifdef _DEBUG_IMPL
10481     // We intentionally return while leaking some CordbProcess objects inside
10482     // rgProcessSet, in some cases (e.g., I've seen this happen when detaching from a
10483     // debuggee almost immediately after attaching to it). In the future, we should
10484     // really consider not leaking these anymore. However, I'm unsure how safe it is to just
10485     // go and InternalRelease() those guys, as above we intentionally DON'T release them when
10486     // they're not synchronized. So for now, to make debug builds happy, exclude those
10487     // references when we run CheckMemLeaks() later on. In our next side-by-side release,
10488     // consider actually doing InternalRelease() on the remaining CordbProcesses on
10489     // retail, and then we can remove the following loop.
10490     for (UINT i=1; i < waitCount; i++)
10491     {
10492         InterlockedDecrement(&Cordb::s_DbgMemTotalOutstandingInternalRefs);
10493     }
10494 #endif //_DEBUG_IMPL
10495 }
10496
10497
10498 //
10499 // This is the thread's real thread proc. It simply calls to the
10500 // thread proc on the given object.
10501 //
10502 /*static*/ 
10503 DWORD WINAPI CordbRCEventThread::ThreadProc(LPVOID parameter)
10504 {
10505     CordbRCEventThread * pThread = (CordbRCEventThread *) parameter;
10506
10507     INTERNAL_THREAD_ENTRY(pThread);
10508     pThread->ThreadProc();
10509     return 0;
10510 }
10511
10512 template<typename T>
10513 InterlockedStack<T>::InterlockedStack()
10514 {
10515     m_pHead = NULL;
10516 }
10517
10518 template<typename T>
10519 InterlockedStack<T>::~InterlockedStack()
10520 {
10521     // This is an arbitrary choice. We expect the stacks be drained.
10522     _ASSERTE(m_pHead == NULL);
10523 }
10524
10525 // Thread safe pushes + pops.
10526 // Many threads can push simultaneously.
10527 // Only 1 thread can pop.
10528 template<typename T>
10529 void InterlockedStack<T>::Push(T * pItem)
10530 {
10531     // InterlockedCompareExchangePointer(&dest, ex, comp).
10532     // Really behaves like:
10533     //     val = *dest;
10534     //     if (*dest == comp) { *dest = ex; }
10535     //     return val;
10536     //
10537     // We can do a thread-safe assign { comp = dest; dest = ex } via:
10538     //     do { comp = dest } while (ICExPtr(&dest, ex, comp) != comp));
10539
10540
10541     do
10542     {
10543         pItem->m_next = m_pHead;
10544     }
10545     while(InterlockedCompareExchangeT(&m_pHead, pItem, pItem->m_next) != pItem->m_next);
10546 }
10547
10548 // Returns NULL on empty,
10549 // else returns the head of the list.
10550 template<typename T>
10551 T * InterlockedStack<T>::Pop()
10552 {
10553     if (m_pHead == NULL)
10554     {
10555         return NULL;
10556     }
10557
10558     // This allows 1 thread to Pop() and race against N threads doing a Push().
10559     T * pItem = NULL;
10560     do
10561     {
10562         pItem = m_pHead;
10563     } while(InterlockedCompareExchangeT(&m_pHead, pItem->m_next, pItem) != pItem);
10564
10565     return pItem;
10566 }
10567
10568
10569 // RCET will take ownership of this item and delete it.
10570 // This can be done w/o taking any locks (thus it can be called from any lock context)
10571 // This may race w/ the RCET draining the queue.
10572 void CordbRCEventThread::QueueAsyncWorkItem(RCETWorkItem * pItem)
10573 {
10574     // @todo -
10575     // Non-blocking insert into queue.
10576
10577     _ASSERTE(pItem != NULL);
10578
10579     m_WorkerStack.Push(pItem);
10580
10581     // Ping the RCET so that it drains the queue.
10582     SetEvent(m_threadControlEvent);
10583 }
10584
10585 // Execute & delete all workitems in the queue.
10586 // This can be done w/o taking any locks. (though individual items may take locks).
10587 void CordbRCEventThread::DrainWorkerQueue()
10588 {
10589     _ASSERTE(IsRCEventThread());
10590
10591     while(true)
10592     {
10593         RCETWorkItem* pCur = m_WorkerStack.Pop();
10594         if (pCur == NULL)
10595         {
10596             break;
10597         }
10598
10599         pCur->Do();
10600         delete pCur;
10601     }
10602 }
10603
10604
10605 //---------------------------------------------------------------------------------------
10606 // Wait for an reply from the debuggee.
10607 //
10608 // Arguments:
10609 //    pProcess - process for debuggee.
10610 //    pAppDomain - not used.
10611 //    pEvent - caller-allocated event to be filled out.
10612 //             This is expected to be at least as big as CorDBIPC_BUFFER_SIZE.
10613 //
10614 // Return Value:
10615 //    S_OK on success. else failure.
10616 //
10617 // Assumptions:
10618 //    Caller allocates 
10619 //
10620 // Notes:
10621 //   WaitForIPCEventFromProcess waits for an event from just the specified
10622 //   process. This should only be called when the process is in a synchronized
10623 //   state, which ensures that the RCEventThread isn't listening to the
10624 //   process's event, too, which would get confusing.
10625 //
10626 //   @dbgtodo - this function should eventually be obsolete once everything
10627 //   is using DAC calls instead of helper-thread. 
10628 //   
10629 //---------------------------------------------------------------------------------------
10630 HRESULT CordbRCEventThread::WaitForIPCEventFromProcess(CordbProcess * pProcess,
10631                                                        CordbAppDomain * pAppDomain,
10632                                                        DebuggerIPCEvent * pEvent)
10633 {
10634     CORDBRequireProcessStateOKAndSync(pProcess, pAppDomain);
10635
10636     DWORD dwStatus;
10637     HRESULT hr = S_OK;
10638
10639     do
10640     {
10641         dwStatus = SafeWaitForSingleObject(pProcess, 
10642                                            pProcess->m_leftSideEventAvailable,
10643                                            CordbGetWaitTimeout());
10644
10645         if (pProcess->m_terminated)
10646         {
10647             return CORDBG_E_PROCESS_TERMINATED;
10648         }
10649         // If we timeout because we're waiting for an uncontinued OOB event, we need to just keep waiting.
10650     } while ((dwStatus == WAIT_TIMEOUT) && pProcess->IsWaitingForOOBEvent());
10651
10652
10653
10654
10655     if (dwStatus == WAIT_OBJECT_0)
10656     {
10657         pProcess->CopyRCEventFromIPCBlock(pEvent);
10658
10659         EX_TRY
10660         {
10661             pProcess->MarshalManagedEvent(pEvent);
10662
10663             STRESS_LOG4(LF_CORDB, LL_INFO1000, "CRCET::SIPCE: Got %s for AD 0x%x, proc 0x%x(%d)\n",
10664                         IPCENames::GetName(pEvent->type), 
10665                         VmPtrToCookie(pEvent->vmAppDomain), 
10666                         pProcess->m_id, 
10667                         pProcess->m_id);
10668
10669         }
10670         EX_CATCH_HRESULT(hr)
10671
10672         SetEvent(pProcess->m_leftSideEventRead);
10673
10674         return hr;
10675     }
10676     else if (dwStatus == WAIT_TIMEOUT)
10677     {
10678         //
10679         // If we timed out, check the left side to see if it is in the
10680         // unrecoverable error mode. If it is, return the HR from the
10681         // left side that caused the error. Otherwise, return that we timed
10682         // out and that we don't really know why.
10683         //
10684         HRESULT realHR = ErrWrapper(CORDBG_E_TIMEOUT);
10685
10686         hr = pProcess->CheckForUnrecoverableError();
10687
10688         if (hr == S_OK)
10689         {
10690             CORDBSetUnrecoverableError(pProcess, realHR, 0);
10691             return realHR;
10692         }
10693         else
10694             return hr;
10695     }
10696     else
10697     {
10698         _ASSERTE(dwStatus == WAIT_FAILED);
10699
10700         hr = HRESULT_FROM_GetLastError();
10701
10702         CORDBSetUnrecoverableError(pProcess, hr, 0);
10703
10704         return hr;
10705     }
10706 }
10707
10708
10709 //
10710 // Start actually creates and starts the thread.
10711 //
10712 HRESULT CordbRCEventThread::Start()
10713 {
10714     if (m_threadControlEvent == NULL)
10715     {
10716         return E_INVALIDARG;
10717     }
10718
10719     m_thread = CreateThread(NULL, 
10720                             0, 
10721                             &CordbRCEventThread::ThreadProc,
10722                             (LPVOID) this, 
10723                             0, 
10724                             &m_threadId);
10725
10726     if (m_thread == NULL)
10727     {
10728         return HRESULT_FROM_GetLastError();
10729     }
10730
10731     return S_OK;
10732 }
10733
10734
10735 //
10736 // Stop causes the thread to stop receiving events and exit. It
10737 // waits for it to exit before returning.
10738 //
10739 HRESULT CordbRCEventThread::Stop()
10740 {
10741     if (m_thread != NULL)
10742     {
10743         LOG((LF_CORDB, LL_INFO100000, "CRCET::Stop\n"));
10744
10745         m_run = FALSE;
10746
10747         SetEvent(m_threadControlEvent);
10748
10749         DWORD ret = WaitForSingleObject(m_thread, INFINITE);
10750
10751         if (ret != WAIT_OBJECT_0)
10752         {
10753             return HRESULT_FROM_GetLastError();
10754         }
10755     }
10756
10757     m_cordb.Clear();
10758
10759     return S_OK;
10760 }
10761
10762
10763 /* ------------------------------------------------------------------------- *
10764  * Win32 Event Thread class
10765  * ------------------------------------------------------------------------- */
10766
10767 enum
10768 {
10769     W32ETA_NONE              = 0,
10770     W32ETA_CREATE_PROCESS    = 1,
10771     W32ETA_ATTACH_PROCESS    = 2,
10772     W32ETA_CONTINUE          = 3,
10773     W32ETA_DETACH            = 4
10774 };
10775
10776
10777
10778 //---------------------------------------------------------------------------------------
10779 // Constructor
10780 //
10781 // Arguments:
10782 //    pCordb - Pointer to the owning cordb object for this event thread.
10783 //    pShim - Pointer to the shim for supporting V2 debuggers on V3 architecture.
10784 //
10785 //---------------------------------------------------------------------------------------
10786 CordbWin32EventThread::CordbWin32EventThread(
10787     Cordb * pCordb, 
10788     ShimProcess * pShim
10789     ) :
10790     m_thread(NULL), m_threadControlEvent(NULL),
10791     m_actionTakenEvent(NULL), m_run(TRUE),
10792     m_action(W32ETA_NONE)
10793 {
10794     m_cordb.Assign(pCordb);
10795     _ASSERTE(pCordb != NULL);
10796
10797     m_pShim = pShim;
10798
10799     m_pNativePipeline = NULL;
10800 }
10801
10802
10803 //
10804 // Destructor. Cleans up all of the open handles and such.
10805 // This expects that the thread has been stopped and has terminated
10806 // before being called.
10807 //
10808 CordbWin32EventThread::~CordbWin32EventThread()
10809 {
10810     if (m_thread != NULL)
10811         CloseHandle(m_thread);
10812
10813     if (m_threadControlEvent != NULL)
10814         CloseHandle(m_threadControlEvent);
10815
10816     if (m_actionTakenEvent != NULL)
10817         CloseHandle(m_actionTakenEvent);
10818
10819     if (m_pNativePipeline != NULL)
10820     {
10821         m_pNativePipeline->Delete();
10822         m_pNativePipeline = NULL;
10823     }
10824
10825     m_sendToWin32EventThreadMutex.Destroy();
10826 }
10827
10828
10829 //
10830 // Init sets up all the objects that the thread will need to run.
10831 //
10832 HRESULT CordbWin32EventThread::Init()
10833 {
10834     if (m_cordb == NULL)
10835         return E_INVALIDARG;
10836
10837     m_sendToWin32EventThreadMutex.Init("Win32-Send lock", RSLock::cLockFlat, RSLock::LL_WIN32_SEND_LOCK);
10838
10839     m_threadControlEvent = WszCreateEvent(NULL, FALSE, FALSE, NULL);
10840     if (m_threadControlEvent == NULL)
10841         return HRESULT_FROM_GetLastError();
10842
10843     m_actionTakenEvent = WszCreateEvent(NULL, FALSE, FALSE, NULL);
10844     if (m_actionTakenEvent == NULL)
10845         return HRESULT_FROM_GetLastError();
10846
10847     m_pNativePipeline = NewPipelineWithDebugChecks();
10848     if (m_pNativePipeline == NULL)
10849     {
10850         return E_OUTOFMEMORY;
10851     }
10852
10853     return S_OK;
10854 }
10855
10856 //
10857 // Main function of the Win32 Event Thread
10858 //
10859 void CordbWin32EventThread::ThreadProc()
10860 {
10861 #if defined(RSCONTRACTS)
10862     DbgRSThread::GetThread()->SetThreadType(DbgRSThread::cW32ET);
10863
10864     // The win32 ET conceptually holds a lock (all threads do).
10865     DbgRSThread::GetThread()->TakeVirtualLock(RSLock::LL_WIN32_EVENT_THREAD);
10866 #endif
10867
10868     // In V2, the debuggee decides what to do if the debugger rudely exits / detaches. (This is 
10869     // handled by host policy). With the OS native-debuggging pipeline, the debugger by default
10870     // kills the debuggee if it exits. To emulate V2 behavior, we need to override that default.
10871     BOOL fOk = m_pNativePipeline->DebugSetProcessKillOnExit(FALSE);
10872     (void)fOk; //prevent "unused variable" error from GCC
10873     _ASSERTE(fOk);
10874
10875
10876     // Run the top-level event loop.
10877     Win32EventLoop();
10878
10879 #if defined(RSCONTRACTS)
10880     // The win32 ET conceptually holds a lock (all threads do).
10881     DbgRSThread::GetThread()->ReleaseVirtualLock(RSLock::LL_WIN32_EVENT_THREAD);
10882 #endif
10883 }
10884
10885 // Define a holder that calls code:DeleteIPCEventHelper
10886 NEW_WRAPPER_TEMPLATE1(DeleteIPCEventHolderHelper, DeleteIPCEventHelper);
10887 typedef DeleteIPCEventHolderHelper<DebuggerIPCEvent>  DeleteIPCEventHolder;
10888
10889 //---------------------------------------------------------------------------------------
10890 //
10891 // Helper to clean up IPCEvent before deleting it.
10892 // This must be called after an event is marshalled via code:CordbProcess::MarshalManagedEvent
10893 //
10894 // Arguments:
10895 //     pManagedEvent - managed event to delete. 
10896 //
10897 // Notes:
10898 //     This can delete a partially marshalled event.
10899 //
10900 void DeleteIPCEventHelper(DebuggerIPCEvent *pManagedEvent)
10901 {
10902     CONTRACTL
10903     {
10904         // This is backout code that shouldn't need to throw.
10905         NOTHROW;
10906     }
10907     CONTRACTL_END;
10908     if (pManagedEvent == NULL)
10909     {
10910         return;
10911     }
10912     switch (pManagedEvent->type & DB_IPCE_TYPE_MASK)
10913     {
10914         // so far only this event need to cleanup.
10915         case DB_IPCE_MDA_NOTIFICATION:
10916             pManagedEvent->MDANotification.szName.CleanUp();
10917             pManagedEvent->MDANotification.szDescription.CleanUp();
10918             pManagedEvent->MDANotification.szXml.CleanUp();
10919             break;
10920
10921         case DB_IPCE_FIRST_LOG_MESSAGE:
10922             pManagedEvent->FirstLogMessage.szContent.CleanUp();
10923             break;
10924
10925         default:
10926             break;
10927     }
10928     delete [] (BYTE *)pManagedEvent;
10929 }
10930
10931 //---------------------------------------------------------------------------------------
10932 // Handle a CLR specific notification event.
10933 //
10934 // Arguments:
10935 //    pManagedEvent - non-null pointer to a managed event.
10936 //    pLockHolder - hold to process lock that gets toggled if this dispatches an event.
10937 //    pCallback - callback to dispatch potential managed events.
10938 //
10939 // Return Value:
10940 //    Throws on error.
10941 //
10942 // Assumptions:
10943 //    Target is stopped. Record was already determined to be a CLR event.
10944 //
10945 // Notes:
10946 //    This is called after caller does WaitForDebugEvent.
10947 //    Any exception this Filter does not recognize is treated as kNotClr.
10948 //    Currently, this includes both managed-exceptions and unmanaged ones. 
10949 //    For interop-debugging, the interop logic will handle all kNotClr and triage if 
10950 //    it's really a non-CLR exception.
10951 //
10952 //---------------------------------------------------------------------------------------
10953 void CordbProcess::FilterClrNotification(
10954     DebuggerIPCEvent * pManagedEvent,
10955     RSLockHolder * pLockHolder,
10956     ICorDebugManagedCallback * pCallback)
10957 {   
10958     CONTRACTL
10959     {
10960         THROWS;
10961         PRECONDITION(CheckPointer(pManagedEvent));
10962         PRECONDITION(CheckPointer(pCallback));
10963         PRECONDITION(ThreadHoldsProcessLock());
10964     }
10965     CONTRACTL_END;
10966
10967     // There are 3 types of events from the LS:
10968     // 1) Replies (eg, corresponding to WaitForIPCEvent)
10969     //       we need to set LSEA/wait on LSER.
10970     // 2) Sync-Complete (kind of like a special notification)
10971     //       Ping the helper
10972     // 3) Notifications (eg, Module-load): 
10973     //       these are dispatched immediately.
10974     // 4) Left-side Startup event
10975
10976
10977     // IF we're synced, then we must be getting a "Reply".
10978     bool fReply = this->GetSynchronized();
10979
10980     LOG((LF_CORDB, LL_INFO10000, "CP::FCN - Received event %s; fReply: %d\n", 
10981          IPCENames::GetName(pManagedEvent->type),
10982          fReply));
10983
10984     if (fReply)    
10985     {   
10986         // 
10987         _ASSERTE(m_pShim != NULL);
10988         //
10989         // Case 1: Reply
10990         //
10991
10992         pLockHolder->Release();
10993         _ASSERTE(!ThreadHoldsProcessLock());
10994
10995         // Save the IPC event and wake up the thread which is waiting for it from the LS.
10996         GetEventChannel()->SaveEventFromLeftSide(pManagedEvent);
10997         SetEvent(this->m_leftSideEventAvailable);
10998
10999         // Some other thread called code:CordbRCEventThread::WaitForIPCEventFromProcess, and 
11000         // that will respond here and set the event.
11001
11002         DWORD dwResult = WaitForSingleObject(this->m_leftSideEventRead, CordbGetWaitTimeout());
11003         pLockHolder->Acquire();
11004         if (dwResult != WAIT_OBJECT_0)
11005         {
11006             // The wait failed.  This is probably WAIT_TIMEOUT which suggests a deadlock/assert on
11007             // the RCEventThread.  
11008             CONSISTENCY_CHECK_MSGF(false, ("WaitForSingleObject failed: %d", dwResult));
11009             ThrowHR(CORDBG_E_TIMEOUT);
11010         }
11011     }
11012     else
11013     {
11014         if (pManagedEvent->type == DB_IPCE_LEFTSIDE_STARTUP)
11015         {
11016             //
11017             // Case 4: Left-side startup event. We'll mark that we're attached from oop.
11018             //
11019
11020             // Now that LS is started, we should definitely be able to instantiate DAC. 
11021             InitializeDac();
11022             
11023             // @dbgtodo 'attach-bit': we don't want the debugger automatically invading the process.
11024             GetDAC()->MarkDebuggerAttached(TRUE);                            
11025         }         
11026         else if (pManagedEvent->type == DB_IPCE_SYNC_COMPLETE)
11027         {
11028             // Since V3 doesn't request syncs, it shouldn't get sync-complete.
11029             // @dbgtodo sync: this changes when V3 can explicitly request an AsyncBreak.
11030             _ASSERTE(m_pShim != NULL);
11031
11032             //
11033             // Case 2: Sync Complete
11034             //
11035
11036             HandleSyncCompleteRecieved();
11037         }
11038         else
11039         {
11040             //
11041             // Case 3: Notification. This will dispatch the event immediately.
11042             //
11043
11044             // Toggles the process-lock if it dispatches callbacks.
11045             HandleRCEvent(pManagedEvent, pLockHolder, pCallback);
11046
11047         } // end Notification
11048     }    
11049 }
11050
11051
11052
11053 //
11054 // If the thread has an unhandled managed exception, hijack it.
11055 //
11056 // Arguments:
11057 //     dwThreadId - OS Thread id.
11058 //
11059 // Returns:
11060 //     True if hijacked; false if not.
11061 //
11062 // Notes:
11063 //     This is called from shim to emulate being synchronized at an unhandled
11064 //     exception. 
11065 //     Other ICorDebug operations could calls this (eg, func-eval at 2nd chance).
11066 BOOL CordbProcess::HijackThreadForUnhandledExceptionIfNeeded(DWORD dwThreadId)
11067 {    
11068     PUBLIC_API_ENTRY(this); // from Shim
11069
11070     BOOL fHijacked = FALSE;
11071     HRESULT hr = S_OK;
11072     EX_TRY
11073     {
11074         RSLockHolder lockHolder(GetProcessLock());
11075
11076         // OS will not execute the Unhandled Exception Filter under native debugger, so
11077         // we need to hijack the thread to get it to execute the UEF, which will then do 
11078         // work for unhandled managed exceptions.
11079         CordbThread * pThread = TryLookupOrCreateThreadByVolatileOSId(dwThreadId);
11080         if (pThread != NULL)
11081         {   
11082             // If the thread has a managed exception, then we should have a pThread object.
11083             
11084             if (pThread->HasUnhandledNativeException())
11085             {
11086                 _ASSERTE(pThread->IsThreadExceptionManaged()); // should have been marked earlier
11087
11088                 pThread->HijackForUnhandledException();
11089                 fHijacked = TRUE;
11090             }
11091         }
11092     }
11093     EX_CATCH_HRESULT(hr);
11094     SIMPLIFYING_ASSUMPTION(SUCCEEDED(hr));
11095
11096     return fHijacked;
11097 }
11098
11099 //---------------------------------------------------------------------------------------
11100 // Validate the given exception record or throw.
11101 //
11102 // Arguments:
11103 //    pRawRecord - non-null raw bytes of the exception
11104 //    countBytes - number of bytes in pRawRecord buffer.
11105 //    format - format of pRawRecord
11106 //
11107 // Returns:
11108 //    A type-safe exception record from the raw buffer.
11109 // 
11110 // Notes:
11111 //   This is a helper for code:CordbProcess::Filter.
11112 //   This can do consistency checks on the incoming parameters such as:
11113 //    * verify countBytes matches the expected size for the given format.
11114 //    * verify the format is supported. 
11115 //
11116 //   If we let a given ICD understand multiple formats (eg, have x86 understand both Exr32 and
11117 //    Exr64), this would be the spot to allow the conversion.
11118 //
11119 const EXCEPTION_RECORD * CordbProcess::ValidateExceptionRecord(
11120         const BYTE pRawRecord[],
11121         DWORD countBytes,
11122         CorDebugRecordFormat format)
11123 {
11124     ValidateOrThrow(pRawRecord);
11125
11126     //
11127     // Check format against expected platform.
11128     //
11129
11130     // @dbgtodo - , cross-plat: Once we do cross-plat, these should be based off target-architecture not host's.
11131 #if defined(_WIN64)
11132     if (format != FORMAT_WINDOWS_EXCEPTIONRECORD64)
11133     {
11134         ThrowHR(E_INVALIDARG);
11135     }
11136 #else
11137     if (format != FORMAT_WINDOWS_EXCEPTIONRECORD32)
11138     {
11139         ThrowHR(E_INVALIDARG);
11140     }
11141 #endif
11142     
11143     // @dbgtodo cross-plat: once we do cross-plat, need to use correct EXCEPTION_RECORD variant.
11144     if (countBytes != sizeof(EXCEPTION_RECORD))
11145     {
11146         ThrowHR(E_INVALIDARG);
11147     }
11148
11149     
11150     const EXCEPTION_RECORD * pRecord = reinterpret_cast<const EXCEPTION_RECORD *> (pRawRecord);
11151
11152     return pRecord;
11153 };
11154
11155 // Return value: S_OK or indication that no more room exists for enabled types
11156 HRESULT CordbProcess::SetEnableCustomNotification(ICorDebugClass * pClass, BOOL fEnable)
11157 {
11158     HRESULT hr = S_OK;
11159     PUBLIC_API_BEGIN(this); // takes the lock
11160
11161     ValidateOrThrow(pClass);
11162
11163     ((CordbClass *)pClass)->SetCustomNotifications(fEnable);
11164
11165     PUBLIC_API_END(hr); 
11166     return hr;
11167 } // CordbProcess::SetEnableCustomNotification
11168
11169 //---------------------------------------------------------------------------------------
11170 // Public implementation of ICDProcess4::Filter
11171 //
11172 // Arguments: 
11173 //    pRawRecord - non-null raw bytes of the exception
11174 //    countBytes - number of bytes in pRawRecord buffer.
11175 //    format - format of pRawRecord
11176 //    dwFlags - flags providing auxillary info for exception record.
11177 //    dwThreadId - thread that exception occurred on.
11178 //    pCallback - callback to dispatch potential managed events on.
11179 //    pContinueStatus - Continuation status for exception. This dictates what 
11180 //         to pass to kernel32!ContinueDebugEvent().
11181 //
11182 // Return Value:
11183 //    S_OK on success.
11184 //
11185 // Assumptions:
11186 //    Target is stopped.
11187 //
11188 // Notes:
11189 //    The exception could be anything, including:
11190 //    - a CLR notification, 
11191 //    - a random managed exception (both from managed code or the runtime),
11192 //    - a non-CLR exception
11193 //
11194 //    This is cross-platform. The {pRawRecord, countBytes, format} describe events
11195 //    on an arbitrary target architecture. On windows, this will be an EXCEPTION_RECORD.
11196 // 
11197 HRESULT CordbProcess::Filter(
11198         const BYTE pRawRecord[],
11199         DWORD countBytes,
11200         CorDebugRecordFormat format,
11201         DWORD dwFlags, 
11202         DWORD dwThreadId, 
11203         ICorDebugManagedCallback * pCallback,
11204         DWORD * pContinueStatus
11205 )
11206 {
11207     HRESULT hr = S_OK;
11208     PUBLIC_API_BEGIN(this); // takes the lock
11209     {
11210         //
11211         // Validate parameters
11212         //
11213
11214         // If we don't care about the continue status, we leave it untouched.
11215         ValidateOrThrow(pContinueStatus);
11216         ValidateOrThrow(pCallback);
11217
11218         const EXCEPTION_RECORD * pRecord = ValidateExceptionRecord(pRawRecord, countBytes, format);
11219
11220         DWORD dwFirstChance = (dwFlags & IS_FIRST_CHANCE);
11221
11222         //
11223         // Deal with 2nd-chance exceptions. Don't actually hijack now (that's too invasive), 
11224         // but mark that we have the exception in case a future operation (eg, func-eval) needs to hijack.
11225         //
11226         if (!dwFirstChance)
11227         {
11228             CordbThread * pThread = TryLookupOrCreateThreadByVolatileOSId(dwThreadId);
11229
11230             // If we don't have a managed-thread object, then it certainly can't have a throwable.
11231             // It's possible this is still an exception from the native portion of the runtime, 
11232             // but that's ok, we'll just treat it as a native exception.
11233             // This could be expensive, don't want to do it often... (definitely not on every Filter).
11234
11235
11236             // OS will not execute the Unhandled Exception Filter under native debugger, so
11237             // we need to hijack the thread to get it to execute the UEF, which will then do 
11238             // work for unhandled managed exceptions.
11239             if ((pThread != NULL) && pThread->IsThreadExceptionManaged())
11240             {                
11241                 // Copy exception record for future use in case we decide to hijack.
11242                 pThread->SetUnhandledNativeException(pRecord);
11243             }
11244             // we don't care about 2nd-chance exceptions, unless we decide to hijack it later.
11245         }
11246
11247         //
11248         // Deal with CLR notifications
11249         //
11250         else if (pRecord->ExceptionCode == CLRDBG_NOTIFICATION_EXCEPTION_CODE) // Special event code
11251         {
11252             //
11253             // This may not be for us, or we may not have a managed thread object:
11254             // 1. Anybody can raise an exception with this exception code, so can't assume this belongs to us yet.
11255             // 2. Notifications may come on unmanaged threads if they're coming from MDAs or CLR internal events 
11256             //    fired before the thread is created.
11257             //
11258             BYTE * pManagedEventBuffer = new BYTE[CorDBIPC_BUFFER_SIZE];
11259             DeleteIPCEventHolder pManagedEvent(reinterpret_cast<DebuggerIPCEvent *>(pManagedEventBuffer));
11260         
11261             bool fOwner = CopyManagedEventFromTarget(pRecord, pManagedEvent);
11262             if (fOwner)
11263             {
11264                 // This toggles the lock if it dispatches callbacks
11265                 FilterClrNotification(pManagedEvent, GET_PUBLIC_LOCK_HOLDER(), pCallback);
11266                 
11267                 // Cancel any notification events from target. These are just supposed to notify ICD and not
11268                 // actually be real exceptions in the target.
11269                 // Canceling here also prevents a VectoredExceptionHandler in the target from picking
11270                 // up exceptions for the CLR.
11271                 *pContinueStatus = DBG_CONTINUE;             
11272             }
11273
11274             // holder will invoke DeleteIPCEventHelper(pManagedEvent).
11275         }
11276
11277     }    
11278     PUBLIC_API_END(hr); 
11279     // we may not find the correct mscordacwks so fail gracefully
11280     _ASSERTE(SUCCEEDED(hr) || (hr != HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND)));
11281
11282     return hr;
11283 }
11284
11285 //---------------------------------------------------------------------------------------
11286 // Wrapper to invoke ICorDebugMutableDataTarget::ContinueStatusChanged
11287 //
11288 // Arguments:
11289 //   dwContinueStatus - new continue status
11290 //
11291 // Returns:
11292 //   None. Throw on error.
11293 //
11294 // Notes:
11295 //   Initial continue status is returned from code:CordbProcess::Filter.
11296 //   Some operations (mainly hijacking on a 2nd-chance exception), may need to 
11297 //   override that continue status.
11298 //   ICorDebug operations invoke a callback on the data-target to notify the debugger
11299 //   of a change in status. Debugger may fail the request.
11300 //
11301 void CordbProcess::ContinueStatusChanged(DWORD dwThreadId, CORDB_CONTINUE_STATUS dwContinueStatus)
11302 {        
11303     HRESULT hr = m_pMutableDataTarget->ContinueStatusChanged(dwThreadId, dwContinueStatus);
11304     IfFailThrow(hr);
11305 }
11306
11307 //---------------------------------------------------------------------------------------
11308 // Request a synchronization to occur after a debug event is dispatched.
11309 // 
11310 // Note:
11311 //    This is called in response to a managed debug event, and so we know that we have
11312 //    a worker thread in the process (the one that just sent the event!)
11313 //    This can not be called asynchronously.
11314 //---------------------------------------------------------------------------------------
11315 void CordbProcess::RequestSyncAtEvent()
11316 {
11317     GetDAC()->RequestSyncAtEvent();
11318 }
11319
11320 //---------------------------------------------------------------------------------------
11321 //
11322 // Primary loop of the Win32 debug event thread.
11323 //
11324 //
11325 // Arguments:
11326 //    None.
11327 //
11328 // Return Value:
11329 //    None.
11330 //
11331 // Notes:
11332 //    This is it, you've found it, the main guy.  This function loops as long as the 
11333 //    debugger is around calling the OS WaitForDebugEvent() API.  It takes the OS Debug
11334 //    Event and filters it thru the right-side, continuing the process if not recognized.
11335 //
11336 // @dbgtodo shim: this will become part of the shim.
11337 //---------------------------------------------------------------------------------------
11338 void CordbWin32EventThread::Win32EventLoop()
11339 {
11340     // This must be called from the win32 event thread.
11341     _ASSERTE(IsWin32EventThread());
11342
11343     LOG((LF_CORDB, LL_INFO1000, "W32ET::W32EL: entered win32 event loop\n"));
11344
11345
11346     DEBUG_EVENT event;
11347     
11348     // Allow the timeout for WFDE to be adjustable. Default to 25 ms based off perf numbers (see issue VSWhidbey 132368).
11349     DWORD dwWFDETimeout = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_DbgWFDETimeout);
11350
11351     while (m_run)
11352     {
11353         BOOL fEventAvailable = FALSE;
11354
11355         // We should not have any locks right now.
11356
11357
11358         // Have to wait on 2 sources:
11359         // WaitForMultipleObjects - ping for messages (create, attach, Continue, detach) and also
11360         //    process exits in the managed-only case.
11361         // Native Debug Events - This is a huge perf hit so we want to avoid it whenever we can.
11362         //    Only wait on these if we're interop debugging and if the process is not frozen.
11363         //    A frozen process can't send any debug events, so don't bother looking for them.
11364
11365
11366         unsigned int cWaitCount = 1;
11367
11368         HANDLE rghWaitSet[2];
11369
11370         rghWaitSet[0] = m_threadControlEvent;
11371
11372         DWORD dwWaitTimeout = INFINITE;
11373
11374         if (m_pProcess != NULL)
11375         {
11376             // Process is always built on Native debugging pipeline, so it needs to always be prepared to call WFDE
11377             // As an optimization, if the target is stopped, then we can avoid calling WFDE.            
11378             {
11379 #ifndef FEATURE_INTEROP_DEBUGGING
11380                 // Managed-only, never win32 stopped, so always check for an event.
11381                 dwWaitTimeout = 0;
11382                 fEventAvailable = m_pNativePipeline->WaitForDebugEvent(&event, dwWFDETimeout, m_pProcess);
11383 #else
11384                 // Wait for a Win32 debug event from any processes that we may be attached to as the Win32 debugger.
11385                 const bool fIsWin32Stopped = (m_pProcess->m_state & CordbProcess::PS_WIN32_STOPPED) != 0;
11386                 const bool fSkipWFDE = fIsWin32Stopped;
11387
11388
11389                 const bool fIsInteropDebugging = m_pProcess->IsInteropDebugging();
11390                 (void)fIsInteropDebugging; //prevent "unused variable" error from GCC
11391                 
11392                 // Assert checks
11393                 _ASSERTE(fIsInteropDebugging == m_pShim->IsInteropDebugging());
11394
11395                 if (!fSkipWFDE)
11396                 {
11397                     dwWaitTimeout = 0;
11398                     fEventAvailable = m_pNativePipeline->WaitForDebugEvent(&event, dwWFDETimeout, m_pProcess);
11399                 }
11400                 else 
11401                 {
11402                     // If we're managed-only debugging, then the process should always be running,
11403                     // which means we always need to be calling WFDE to pump potential debug events.
11404                     // If we're interop-debugging, then the process can be stopped at a native-debug event,
11405                     // in which case we don't have to call WFDE until we resume it again.
11406                     // So we can only skip the WFDE when we're interop-debugging. 
11407                     _ASSERTE(fIsInteropDebugging); 
11408                 }
11409 #endif // FEATURE_INTEROP_DEBUGGING
11410             }
11411
11412
11413         } // end m_pProcess != NULL
11414
11415 #if defined(FEATURE_INTEROP_DEBUGGING)
11416         // While interop-debugging, the process may get killed rudely underneath us, even if we haven't
11417         // continued the last debug event. In such cases, The process object will get signalled normally.
11418         // If we didn't just get a native-exitProcess event, then listen on the process handle for exit.
11419         // (this includes all managed-only debugging)
11420         // It's very important to establish this before we go into the WaitForMutlipleObjects below
11421         // because the debuggee may exit while we're sitting in that loop (waiting for the debugger to call Continue).
11422         bool fDidNotJustGetExitProcessEvent = !fEventAvailable || (event.dwDebugEventCode != EXIT_PROCESS_DEBUG_EVENT);
11423 #else
11424         // In non-interop scenarios, we'll never get any native debug events, let alone an ExitProcess native event.
11425         bool fDidNotJustGetExitProcessEvent = true;
11426 #endif // FEATURE_INTEROP_DEBUGGING
11427
11428
11429         // The m_pProcess handle will get nulled out after we process the ExitProcess event, and
11430         // that will ensure that we only wait for an Exit event once.
11431         if ((m_pProcess != NULL) && fDidNotJustGetExitProcessEvent)
11432         {
11433             rghWaitSet[1] = m_pProcess->UnsafeGetProcessHandle();
11434             cWaitCount = 2;
11435         }
11436
11437         // See if any process that we aren't attached to as the Win32 debugger have exited. (Note: this is a
11438         // polling action if we are also waiting for Win32 debugger events. We're also looking at the thread
11439         // control event here, too, to see if we're supposed to do something, like attach.
11440         DWORD dwStatus = WaitForMultipleObjectsEx(cWaitCount, rghWaitSet, FALSE, dwWaitTimeout, FALSE);
11441
11442         _ASSERTE((dwStatus == WAIT_TIMEOUT) || (dwStatus < cWaitCount));
11443
11444         if (!m_run)
11445         {
11446             _ASSERTE(m_action == W32ETA_NONE);
11447             break;
11448         }
11449
11450         LOG((LF_CORDB, LL_INFO100000, "W32ET::W32EL - got event , ret=%d, has w32 dbg event=%d\n",
11451              dwStatus, fEventAvailable));
11452
11453         // If we haven't timed out, or if it wasn't the thread control event
11454         // that was set, then a process has
11455         // exited...
11456         if ((dwStatus != WAIT_TIMEOUT) && (dwStatus != WAIT_OBJECT_0))
11457         {
11458             // Grab the process that exited.
11459             _ASSERTE((dwStatus - WAIT_OBJECT_0) == 1);
11460             ExitProcess(false); // not detach
11461             fEventAvailable = false;
11462         }
11463         // Should we create a process?
11464         else if (m_action == W32ETA_CREATE_PROCESS)
11465         {
11466             CreateProcess();
11467         }
11468         // Should we attach to a process?
11469         else if (m_action == W32ETA_ATTACH_PROCESS)
11470         {
11471             AttachProcess();
11472         }
11473         // Should we detach from a process?
11474         else if (m_action == W32ETA_DETACH)
11475         {
11476             ExitProcess(true); // detach case
11477
11478             // Once we detach, we don't need to continue any outstanding event.
11479             // So act like we never got the event.
11480             fEventAvailable = false;
11481             PREFIX_ASSUME(m_pProcess == NULL); // W32 cleared process pointer
11482         }
11483
11484 #ifdef FEATURE_INTEROP_DEBUGGING
11485         // Should we continue the process?
11486         else if (m_action == W32ETA_CONTINUE)
11487         {
11488             HandleUnmanagedContinue();
11489         }
11490 #endif // FEATURE_INTEROP_DEBUGGING
11491
11492         // We don't need to sweep the FCH threads since we never hijack a thread in cooperative mode.
11493
11494
11495         // Only process an event if one is available.
11496         if (!fEventAvailable)
11497         {
11498             continue;
11499         }
11500
11501         // The only ref we have is the one in the ProcessList hash;
11502         // If we dispatch an ExitProcess event, we may even lose that.
11503         // But since the CordbProcess is our parent object, we know it won't go away until
11504         // it neuters us, so we can safely proceed.
11505         // Find the process this event is for.
11506         PREFIX_ASSUME(m_pProcess != NULL);
11507         _ASSERTE(m_pProcess->m_id == GetProcessId(&event)); // should only get events for our proc
11508         g_pRSDebuggingInfo->m_MRUprocess = m_pProcess;
11509
11510         // Must flush the dac cache since we were just running.
11511         m_pProcess->ForceDacFlush();
11512         
11513         // So we've filtered out CLR events.
11514         // Let the shim handle the remaining events. This will call back into Filter() if appropriate.
11515         // This will also ensure the debug event gets continued.
11516         HRESULT hrShim = S_OK;
11517         {
11518             PUBLIC_CALLBACK_IN_THIS_SCOPE0_NO_LOCK(NULL);
11519             hrShim = m_pShim->HandleWin32DebugEvent(&event); 
11520         }
11521         // Any errors from the shim (eg. failure to load DAC) are unrecoverable
11522         SetUnrecoverableIfFailed(m_pProcess, hrShim);  
11523
11524     } // loop
11525
11526     LOG((LF_CORDB, LL_INFO1000, "W32ET::W32EL: exiting event loop\n"));
11527
11528     return;
11529 }
11530
11531 //---------------------------------------------------------------------------------------
11532 //
11533 // Returns if the current thread is the win32 thread.
11534 //
11535 // Return Value:
11536 //    true iff this is the win32 event thread.
11537 //
11538 //---------------------------------------------------------------------------------------
11539 bool CordbProcess::IsWin32EventThread()
11540 {
11541     _ASSERTE((m_pShim != NULL) || !"Don't check win32 event thread in V3 cases");
11542     return m_pShim->IsWin32EventThread();
11543 }
11544
11545 //---------------------------------------------------------------------------------------
11546 // Call when the sync complete event is received and can be processed.
11547 // 
11548 // Notes:
11549 //    This is called when the RS gets the sync-complete from the LS and can process it.
11550 //    
11551 //    This has a somewhat elaborate contract to fill between Interop-debugging, Async-Break, draining the
11552 //    managed event-queue, and coordinating with the dispatch thread (RCET).
11553 //    
11554 //    @dbgtodo - this should eventually get hoisted into the shim.
11555 void CordbProcess::HandleSyncCompleteRecieved()
11556 {
11557     _ASSERTE(ThreadHoldsProcessLock());
11558
11559     this->SetSyncCompleteRecv(true);
11560
11561     // If some thread is waiting for the process to sync, notify that it can go now.
11562     if (this->m_stopRequested)
11563     {
11564         this->SetSynchronized(true); 
11565         SetEvent(this->m_stopWaitEvent);
11566     }
11567     else
11568     {
11569         // Note: we set the m_stopWaitEvent all the time and leave it high while we're stopped. This
11570         // must be done after we've checked m_stopRequested.
11571         SetEvent(this->m_stopWaitEvent);
11572
11573         // Otherwise, simply mark that the state of the process has changed and let the
11574         // managed event dispatch logic take over.
11575         //
11576         // Note: process->m_synchronized remains false, which indicates to the RC event
11577         // thread that it can dispatch the next managed event.
11578         m_cordb->ProcessStateChanged();
11579     }
11580 }
11581
11582
11583 #ifdef FEATURE_INTEROP_DEBUGGING
11584
11585 // Get a Thread's _user_ starting address (the real starting address may be some
11586 // OS shim.)
11587 // This may return NULL for the Async-Break thread.
11588 void* GetThreadUserStartAddr(const DEBUG_EVENT* pCreateThreadEvent)
11589 {
11590     // On Win7 and above, we can trust the lpStartAddress field of the CREATE_THREAD_DEBUG_EVENT
11591     // to be the user start address (the actual OS start address is an implementation detail that 
11592     // doesn't need to be exposed to users). Note that we are assuming that the target process
11593     // is running on Win7 if mscordbi is. If we ever have some remoting scenario where the target
11594     // can run on a different windows machine with a different OS version we will need a way to
11595     // determine the target's OS version
11596     if(RunningOnWin7())
11597     {
11598         return pCreateThreadEvent->u.CreateThread.lpStartAddress;
11599     }
11600     
11601     // On pre-Win7 OSes, we rely on an OS implementation detail to get the real user thread start:
11602     // it exists in EAX at thread start time.
11603     // Note that for a brief period of time there was a GetThreadStartInformation API in Longhorn 
11604     // we could use for this, but it was removed during the Longhorn reset.  
11605     HANDLE hThread = pCreateThreadEvent->u.CreateThread.hThread;
11606 #if defined(DBG_TARGET_X86)
11607     // Grab the thread's context.
11608     DT_CONTEXT c;
11609     c.ContextFlags = DT_CONTEXT_FULL;
11610     BOOL succ = DbiGetThreadContext(hThread, &c);
11611
11612     if (succ)
11613     {
11614         return (void*) c.Eax;
11615     }
11616 #elif defined(DBG_TARGET_AMD64)
11617     DT_CONTEXT c;
11618     c.ContextFlags = DT_CONTEXT_FULL;
11619     BOOL succ = DbiGetThreadContext(hThread, &c);
11620
11621     if (succ)
11622     {
11623         return (void*) c.Rcx;
11624     }
11625 #else
11626     PORTABILITY_ASSERT("port GetThreadUserStartAddr");
11627 #endif
11628
11629     return NULL;
11630 }
11631
11632
11633 //---------------------------------------------------------------------------------------
11634 //
11635 // Get (create if needed) the unmanaged thread for an unmanaged debug event.
11636 //
11637 // Arguments:
11638 //    event - native debug event.
11639 //
11640 // Return Value:
11641 //    Unmanaged thread corresponding to the native debug event.
11642 //
11643 //
11644 // Notes:
11645 //    Thread may be newly allocated, or may be existing. CordbProcess holds 
11646 //    list of all CordbUnmanagedThreads, and will handle freeing memory.
11647 //
11648 //---------------------------------------------------------------------------------------
11649 CordbUnmanagedThread * CordbProcess::GetUnmanagedThreadFromEvent(const DEBUG_EVENT * pEvent)
11650 {
11651     _ASSERTE(ThreadHoldsProcessLock());
11652     HRESULT hr;
11653
11654     CordbUnmanagedThread * pUnmanagedThread = NULL;
11655
11656     // Remember newly created threads.
11657     if (pEvent->dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT)
11658     {
11659         // We absolutely should have an unmanaged callback by this point.
11660         // That means that the client debugger should have called ICorDebug::SetUnmanagedHandler by now.
11661         // However, we can't actually enforce that (see comment  in ICorDebug::SetUnmanagedHandler for details), 
11662         // so we do a runtime check to check this. 
11663         // This is an extremely gross API misuse and an issue in the client if the callback is not set yet.
11664         // Without the unmanaged callback, we absolutely can't do interop-debugging. We assert (checked builds) and 
11665         // dispatch unrecoverable error (retail builds) to avoid an AV.
11666
11667
11668         if (this->m_cordb->m_unmanagedCallback == NULL)
11669         {
11670             CONSISTENCY_CHECK_MSGF((this->m_cordb->m_unmanagedCallback != NULL), 
11671                 ("GROSS API misuse!!\nNo unmanaged callback set by the time we've received CreateProcess debug event for proces 0x%x.\n", 
11672                 pEvent->dwProcessId));
11673                 
11674             CORDBSetUnrecoverableError(this, CORDBG_E_INTEROP_NOT_SUPPORTED, 0);
11675
11676             // Returning NULL will tell caller not to dispatch event to client. We have no callback object to dispatch upon.
11677             return NULL;
11678         }
11679         
11680         pUnmanagedThread = this->HandleUnmanagedCreateThread(pEvent->dwThreadId,
11681                                                              pEvent->u.CreateProcessInfo.hThread,
11682                                                              pEvent->u.CreateProcessInfo.lpThreadLocalBase);
11683
11684         // Managed-attach won't start until after Cordbg continues from the loader-bp.
11685     }
11686     else if (pEvent->dwDebugEventCode == CREATE_THREAD_DEBUG_EVENT)
11687     {
11688         pUnmanagedThread = this->HandleUnmanagedCreateThread(pEvent->dwThreadId,
11689                                                              pEvent->u.CreateThread.hThread,
11690                                                              pEvent->u.CreateThread.lpThreadLocalBase);
11691
11692         BOOL fBlockExists = FALSE;
11693         hr = S_OK;
11694         EX_TRY
11695         {
11696             // See if we have the debugger control block yet...
11697
11698             this->GetEventBlock(&fBlockExists);
11699
11700             // If we have the debugger control block, and if that control block has the address of the thread proc for
11701             // the helper thread, then we're initialized enough on the Left Side to recgonize the helper thread based on
11702             // its thread proc's address.
11703             if (this->GetDCB() != NULL) 
11704             {
11705                 // get the latest LS DCB information
11706                 UpdateRightSideDCB();
11707                 if ((this->GetDCB()->m_helperThreadStartAddr != NULL) && (pUnmanagedThread != NULL))
11708                 {
11709                     void * pStartAddr = GetThreadUserStartAddr(pEvent);
11710
11711                     if (pStartAddr == this->GetDCB()->m_helperThreadStartAddr)
11712                     {
11713                         // Remember the ID of the helper thread.
11714                         this->m_helperThreadId = pEvent->dwThreadId;
11715
11716                         LOG((LF_CORDB, LL_INFO1000, "W32ET::W32EL: Left Side Helper Thread is 0x%x\n", pEvent->dwThreadId));
11717                     }
11718                 }
11719             }
11720         }
11721         EX_CATCH_HRESULT(hr)
11722         {
11723             if (fBlockExists && FAILED(hr))
11724             {                        
11725                 _ASSERTE(IsLegalFatalError(hr));
11726                 // Send up the DebuggerError event
11727                 this->UnrecoverableError(hr, 0, NULL, 0);
11728
11729                 // Kill the process.
11730                 // RS will pump events until we LS process exits.
11731                 TerminateProcess(this->m_handle, hr);
11732
11733                 return pUnmanagedThread;            
11734             }
11735         }
11736     }
11737     else
11738     {
11739         // Find the unmanaged thread that this event is for.
11740         pUnmanagedThread = this->GetUnmanagedThread(pEvent->dwThreadId);
11741     }
11742
11743     return pUnmanagedThread;
11744 }
11745
11746 //---------------------------------------------------------------------------------------
11747 //
11748 // Handle a native-debug event representing a managed sync-complete event.
11749 //
11750 //
11751 // Return Value:
11752 //    Reaction telling caller how to respond to the native-debug event.
11753 //
11754 // Assumptions:
11755 //    Called within the Triage process after receiving a native-debug event.
11756 //
11757 //---------------------------------------------------------------------------------------
11758 Reaction CordbProcess::TriageSyncComplete()
11759 {
11760     _ASSERTE(ThreadHoldsProcessLock());
11761
11762     STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::TSC: received 'sync complete' flare.\n");
11763
11764     _ASSERTE(IsInteropDebugging());
11765
11766     // Note: we really don't need to be suspending Runtime threads that we know have tripped
11767     // here. If we ever end up with a nice, quick way to know that about each unmanaged thread, then
11768     // we should put that to good use here.
11769     this->SuspendUnmanagedThreads();
11770
11771     this->HandleSyncCompleteRecieved();
11772
11773     // Let the process run free.
11774     return REACTION(cIgnore);
11775
11776     // At this point, all managed threads are stopped at safe places and all unmanaged
11777     // threads are either suspended or hijacked. All stopped managed threads are also hard
11778     // suspended (due to the call to SuspendUnmanagedThreads above) except for the thread
11779     // that sent the sync complete flare.
11780
11781     // We've handled this exception, so skip all further processing.
11782     UNREACHABLE();
11783 }
11784
11785 //-----------------------------------------------------------------------------
11786 // Triage a breakpoint (non-flare) on a "normal" thread.
11787 //-----------------------------------------------------------------------------
11788 Reaction CordbProcess::TriageBreakpoint(CordbUnmanagedThread * pUnmanagedThread, const DEBUG_EVENT * pEvent)
11789 {
11790     _ASSERTE(ThreadHoldsProcessLock());
11791
11792     HRESULT hr = S_OK;
11793
11794     DWORD dwExCode = pEvent->u.Exception.ExceptionRecord.ExceptionCode;
11795     const void * pExAddress = pEvent->u.Exception.ExceptionRecord.ExceptionAddress;
11796
11797     _ASSERTE(dwExCode == STATUS_BREAKPOINT);
11798
11799     // There are three cases here:
11800     //
11801     // 1. The breakpoint definetly belongs to the Runtime. (I.e., a BP in our patch table that
11802     // is in managed code.) In this case, we continue the process with
11803     // DBG_EXCEPTION_NOT_HANDLED, which lets the in-process exception logic kick in as if we
11804     // weren't here.
11805     //
11806     // 2. The breakpoint is definetly not ours. (I.e., a BP that is not in our patch table.) We
11807     // pass these up as regular exception events, doing the can't stop check as usual.
11808     //
11809     // 3. We're not sure. (I.e., a BP in our patch table, but set in unmangaed code.) In this
11810     // case, we hijack as usual, also with can't stop check as usual.
11811
11812     bool fPatchFound = false;
11813     bool fPatchIsUnmanaged = false;
11814
11815     hr = this->FindPatchByAddress(PTR_TO_CORDB_ADDRESS(pExAddress),
11816                                   &fPatchFound,
11817                                   &fPatchIsUnmanaged);
11818
11819     if (SUCCEEDED(hr))
11820     {
11821         if (fPatchFound)
11822         {
11823 #ifdef _DEBUG
11824             // What if managed & native patch the same address? That could happen on a step out M --> U.
11825             {
11826                 NativePatch * pNativePatch = GetNativePatch(pExAddress);
11827                 SIMPLIFYING_ASSUMPTION_MSGF(pNativePatch == NULL, ("Have Managed & native patch at 0x%p", pExAddress));
11828             }
11829 #endif
11830
11831             // BP could be ours... if its unmanaged, then we still need to hijack, so fall
11832             // through to that logic. Otherwise, its ours.
11833             if (!fPatchIsUnmanaged)
11834             {
11835                 LOG((LF_CORDB, LL_INFO1000, "W32ET::W32EL: breakpoint exception "
11836                      "belongs to runtime due to patch table match.\n"));
11837
11838                 return REACTION(cCLR);
11839             }
11840             else
11841             {
11842                 LOG((LF_CORDB, LL_INFO1000, "W32ET::W32EL: breakpoint exception "
11843                      "matched in patch table, but its unmanaged so might hijack anyway.\n"));
11844
11845                 // If we're in cooperative mode, then we must have a inproc handler, and don't need to hijack
11846                 // One way this can happen is the patch placed for a func-eval complete is hit in coop-mode.
11847                 if (pUnmanagedThread->GetEEPGCDisabled())
11848                 {
11849                     LOG((LF_CORDB, LL_INFO10000, "Already in coop-mode, don't need to hijack\n"));
11850                     return REACTION(cCLR);
11851                 }
11852                 else
11853                 {
11854                     return REACTION(cBreakpointRequiringHijack);
11855                 }
11856             }
11857
11858             UNREACHABLE();
11859         }
11860         else // Patch not found
11861         {
11862             // If we're here, then we have a BP that's not in the managed patch table, and not
11863             // in the native patch list. This should be rare. Perhaps an int3 / DebugBreak() / Assert in
11864             // the native code stream.
11865             // Anyway, we don't know about this patch so we can't skip it. The only thing we can do
11866             // is chuck it up to Cordbg and hope they can help us. Note that this is the same case
11867             // we were in w. V1.
11868
11869             // BP doesn't belong to CLR ... so dispatch it to Cordbg as either make it IB or OOB.
11870             // @todo - make the runtime 1 giant Can't stop region.
11871             bool fCantStop = pUnmanagedThread->IsCantStop();
11872
11873 #ifdef _DEBUG
11874             // We rarely expect a raw int3 here. Add a debug check that will assert.
11875             // Tests that know they don't have raw int3 can enable this regkey to get
11876             // extra coverage.
11877             static DWORD s_fBreakOnRawInt3 = -1;
11878
11879             if (s_fBreakOnRawInt3 == -1)
11880                 s_fBreakOnRawInt3 = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgBreakOnRawInt3);
11881
11882             if (s_fBreakOnRawInt3)
11883             {
11884                 CONSISTENCY_CHECK_MSGF(false, ("Unexpected Raw int3 at:%p on tid 0x%x (%d). CantStop=%d."
11885                     "This assert is used by specific tests to get extra checks."
11886                     "For normal cases it's ignorable and is enabled by setting DbgBreakOnRawInt3==1.",
11887                     pExAddress, pEvent->dwThreadId, pEvent->dwThreadId, fCantStop));
11888             }
11889 #endif
11890
11891             if (fCantStop)
11892             {
11893                 // If we're in a can't stop region, then its OOB no matter what at this point.
11894                 return REACTION(cOOB);
11895             }
11896             else
11897             {
11898                 // PGC must be enabled if we're going to stop for an IB event.
11899                 bool PGCDisabled = pUnmanagedThread->GetEEPGCDisabled();
11900                 _ASSERTE(!PGCDisabled);
11901
11902                 // Bp is definitely not ours, and PGC is not disabled, so in-band exception.
11903                 LOG((LF_CORDB, LL_INFO1000, "W32ET::W32EL: breakpoint exception "
11904                      "does not belong to the runtime due to failed patch table match.\n"));
11905
11906                 return REACTION(cInband);
11907             }
11908
11909             UNREACHABLE();
11910         }
11911
11912         UNREACHABLE();
11913     }
11914     else
11915     {
11916         // Patch table lookup failed? Only on OOM or if ReadProcessMemory fails...
11917         _ASSERTE(!"Patch table lookup failed!");
11918         CORDBSetUnrecoverableError(this, hr, 0);
11919         return REACTION(cOOB);
11920     }
11921
11922     UNREACHABLE();
11923 }
11924
11925 //---------------------------------------------------------------------------------------
11926 //
11927 // Triage a "normal" 1st chance exception on a "normal" thread.
11928 // Not hijacked, not the helper thread, not a flare, etc.. This is the common
11929 // case for a native exception from native code.
11930 //
11931 // Arguments:
11932 //     pUnmanagedThread - Pointer to the CordbUnmanagedThread object that we want to hijack.
11933 //     pEvent - Pointer to the debug event which contains the exception code and address.
11934 //
11935 // Return Value:
11936 //     The Reaction tells if the event is in-band, out-of-band, CLR specific or ignorable.
11937 //
11938 //---------------------------------------------------------------------------------------
11939 Reaction CordbProcess::Triage1stChanceNonSpecial(CordbUnmanagedThread * pUnmanagedThread, const DEBUG_EVENT * pEvent)
11940 {
11941     _ASSERTE(ThreadHoldsProcessLock());
11942     CONTRACTL
11943     {
11944         THROWS;
11945     }
11946     CONTRACTL_END;
11947
11948     HRESULT hr = S_OK;
11949
11950     DWORD dwExCode = pEvent->u.Exception.ExceptionRecord.ExceptionCode;
11951     const void * pExAddress = pEvent->u.Exception.ExceptionRecord.ExceptionAddress;
11952
11953     // This had better not be a flare. If it is, that means we have some race that unmarked
11954     // the hijacks.
11955     _ASSERTE(!ExceptionIsFlare(dwExCode, pExAddress));
11956
11957     // Any first chance exception could belong to the Runtime, so long as the Runtime has actually been
11958     // initialized. Here we'll setup a first-chance hijack for this thread so that it can give us the
11959     // true answer that we need.
11960
11961     // But none of those exceptions could possibly be ours unless we have a managed thread to go with
11962     // this unmanaged thread. A non-NULL EEThreadPtr tells us that there is indeed a managed thread for
11963     // this unmanaged thread, even if the Right Side hasn't received a managed ThreadCreate message yet.
11964     REMOTE_PTR pEEThread;
11965     hr = pUnmanagedThread->GetEEThreadPtr(&pEEThread);
11966     _ASSERTE(SUCCEEDED(hr));
11967
11968     if (pEEThread == NULL)
11969     {
11970         // No managed thread, so it can't possibly belong to the runtime!
11971         // But it may still be in a can't-stop region (think some goofy shutdown case).
11972         if (pUnmanagedThread->IsCantStop())
11973         {
11974             return REACTION(cOOB);
11975         }
11976         else
11977         {
11978             return REACTION(cInband);
11979         }
11980     }
11981
11982
11983
11984     // We have to be careful here. A Runtime thread may be in a place where we cannot let an
11985     // unmanaged exception stop it. For instance, an unmanaged user breakpoint set on
11986     // WaitForSingleObject will prevent Runtime threads from sending events to the Right Side. So at
11987     // various points below, we check to see if this Runtime thread is in a place were we can't let
11988     // it stop, and if so then we jump over to the out-of-band dispatch logic and treat this
11989     // exception as out-of-band. The debugger is supposed to continue from the out-of-band event
11990     // properly and help us avoid this problem altogether.
11991
11992     // Grab a few flags from the thread's state...
11993     bool fThreadStepping = false;
11994     bool fSpecialManagedException = false;
11995
11996     pUnmanagedThread->GetEEState(&fThreadStepping, &fSpecialManagedException);
11997
11998     // If we've got a single step exception, and if the Left Side has indicated that it was
11999     // stepping the thread, then the exception is ours.
12000     if (dwExCode == STATUS_SINGLE_STEP)
12001     {
12002         if (fThreadStepping)
12003         {
12004             // Yup, its the Left Side that was stepping the thread...
12005             STRESS_LOG0(LF_CORDB, LL_INFO1000, "W32ET::W32EL: single step exception belongs to the runtime.\n");
12006
12007             return REACTION(cCLR);
12008         }
12009
12010         // Any single step that is triggered when the thread's state doesn't indicate that
12011         // we were stepping the thread automatically gets passed out as an unmanged event.
12012         STRESS_LOG0(LF_CORDB, LL_INFO1000, "W32ET::W32EL: single step exception "
12013              "does not belong to the runtime.\n");
12014
12015         if (pUnmanagedThread->IsCantStop())
12016         {
12017             return REACTION(cOOB);
12018         }
12019         else
12020         {
12021             return REACTION(cInband);
12022         }
12023
12024         UNREACHABLE();
12025     }
12026
12027 #ifdef CorDB_Short_Circuit_First_Chance_Ownership
12028     // If the runtime indicates that this is a special exception being thrown within the runtime,
12029     // then its ours no matter what.
12030     else if (fSpecialManagedException)
12031     {
12032         STRESS_LOG0(LF_CORDB, LL_INFO1000, "W32ET::W32EL: exception belongs to the runtime due to "
12033              "special managed exception marking.\n");
12034
12035         return REACTION(cCLR);
12036     }
12037     else if ((dwExCode == EXCEPTION_COMPLUS) || (dwExCode == EXCEPTION_HIJACK))
12038     {
12039         STRESS_LOG0(LF_CORDB, LL_INFO1000,
12040              "W32ET::W32EL: exception belongs to Runtime due to match on built in exception code\n");
12041
12042         return REACTION(cCLR);
12043     }
12044     else if (dwExCode == EXCEPTION_MSVC)
12045     {
12046         // The runtime may use C++ exceptions internally. We can still report these 
12047         // to the debugger as long as we're outside of a can't-stop region.
12048         if (pUnmanagedThread->IsCantStop())
12049         {
12050             return REACTION(cCLR);
12051         }
12052         else
12053         {
12054             return REACTION(cInband);
12055         }
12056     }
12057     else if (dwExCode == STATUS_BREAKPOINT)
12058     {
12059         return TriageBreakpoint(pUnmanagedThread, pEvent);
12060     }// end BP case
12061 #endif
12062
12063     // It's not a breakpoint or single-step. Now it just comes down to the address from where
12064     // the exception is coming from. If it's managed, we give it back to the CLR. If it's
12065     // from native, then we dispatch to Cordbg.
12066     // We can use DAC to figure this out from Out-of-process.
12067     _ASSERTE(dwExCode != STATUS_BREAKPOINT); // BP were already handled.
12068
12069
12070     // Use DAC to decide if it's ours or not w/o going inproc.
12071     CORDB_ADDRESS address = PTR_TO_CORDB_ADDRESS(pExAddress);
12072
12073     IDacDbiInterface::AddressType addrType;
12074
12075     addrType = GetDAC()->GetAddressType(address);
12076     bool fIsCorCode =((addrType == IDacDbiInterface::kAddressManagedMethod) ||
12077                       (addrType == IDacDbiInterface::kAddressRuntimeManagedCode) ||
12078                       (addrType == IDacDbiInterface::kAddressRuntimeUnmanagedCode));
12079
12080     STRESS_LOG2(LF_CORDB, LL_INFO1000, "W32ET::W32EL: IsCorCode(0x%I64p)=%d\n", address, fIsCorCode);
12081
12082
12083     if (fIsCorCode)
12084     {
12085         return REACTION(cCLR);
12086     }
12087     else
12088     {
12089         if (pUnmanagedThread->IsCantStop())
12090         {
12091             return REACTION(cOOB);
12092         }
12093         else
12094         {
12095             return REACTION(cInband);
12096         }        
12097     }
12098
12099     UNREACHABLE();
12100 }
12101
12102 //---------------------------------------------------------------------------------------
12103 //
12104 // Triage a 1st-chance exception when the CLR is initialized.
12105 //
12106 // Arguments:
12107 //    pUnmanagedThread - thread that the event has occurred on.
12108 //    pEvent - native debug event for the exception that occurred that this is triaging.
12109 //
12110 // Return Value:
12111 //    Reaction for how to handle this event.
12112 //
12113 // Assumptions:
12114 //    Called when receiving a debug event when the process is stopped.
12115 //
12116 // Notes:
12117 //    A 1st-chance event has a wide spectrum of possibility including:
12118 //    - It may be unmanaged or managed. 
12119 //    - Or it may be an execution control exception for managed-exceution 
12120 //    - thread skipping an OOB event.
12121 //
12122 //---------------------------------------------------------------------------------------
12123 Reaction CordbProcess::TriageExcep1stChanceAndInit(CordbUnmanagedThread * pUnmanagedThread, 
12124                                                    const DEBUG_EVENT * pEvent)
12125 {
12126     _ASSERTE(ThreadHoldsProcessLock());
12127     _ASSERTE(m_runtimeOffsetsInitialized);
12128
12129     NativePatch * pNativePatch = NULL;
12130     DebuggerIPCRuntimeOffsets * pIPCRuntimeOffsets = &(this->m_runtimeOffsets);
12131
12132     DWORD dwExCode = pEvent->u.Exception.ExceptionRecord.ExceptionCode;
12133     const void * pExAddress = pEvent->u.Exception.ExceptionRecord.ExceptionAddress;
12134
12135
12136 #ifdef _DEBUG
12137     // Some Interop bugs involve threads that land at a crazy IP. Since we're interop-debugging, we can't
12138     // attach a debugger to the LS. So we have some debug mode where we enable the SS flag and thus
12139     // produce a trace of where a thread is going.
12140     if (pUnmanagedThread->IsDEBUGTrace() && (dwExCode == STATUS_SINGLE_STEP))
12141     {
12142         pUnmanagedThread->ClearState(CUTS_DEBUG_SingleStep);
12143         LOG((LF_CORDB, LL_INFO10000, "DEBUG TRACE, thread %4x at IP: 0x%p\n", pUnmanagedThread->m_id, pExAddress));
12144
12145         // Clear the exception and pretend this never happened.
12146         return REACTION(cIgnore);
12147     }
12148 #endif
12149
12150     // If we were stepping for exception retrigger and got the single step and it should be hidden then just ignore it.
12151     // Anything that isn't cInbandExceptionRetrigger will cause the debug event to be dequeued, stepping turned off, and
12152     // it will count as not retriggering
12153     // TODO: I don't think the IsSSFlagNeeded() check is needed here though it doesn't break anything
12154     if (pUnmanagedThread->IsSSFlagNeeded() && pUnmanagedThread->IsSSFlagHidden() && (dwExCode == STATUS_SINGLE_STEP))
12155     {
12156         LOG((LF_CORDB, LL_INFO10000, "CP::TE1stCAI: ignoring hidden single step\n"));
12157         return REACTION(cIgnore);
12158     }
12159
12160     // Is this a breakpoint indicating that the Left Side is now synchronized?
12161     if ((dwExCode == STATUS_BREAKPOINT) &&
12162         (pExAddress == pIPCRuntimeOffsets->m_notifyRSOfSyncCompleteBPAddr))
12163     {
12164         return TriageSyncComplete();
12165     }
12166     else if ((dwExCode == STATUS_BREAKPOINT) &&
12167              (pExAddress == pIPCRuntimeOffsets->m_excepForRuntimeHandoffCompleteBPAddr))
12168     {
12169         _ASSERTE(!"This should be unused now");
12170
12171         // This notification means that a thread that had been first-chance hijacked is now
12172         // finally leaving the hijack.
12173         STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::TE1stCAI: received 'first chance hijack handoff complete' flare.\n");
12174
12175         // Let the process run.
12176         return REACTION(cIgnore);
12177     }
12178     else if ((dwExCode == STATUS_BREAKPOINT) &&
12179              (pExAddress == pIPCRuntimeOffsets->m_signalHijackCompleteBPAddr))
12180     {
12181         STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::TE1stCAI: received 'hijack complete' flare.\n");
12182         return REACTION(cInbandHijackComplete);
12183     }
12184     else if ((dwExCode == STATUS_BREAKPOINT) &&
12185              (pExAddress == m_runtimeOffsets.m_signalHijackStartedBPAddr))
12186     {
12187         STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::TE1stCAI: received 'hijack started' flare.\n");
12188         return REACTION(cFirstChanceHijackStarted);
12189     }
12190     else if ((dwExCode == STATUS_BREAKPOINT) && ((pNativePatch = GetNativePatch(pExAddress)) != NULL) )
12191     {
12192         // We hit a native BP placed by Cordbg.  This could happen on any thread (including helper)
12193         bool fCantStop = pUnmanagedThread->IsCantStop();
12194
12195         // REVISIT_TODO: if the user also set a breakpoint here then we should dispatch to the debugger
12196         // and rely on the debugger to get us past this. Should be a rare case though.
12197         if (fCantStop)
12198         {
12199             // Need to skip it completely; never dispatch.
12200             pUnmanagedThread->SetupForSkipBreakpoint(pNativePatch);
12201
12202             // Debuggee will single step over the patch, and fire a SS exception.
12203             // We'll then call FixupForSkipBreakpoint, and continue the process.
12204             return REACTION(cIgnore);
12205         }
12206         else
12207         {
12208             // Native patch in native code. A very common scenario.
12209             // Dispatch as an IB event to Cordbg.
12210             STRESS_LOG1(LF_CORDB, LL_INFO10000, "Native patch in native code (at %p), dispatching as IB event.\n", pExAddress);
12211             return REACTION(cInband);
12212         }
12213
12214         UNREACHABLE();
12215     }
12216
12217     else if ((dwExCode == STATUS_BREAKPOINT) && !IsBreakOpcodeAtAddress(pExAddress))
12218     {
12219         // If we got an int3 exception, but there's not actually an int3 at the address, then just reset the IP
12220         // to the address. This can happen if the int 3 is cleared after the thread has dispatched it (in which case
12221         // WFDE will pick it up) but before we realize it's one of ours.
12222         STRESS_LOG2(LF_CORDB, LL_INFO1000, "CP::TE1stCAI: Phantom Int3: Tid=0x%x, addr=%p\n", pEvent->dwThreadId, pExAddress);
12223
12224         DT_CONTEXT context;
12225
12226         context.ContextFlags = DT_CONTEXT_FULL;
12227
12228         BOOL fSuccess = DbiGetThreadContext(pUnmanagedThread->m_handle, &context);
12229
12230         _ASSERTE(fSuccess);
12231
12232         if (fSuccess)
12233         {
12234             // Backup IP to point to the instruction we need to execute. Continuing from a breakpoint exception
12235             // continues execution at the instruction after the breakpoint, but we need to continue where the
12236             // breakpoint was.
12237             CORDbgSetIP(&context, (LPVOID) pExAddress);
12238
12239             fSuccess = DbiSetThreadContext(pUnmanagedThread->m_handle, &context);
12240             _ASSERTE(fSuccess);
12241         }
12242
12243         return REACTION(cIgnore);
12244     }
12245     else if (pUnmanagedThread->IsSkippingNativePatch())
12246     {
12247         // If we Single-Step over an exception, then the OS never gives us the single-step event.
12248         // Thus if we're skipping a native patch, we don't care what exception event we got.
12249         LOG((LF_CORDB, LL_INFO100000, "Done skipping native patch. Ex=0x%x\n, IsSS=%d", 
12250              dwExCode, 
12251              (dwExCode == STATUS_SINGLE_STEP)));
12252
12253         // This is the 2nd half of skipping a native patch.
12254         // This could happen on any thread (including helper)
12255         // We've already removed the opcode and now we just finished a single-step over it.
12256         // So put the patch back in, and continue the process.
12257         pUnmanagedThread->FixupForSkipBreakpoint();
12258
12259         return REACTION(cIgnore);
12260     }
12261     else if (this->IsHelperThreadWorked(pUnmanagedThread->GetOSTid()))
12262     {
12263         // We should never ever get a single-step event from the helper thread.
12264         CONSISTENCY_CHECK_MSGF(dwExCode != STATUS_SINGLE_STEP, (
12265                 "Single-Step exception on helper thread (tid=0x%x/%d) in debuggee process (pid=0x%x/%d).\n"
12266                 "For more information, attach a debuggee non-invasively to the LS to get the callstack.\n",
12267                 pUnmanagedThread->m_id, 
12268                 pUnmanagedThread->m_id, 
12269                 this->m_id, 
12270                 this->m_id));
12271
12272         // We ignore any first chance exceptions from the helper thread. There are lots of places
12273         // on the left side where we attempt to dereference bad object refs and such that will be
12274         // handled by exception handlers already in place.
12275         //
12276         // Note: we check this after checking for the sync complete notification, since that can
12277         // come from the helper thread.
12278         //
12279         // Note: we do let single step and breakpoint exceptions go through to the debugger for processing.
12280         if ((dwExCode != STATUS_BREAKPOINT) && (dwExCode != STATUS_SINGLE_STEP))
12281         {
12282             return REACTION(cCLR);
12283         }
12284         else
12285         {
12286             // Since the helper thread is part of the "can't stop" region, we should have already
12287             // skipped any BPs on it.
12288             // However, any Assert on the helper thread will hit this case.
12289             CONSISTENCY_CHECK_MSGF((dwExCode != STATUS_BREAKPOINT), (
12290                 "Assert on helper thread (tid=0x%x/%d) in debuggee process (pid=0x%x/%d).\n"
12291                 "For more information, attach a debuggee non-invasively to the LS to get the callstack.\n",
12292                 pUnmanagedThread->m_id, 
12293                 pUnmanagedThread->m_id, 
12294                 this->m_id, 
12295                 this->m_id));
12296
12297             // These breakpoint and single step exceptions have to be dispatched to the debugger as
12298             // out-of-band events. This tells the debugger that they must continue from these events
12299             // immediatly, and that no interaction with the Left Side is allowed until they do so. This
12300             // makes sense, since these events are on the helper thread.
12301             return REACTION(cOOB);
12302         }
12303         UNREACHABLE();
12304     }
12305     else if (pUnmanagedThread->IsFirstChanceHijacked() && this->ExceptionIsFlare(dwExCode, pExAddress))
12306     {
12307         _ASSERTE(!"This should be unused now");
12308     }
12309     else if (pUnmanagedThread->IsGenericHijacked())
12310     {
12311         if (this->ExceptionIsFlare(dwExCode, pExAddress))
12312         {
12313             STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::TE1stCAI: fixing up from generic hijack.\n");
12314
12315             _ASSERTE(dwExCode == STATUS_BREAKPOINT);
12316
12317             // Fixup the thread from the generic hijack.
12318             pUnmanagedThread->FixupFromGenericHijack();
12319
12320             // We force continue from this flare, since its only purpose was to notify us that we had to
12321             // fixup the thread from a generic hijack.
12322             return REACTION(cIgnore);
12323         }
12324         else
12325         {
12326             // We might reach here due to the stack overflow issue, due to target
12327             // memory corruption, or even due to an exception thrown during hijacking
12328
12329             BOOL bStackOverflow = FALSE;
12330
12331             if (dwExCode == STATUS_ACCESS_VIOLATION || dwExCode == STATUS_STACK_OVERFLOW)
12332             {
12333                 CORDB_ADDRESS stackLimit;
12334                 CORDB_ADDRESS stackBase;
12335                 if (pUnmanagedThread->GetStackRange(&stackBase, &stackLimit))
12336                 {
12337                     TADDR addr = pEvent->u.Exception.ExceptionRecord.ExceptionInformation[1];
12338                     if (stackLimit <= addr && addr < stackBase)
12339                         bStackOverflow = TRUE;
12340                 }
12341                 else
12342                 {
12343                     // to limit the impact of the change we'll consider failure to retrieve the stack
12344                     // bounds as stack overflow as well
12345                     bStackOverflow = TRUE;
12346                 }
12347             }
12348
12349             if (!bStackOverflow)
12350             {
12351                 // generic hijack means we're in CantStop, so return cOOB
12352                 return REACTION(cOOB);
12353             }
12354
12355             // If generichijacked and its not a flare, and the address referenced is on the stack then we've 
12356             // got our special stack overflow case. Take off generic hijacked, mark that the helper thread 
12357             // is dead, throw this event on the floor, and pop anyone in SendIPCEvent out of their wait.
12358             pUnmanagedThread->ClearState(CUTS_GenericHijacked);
12359             
12360             this->m_helperThreadDead = true;
12361             
12362             // This only works on Windows, not on Mac.  We don't support interop-debugging on Mac anyway.
12363             SetEvent(m_pEventChannel->GetRightSideEventAckHandle());
12364
12365             // Note: we remember that this was a second chance event from one of the special stack overflow
12366             // cases with CUES_ExceptionUnclearable. This tells us to force the process to terminate when we
12367             // continue from the event. Since for some odd reason the OS decides to re-raise this exception
12368             // (first chance then second chance) infinitely.
12369
12370             _ASSERTE(pUnmanagedThread->HasIBEvent());
12371
12372             pUnmanagedThread->IBEvent()->SetState(CUES_ExceptionUnclearable);
12373
12374             //newEvent = false;
12375             return REACTION(cInband_NotNewEvent);
12376         }
12377     }
12378     else
12379     {
12380         Reaction r(REACTION(cOOB));
12381         HRESULT hrCheck = S_OK;;
12382         EX_TRY
12383         {
12384             r = Triage1stChanceNonSpecial(pUnmanagedThread, pEvent);
12385         }
12386         EX_CATCH_HRESULT(hrCheck);
12387         SIMPLIFYING_ASSUMPTION(SUCCEEDED(hrCheck));
12388         SetUnrecoverableIfFailed(this, hrCheck);
12389
12390         return r;
12391
12392     }
12393
12394     // At this point, any first-chance exceptions that could be special have been handled. Any
12395     // first-chance exception that we're still processing at this point is destined to be
12396     // dispatched as an unmanaged event.
12397     UNREACHABLE();
12398 }
12399
12400
12401 //---------------------------------------------------------------------------------------
12402 //
12403 // Triage a 2nd-chance exception when the CLR is initialized.
12404 //
12405 // Arguments:
12406 //    pUnmanagedThread - thread that the event has occurred on.
12407 //    pEvent - native debug event for the exception that occurred that this is triaging.
12408 //
12409 // Return Value:
12410 //    Reaction for how to handle this event.
12411 //
12412 // Assumptions:
12413 //    Called when receiving a debug event when the process is stopped.
12414 //
12415 // Notes:
12416 //    We already hijacked 2nd-chance managed exceptions, so this is just handling 
12417 //    some V2 Interop corner cases. 
12418 //    @dbgtodo interop: this should eventually completely go away with the V3 design.
12419 //
12420 //---------------------------------------------------------------------------------------
12421 Reaction CordbProcess::TriageExcep2ndChanceAndInit(CordbUnmanagedThread * pUnmanagedThread, const DEBUG_EVENT * pEvent)
12422 {
12423     _ASSERTE(ThreadHoldsProcessLock());
12424
12425     DWORD dwExCode = pEvent->u.Exception.ExceptionRecord.ExceptionCode;
12426
12427 #ifdef _DEBUG
12428     // For debugging, add an extra knob that let us break on any 2nd chance exceptions.
12429     // Most tests don't throw 2nd-chance, so we could have this enabled most of the time and
12430     // catch bogus 2nd chance exceptions
12431     static DWORD dwNo2ndChance = -1;
12432
12433     if (dwNo2ndChance == -1)
12434     {
12435         dwNo2ndChance = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgNo2ndChance);
12436     }
12437
12438     if (dwNo2ndChance)
12439     {
12440         CONSISTENCY_CHECK_MSGF(false, ("2nd chance exception occurred on LS thread=0x%x, code=0x%08x, address=0x%p\n"
12441             "This assert is firing b/c you explicitly requested it by having the 'DbgNo2ndChance' knob enabled.\n"
12442             "Disable it to avoid asserts on 2nd chance.",
12443             pUnmanagedThread->m_id,
12444             dwExCode,
12445             pEvent->u.Exception.ExceptionRecord.ExceptionAddress));
12446     }
12447 #endif
12448
12449
12450     // Second chance exception, Runtime initialized. It could belong to the Runtime, so we'll check. If it
12451     // does, then we'll hijack the thread. Otherwise, well just fall through and let it get
12452     // dispatched. Note: we do this so that the CLR's unhandled exception logic gets a chance to run even
12453     // though we've got a win32 debugger attached. But the unhandled exception logic never touches
12454     // breakpoint or single step exceptions, so we ignore those here, too.
12455
12456     // There are strange cases with stack overflow exceptions. If a nieve application catches a stack
12457     // overflow exception and handles it, without resetting the guard page, then the app will get an AV when
12458     // it overflows the stack a second time. We will get the first chance AV, but when we continue from it the
12459     // OS won't run any SEH handlers, so our FCH won't actually work. Instead, we'll get the AV back on
12460     // second chance right away, and we'll end up right here.
12461     if (this->IsSpecialStackOverflowCase(pUnmanagedThread, pEvent))
12462     {
12463         // IsSpecialStackOverflowCase will queue the event for us, so its no longer a "new event". Setting
12464         // newEvent = false here basically prevents us from playing with the event anymore and we fall down
12465         // to the dispatch logic below, which will get our already queued first chance AV dispatched for
12466         // this thread.
12467         //newEvent = false;
12468         return REACTION(cInband_NotNewEvent);
12469     }
12470     else if (this->IsHelperThreadWorked(pUnmanagedThread->GetOSTid()))
12471     {
12472         // A second chance exception from the helper thread. This is pretty bad... we just force continue
12473         // from them and hope for the best.
12474         return REACTION(cCLR);
12475     }
12476     
12477     if(pUnmanagedThread->IsCantStop())
12478     {
12479         return REACTION(cOOB);
12480     }
12481     else
12482     {
12483         return REACTION(cInband);
12484     }
12485 }
12486
12487
12488 //---------------------------------------------------------------------------------------
12489 //
12490 // Triage a win32 Debug event to get a reaction
12491 //
12492 // Arguments:
12493 //    pUnmanagedThread - thread that the event has occurred on.
12494 //    pEvent - native debug event for the exception that occurred that this is triaging.
12495 //
12496 // Return Value:
12497 //    Reaction for how to handle this event.
12498 //
12499 // Assumptions:
12500 //    Called when receiving a debug event when the process is stopped.
12501 //
12502 // Notes:
12503 //    This is the main triage routine for Win32 debug events, this delegates to the
12504 //    1st and 2nd chance routines above appropriately.
12505 //
12506 //---------------------------------------------------------------------------------------
12507 Reaction CordbProcess::TriageWin32DebugEvent(CordbUnmanagedThread * pUnmanagedThread, const DEBUG_EVENT * pEvent)
12508 {
12509     _ASSERTE(ThreadHoldsProcessLock());
12510
12511     // Lots of special cases for exception events. The vast majority of hybrid debugging work that takes
12512     // place is in response to exception events. The work below will consider certian exception events
12513     // special cases and rather than letting them be queued and dispatched, they will be handled right
12514     // here.
12515     if (pEvent->dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
12516     {
12517         STRESS_LOG4(LF_CORDB, LL_INFO1000, "CP::TW32DE: unmanaged exception on "
12518              "tid 0x%x, code 0x%08x, addr 0x%08x, chance %d\n",
12519              pEvent->dwThreadId,
12520              pEvent->u.Exception.ExceptionRecord.ExceptionCode,
12521              pEvent->u.Exception.ExceptionRecord.ExceptionAddress,
12522              2-pEvent->u.Exception.dwFirstChance);
12523
12524 #ifdef LOGGING
12525         if (pEvent->u.Exception.ExceptionRecord.ExceptionCode == STATUS_ACCESS_VIOLATION)
12526         {
12527             LOG((LF_CORDB, LL_INFO1000, "\t<%s> address 0x%08x\n",
12528                  pEvent->u.Exception.ExceptionRecord.ExceptionInformation[0] ? "write to" : "read from",
12529                  pEvent->u.Exception.ExceptionRecord.ExceptionInformation[1]));
12530         }
12531 #endif
12532
12533         // Mark the loader bp for kicks. We won't start managed attach until native attach is finished.
12534         if (!this->m_loaderBPReceived)
12535         {
12536             // If its a first chance breakpoint, and its the first one, then its the loader breakpoint.
12537             if (pEvent->u.Exception.dwFirstChance &&
12538                 (pEvent->u.Exception.ExceptionRecord.ExceptionCode == STATUS_BREAKPOINT))
12539             {
12540                 LOG((LF_CORDB, LL_INFO1000, "CP::TW32DE: loader breakpoint received.\n"));
12541
12542                 // Remember that we've received the loader BP event.
12543                 this->m_loaderBPReceived = true;
12544
12545                 // We never hijack the loader BP anymore (CLR 2.0+).
12546                 // This is b/c w/ interop-attach, we don't start the managed-attach until _after_ Cordbg
12547                 // continues from the loader-bp.
12548             }
12549         } // end of loader bp.
12550
12551         // This event might be the retriggering of an event we already saw but previously had to hijack
12552         if(pUnmanagedThread->HasIBEvent())
12553         {
12554             const EXCEPTION_RECORD* pRecord1 = &(pEvent->u.Exception.ExceptionRecord);
12555             const EXCEPTION_RECORD* pRecord2 = &(pUnmanagedThread->IBEvent()->m_currentDebugEvent.u.Exception.ExceptionRecord);
12556             if(pRecord1->ExceptionCode == pRecord2->ExceptionCode &&
12557                 pRecord1->ExceptionFlags == pRecord2->ExceptionFlags &&
12558                 pRecord1->ExceptionAddress == pRecord2->ExceptionAddress)
12559             {
12560                 STRESS_LOG0(LF_CORDB, LL_INFO1000, "CP::TW32DE: event is continuation of previously hijacked event.\n");
12561                 // if we continued from the hijack then we should have already dispatched this event
12562                 _ASSERTE(pUnmanagedThread->IBEvent()->IsDispatched());
12563                 return REACTION(cInbandExceptionRetrigger);
12564             }
12565         }
12566
12567         // We only care about exception events if they are first chance events and if the Runtime is
12568         // initialized within the process. Otherwise, we don't do anything special with them.
12569         if (pEvent->u.Exception.dwFirstChance && this->m_initialized)
12570         {
12571             return TriageExcep1stChanceAndInit(pUnmanagedThread, pEvent);
12572         }
12573         else if (!pEvent->u.Exception.dwFirstChance && this->m_initialized)
12574         {
12575             return TriageExcep2ndChanceAndInit(pUnmanagedThread, pEvent);
12576         }
12577         else
12578         {
12579             // An exception event, but the Runtime hasn't been initialize. I.e., its an exception event
12580             // that we will never try to hijack.
12581             return REACTION(cInband);
12582         }
12583
12584         UNREACHABLE();
12585     }
12586     else
12587     // OOB
12588     {
12589         return REACTION(cOOB);
12590     }
12591
12592 }
12593
12594 //---------------------------------------------------------------------------------------
12595 //
12596 // Top-level handler for a win32 debug event during Interop-debugging.
12597 //
12598 // Arguments:
12599 //    event - native debug event to handle.
12600 //
12601 // Assumptions:
12602 //    The process just got a native debug event via WaitForDebugEvent
12603 //
12604 // Notes:
12605 //    The function will Triage the excpetion and then handle it based on the
12606 //    appropriate reaction (see: code:Reaction).
12607 //
12608 // @dbgtodo interop: this should all go into the shim.
12609 //---------------------------------------------------------------------------------------
12610 void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEvent)
12611 {
12612     PUBLIC_API_ENTRY_FOR_SHIM(this);
12613     _ASSERTE(IsInteropDebugging() || !"Only do this in real interop handling path");
12614
12615
12616     STRESS_LOG3(LF_CORDB, LL_INFO1000, "W32ET::W32EL: got unmanaged event %d on thread 0x%x, proc 0x%x\n",
12617          pEvent->dwDebugEventCode, pEvent->dwThreadId, pEvent->dwProcessId);
12618
12619     // Get the Lock.
12620     _ASSERTE(!this->ThreadHoldsProcessLock());
12621
12622     RSSmartPtr<CordbProcess> pRef(this); // make sure we're alive...
12623
12624     RSLockHolder processLockHolder(&this->m_processMutex);
12625
12626     // If we get a new Win32 Debug event, then we need to flush any cached oop data structures.
12627     // This includes refreshing DAC and our patch table.
12628     ForceDacFlush();
12629     ClearPatchTable();
12630
12631 #ifdef _DEBUG
12632     // We want to detect if we've deadlocked. Unfortunately, w/ interop debugging, there can be a lot of
12633     // deadtime since we need to wait for a debug event. Thus the CPU usage may appear to be at 0%, but
12634     // we're not deadlocked b/c we're still receiving debug events.
12635     // So ping every X debug events.
12636     static int s_cCount = 0;
12637     static int s_iPingLevel = -1;
12638     if (s_iPingLevel == -1)
12639     {
12640         s_iPingLevel = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgPingInterop);
12641     }
12642     if (s_iPingLevel != 0)
12643     {
12644         s_cCount++;
12645         if (s_cCount >= s_iPingLevel)
12646         {
12647             s_cCount = 0;
12648             ::Beep(1000,100);
12649
12650             // Refresh so we can adjust ping level midstream.
12651             s_iPingLevel = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgPingInterop);
12652         }
12653     }
12654 #endif
12655
12656     bool fNewEvent = true;
12657
12658     // Mark the process as stopped.
12659     this->m_state |= CordbProcess::PS_WIN32_STOPPED;
12660
12661     CordbUnmanagedThread * pUnmanagedThread = GetUnmanagedThreadFromEvent(pEvent);
12662
12663     // In retail, if there is no unmanaged thread then we just continue and loop back around. UnrecoverableError has
12664     // already been set in this case. Note: there is an issue in the Win32 debugging API that can cause duplicate
12665     // ExitThread events. We therefore must handle not finding an unmanaged thread gracefully.
12666
12667     _ASSERTE((pUnmanagedThread != NULL) || (pEvent->dwDebugEventCode == EXIT_THREAD_DEBUG_EVENT));
12668
12669     if (pUnmanagedThread == NULL)
12670     {
12671         // Note: we use ContinueDebugEvent directly here since our continue is very simple and all of our other
12672         // continue mechanisms rely on having an UnmanagedThread object to play with ;)
12673         STRESS_LOG2(LF_CORDB, LL_INFO1000, "W32ET::W32EL: Continuing without thread on tid 0x%x, code=0x%x\n", 
12674                     pEvent->dwThreadId, 
12675                     pEvent->dwDebugEventCode);
12676
12677         this->m_state &= ~CordbProcess::PS_WIN32_STOPPED;
12678
12679         BOOL fOk = ContinueDebugEvent(pEvent->dwProcessId, pEvent->dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
12680
12681         _ASSERTE(fOk || !"ContinueDebugEvent failed when he have no thread. Debuggee is likely hung");
12682
12683         return;
12684     }
12685
12686     // There's an innate race such that we can get a Debug Event even after we've suspended a thread.
12687     // This can happen if the thread has already dispatched the debug event but we haven't called WFDE to pick it up 
12688     // yet. This is sufficiently goofy that we want to stress log it.
12689     if (pUnmanagedThread->IsSuspended())
12690     {
12691         STRESS_LOG1(LF_CORDB, LL_INFO1000, "W32ET::W32EL: Thread 0x%x is suspended\n", pEvent->dwThreadId);
12692     }
12693     
12694     // For debugging crazy races in retail, we'll keep a rolling queue of win32 debug events.
12695     this->DebugRecordWin32Event(pEvent, pUnmanagedThread);
12696
12697
12698     // Check to see if shutdown of the in-proc debugging services has begun. If it has, then we know we'll no longer
12699     // be running any managed code, and we know that we can stop hijacking threads. We remember this by setting
12700     // m_initialized to false, thus preventing most things from happening elsewhere.
12701     // Don't even bother checking the DCB fields until it's been verified (m_initialized == true)
12702     if (this->m_initialized && (this->GetDCB() != NULL))
12703     {
12704         UpdateRightSideDCB();
12705         if (this->GetDCB()->m_shutdownBegun)
12706         {
12707             STRESS_LOG0(LF_CORDB, LL_INFO1000, "W32ET::W32EL: shutdown begun...\n");
12708             this->m_initialized = false;
12709         }
12710     }
12711
12712 #ifdef _DEBUG
12713     //Verify that GetThreadContext agrees with the exception address
12714     if (pEvent->dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
12715     {
12716         DT_CONTEXT tempDebugContext;
12717         tempDebugContext.ContextFlags = DT_CONTEXT_FULL;
12718         DbiGetThreadContext(pUnmanagedThread->m_handle, &tempDebugContext);
12719         CordbUnmanagedThread::LogContext(&tempDebugContext);
12720         _ASSERTE(CORDbgGetIP(&tempDebugContext) == pEvent->u.Exception.ExceptionRecord.ExceptionAddress ||
12721             (DWORD)CORDbgGetIP(&tempDebugContext) == ((DWORD)pEvent->u.Exception.ExceptionRecord.ExceptionAddress)+1);
12722     }
12723 #endif
12724
12725     // This call will decide what to do w/ the the win32 event we just got. It does a lot of work.
12726     Reaction reaction = TriageWin32DebugEvent(pUnmanagedThread, pEvent);
12727
12728
12729     // Stress-log the reaction.
12730 #ifdef _DEBUG
12731     STRESS_LOG3(LF_CORDB, LL_INFO1000, "Reaction: %d (%s), line=%d\n", 
12732                 reaction.GetType(), 
12733                 reaction.GetReactionName(), 
12734                 reaction.GetLine());
12735 #else
12736     STRESS_LOG1(LF_CORDB, LL_INFO1000, "Reaction: %d\n", reaction.GetType());
12737 #endif
12738
12739     // Make sure the lock wasn't accidentally released.
12740     _ASSERTE(ThreadHoldsProcessLock());
12741     CordbWin32EventThread * pW32EventThread = this->m_pShim->GetWin32EventThread();
12742     _ASSERTE(pW32EventThread != NULL);
12743
12744     // if we were waiting for a retriggered exception but recieved any other event then turn
12745     // off the single stepping and dequeue the IB event. Right now we only use the SS flag internally
12746     // for stepping during possible retrigger.
12747     if(reaction.GetType() != Reaction::cInbandExceptionRetrigger && pUnmanagedThread->IsSSFlagNeeded())
12748     {
12749         _ASSERTE(pUnmanagedThread->HasIBEvent());
12750         CordbUnmanagedEvent* pUnmanagedEvent = pUnmanagedThread->IBEvent();
12751         _ASSERTE(pUnmanagedEvent->IsIBEvent());
12752         _ASSERTE(pUnmanagedEvent->IsEventContinuedUnhijacked());
12753         _ASSERTE(pUnmanagedEvent->IsDispatched());
12754         LOG((LF_CORDB, LL_INFO100000, "CP::HDEFID: IB event did not retrigger ue=0x%p\n", pUnmanagedEvent));
12755
12756         DequeueUnmanagedEvent(pUnmanagedThread);
12757         pUnmanagedThread->EndStepping();
12758     }
12759
12760     switch(reaction.GetType())
12761     {
12762     // Common for flares.
12763     case Reaction::cIgnore:
12764
12765         // Shouldn't be suspending in the first place with outstanding flares.
12766         _ASSERTE(!pUnmanagedThread->IsSuspended());
12767         
12768         pW32EventThread->ForceDbgContinue(this, pUnmanagedThread, DBG_CONTINUE, false);
12769         goto LDone;
12770
12771     case Reaction::cCLR:
12772         // Don't care if thread is suspended here. We'll just let the thread continue whatever it's doing.
12773         
12774         this->m_DbgSupport.m_TotalCLR++;
12775
12776         // If this is for the CLR, then we just continue unhandled and know that the CLR has
12777         // a handler inplace to deal w/ this exception.
12778         pW32EventThread->ForceDbgContinue(this, pUnmanagedThread, DBG_EXCEPTION_NOT_HANDLED, false);
12779         goto LDone;
12780
12781
12782     case Reaction::cInband_NotNewEvent:
12783         fNewEvent = false;
12784
12785         // fall through to Inband case...
12786
12787     case Reaction::cInband:
12788     {
12789         this->m_DbgSupport.m_TotalIB++;
12790
12791         // Hijack in-band events (exception events, exit threads) if there is already an event at the head
12792         // of the queue or if the process is currently synchronized. Of course, we only do this if the
12793         // process is initialized.
12794         //
12795         // Note: we also hijack these left over in-band events if we're activley trying to send the
12796         // managed continue message to the Left Side. This is controlled by m_specialDeferment below.
12797
12798         // Only exceptions can be IB events - everything else is OOB.
12799         _ASSERTE(pEvent->dwDebugEventCode == EXCEPTION_DEBUG_EVENT);
12800
12801         // CLR internal exceptions should be sent back to the CLR and never treated as inband events.
12802         // If this assert fires, the event was triaged wrong.
12803         CONSISTENCY_CHECK_MSGF((pEvent->u.Exception.ExceptionRecord.ExceptionCode != EXCEPTION_COMPLUS), 
12804             ("Attempting to dispatch a CLR internal exception as an Inband event. Reaction line=%d\n", 
12805              reaction.GetLine()));
12806
12807
12808         _ASSERTE(!pUnmanagedThread->IsCantStop());
12809
12810         // We need to decide whether or not to dispatch this event immediately
12811         // We defer it to enforce that we only dispatch 1 IB event at a time (managed events are
12812         // considered IB here).
12813         // This means if:
12814         // 1) there's already an outstanding unmanaged inband event (an event the user has not continued from)
12815         // 2) If the process is synchronized (since that means we've already dispatched a managed event).
12816         // 3) If we've received a SyncComplete event, but aren't yet Sync.  This will almost always be the same as
12817         //    whether we're synced, but has a distict quality. It's always set by the w32 event thread in Interop,
12818         //    and so it's guaranteed to be serialized against this check here (also on the w32et). 
12819         // 4) Special deferment - This covers the region where we're sending a Stop/Continue IPC event across.
12820         //    We defer it here to keep the Helper thread alive so that it can handle these IPC events.
12821         // Queued events will be dispatched when continue is called.
12822         BOOL fHasUserUncontinuedNativeEvents = HasUserUncontinuedNativeEvents();
12823         bool fDeferInbandEvent = (fHasUserUncontinuedNativeEvents ||
12824                                   GetSynchronized() || 
12825                                   GetSyncCompleteRecv() ||
12826                                   m_specialDeferment);
12827                                          
12828         // If we've got a new event, queue it.
12829         if (fNewEvent)
12830         {
12831             this->QueueUnmanagedEvent(pUnmanagedThread, pEvent);
12832         }
12833
12834         if (fNewEvent && this->m_initialized && fDeferInbandEvent)
12835         {
12836             STRESS_LOG4(LF_CORDB, LL_INFO1000, "W32ET::W32EL: Needed to defer dispatching event: %d %d %d %d\n",
12837                  fHasUserUncontinuedNativeEvents,
12838                  GetSynchronized(),
12839                  GetSyncCompleteRecv(),
12840                  m_specialDeferment);
12841
12842             // this continues the IB debug event into the hijack
12843             // the process is now running again
12844             pW32EventThread->DoDbgContinue(this, pUnmanagedThread->IBEvent());
12845
12846             // Since we've hijacked this event, we don't need to do any further processing.
12847             goto LDone;
12848         }
12849         else
12850         {
12851             // No need to defer the dispatch, do it now
12852             this->DispatchUnmanagedInBandEvent();
12853  
12854             goto LDone;
12855         }
12856         UNREACHABLE();
12857     }
12858     
12859     case Reaction::cFirstChanceHijackStarted:
12860     {   
12861         // determine the logical event we are handling, if any
12862         CordbUnmanagedEvent* pUnmanagedEvent = NULL;
12863         if(pUnmanagedThread->HasIBEvent())
12864         {
12865             pUnmanagedEvent = pUnmanagedThread->IBEvent();
12866         }
12867         LOG((LF_CORDB, LL_INFO100000, "W32ET::W32EL: IB hijack starting, ue=0x%p\n", pUnmanagedEvent));
12868
12869         // fetch the LS memory set up for this hijack
12870         REMOTE_PTR pDebuggerWord = NULL;
12871         DebuggerIPCFirstChanceData fcd;
12872         pUnmanagedThread->GetEEDebuggerWord(&pDebuggerWord);
12873         SafeReadStruct(PTR_TO_CORDB_ADDRESS(pDebuggerWord), &fcd);
12874
12875         LOG((LF_CORDB, LL_INFO100000, "W32ET::W32EL: old fcd DebugCounter=0x%x\n", fcd.debugCounter));
12876
12877         // determine what action the LS should take
12878         if(pUnmanagedThread->IsBlockingForSync())
12879         {
12880             // there should be an event we hijacked in this case
12881             _ASSERTE(pUnmanagedEvent != NULL);
12882             
12883             // block that event
12884             LOG((LF_CORDB, LL_INFO100000, "W32ET::W32EL: blocking\n"));
12885             fcd.action = HIJACK_ACTION_WAIT;
12886             fcd.debugCounter = 0x2;
12887             SafeWriteStruct(PTR_TO_CORDB_ADDRESS(pDebuggerWord), &fcd);
12888         }
12889         else
12890         {
12891             // we don't need to block. We want the vectored handler to just exit
12892             // as if it wasn't there
12893             _ASSERTE(fcd.action == HIJACK_ACTION_EXIT_UNHANDLED);
12894             LOG((LF_CORDB, LL_INFO100000, "W32ET::W32EL: not blocking\n"));
12895         }
12896
12897         LOG((LF_CORDB, LL_INFO100000, "W32ET::W32EL: continuing from flare\n"));
12898         pW32EventThread->ForceDbgContinue(this, pUnmanagedThread, DBG_CONTINUE, false);
12899         goto LDone;
12900     }
12901
12902     case Reaction::cInbandHijackComplete:
12903     {
12904         // We now execute the hijack worker even when not actually hijacked
12905         // so can't assert this 
12906         //_ASSERTE(pUnmanagedThread->IsFirstChanceHijacked());
12907
12908         // we should not be stepping at the end of hijacks
12909         _ASSERTE(!pUnmanagedThread->IsSSFlagHidden());
12910         _ASSERTE(!pUnmanagedThread->IsSSFlagNeeded());
12911
12912         // if we were hijacked then clean up
12913         if(pUnmanagedThread->IsFirstChanceHijacked())
12914         {
12915             LOG((LF_CORDB, LL_INFO100000, "W32ET::W32EL: hijack complete will restore context...\n"));
12916             DT_CONTEXT tempContext = { 0 };
12917             tempContext.ContextFlags = DT_CONTEXT_FULL;
12918             HRESULT hr = pUnmanagedThread->GetThreadContext(&tempContext);
12919             _ASSERTE(SUCCEEDED(hr));
12920
12921             // The sync hijack returns normally but the m2uHandoff hijack needs to have the IP
12922             // deliberately restored
12923             if(!pUnmanagedThread->IsBlockingForSync())
12924             {
12925                 // restore the context to the current un-hijacked context
12926                 BOOL succ = DbiSetThreadContext(pUnmanagedThread->m_handle, &tempContext);
12927                 _ASSERTE(succ);
12928
12929                 // Because hijacks don't return normally they might have pushed handlers without poping them
12930                 // back off. To take care of that we explicitly restore the old SEH chain.
12931     #ifdef DBG_TARGET_X86
12932                 hr = pUnmanagedThread->RestoreLeafSeh();
12933                 _ASSERTE(SUCCEEDED(hr));
12934     #endif
12935             }
12936             else
12937             {
12938                 _ASSERTE(pUnmanagedThread->HasIBEvent());
12939                 CordbUnmanagedEvent* pUnmanagedEvent = pUnmanagedThread->IBEvent();
12940                 LOG((LF_CORDB, LL_INFO100000, "W32ET::W32EL: IB hijack completing, continuing unhijacked ue=0x%p\n", pUnmanagedEvent));
12941                 _ASSERTE(pUnmanagedEvent->IsEventContinuedHijacked());
12942                 _ASSERTE(pUnmanagedEvent->IsDispatched());
12943                 _ASSERTE(pUnmanagedEvent->IsEventUserContinued());
12944                 _ASSERTE(!pUnmanagedEvent->IsEventContinuedUnhijacked());
12945                 pUnmanagedEvent->SetState(CUES_EventContinuedUnhijacked);
12946
12947                 // fetch the LS memory set up for this hijack
12948                 REMOTE_PTR pDebuggerWord = NULL;
12949                 DebuggerIPCFirstChanceData fcd;
12950                 pUnmanagedThread->GetEEDebuggerWord(&pDebuggerWord);
12951                 SafeReadStruct(PTR_TO_CORDB_ADDRESS(pDebuggerWord), &fcd);
12952
12953                 LOG((LF_CORDB, LL_INFO10000, "W32ET::W32EL: pDebuggerWord is 0x%p\n", pDebuggerWord));
12954
12955                 //set the correct continuation action based upon the user's selection
12956                 if(pUnmanagedEvent->IsExceptionCleared())
12957                 {
12958                     LOG((LF_CORDB, LL_INFO10000, "W32ET::W32EL: exception cleared\n"));
12959                     fcd.action = HIJACK_ACTION_EXIT_HANDLED;
12960                 }
12961                 else
12962                 {
12963                     LOG((LF_CORDB, LL_INFO10000, "W32ET::W32EL: exception not cleared\n"));
12964                     fcd.action = HIJACK_ACTION_EXIT_UNHANDLED;
12965                 }
12966
12967                 //
12968                 // LS context is restored here so that execution continues from next instruction that caused the hijack.
12969                 // We shouldn't always restore the LS context though.
12970                 // Consider the following case where this can cause issues:
12971                 // Debuggee process hits an exception and calls KERNELBASE!RaiseException, debugger gets the notification and
12972                 // prepares for first-chance hijack. Debugger(DBI) saves the current thread context (see SetupFirstChanceHijackForSync) which is restored
12973                 // later below (see SafeWriteThreadContext call) when the process is in VEH (CLRVectoredExceptionHandlerShim->FirstChanceSuspendHijackWorker).
12974                 // The thread context that got saved(by SetupFirstChanceHijackForSync) was for when the thread was executing RaiseException and when
12975                 // this context gets restored in VEH, the thread resumes after the exception handler with a context that is not same as one with which
12976                 // it entered. This inconsistency can lead to bad execution code-paths or even a debuggee crash.
12977                 //
12978                 // Example case where we should definitely update the LS context:
12979                 // After a DbgBreakPoint call, IP gets updated to point to the instruction after int 3 and this is the context saved by debugger.
12980                 // The IP in context passed to VEH still points to int 3 though and if we don't update the LS context in VEH, the breakpoint
12981                 // instruction will get executed again.
12982                 //
12983                 // Here's a list of cases when we update the LS context:
12984                 // * we know that context was explicitly updated during this hijack, OR
12985                 // * if single-stepping flag was set on it originally, OR
12986                 // * if this was a breakpoint event
12987                 // Note that above list is a heuristic and it is possible that we need to add more such cases in future.
12988                 //
12989                 BOOL isBreakPointEvent = (pUnmanagedEvent->m_currentDebugEvent.dwDebugEventCode == EXCEPTION_DEBUG_EVENT &&
12990                     pUnmanagedEvent->m_currentDebugEvent.u.Exception.ExceptionRecord.ExceptionCode == STATUS_BREAKPOINT);
12991                 if (pUnmanagedThread->IsContextSet() || IsSSFlagEnabled(&tempContext) || isBreakPointEvent)
12992                 {
12993                     _ASSERTE(fcd.pLeftSideContext != NULL);
12994                     LOG((LF_CORDB, LL_INFO10000, "W32ET::W32EL: updating LS context at 0x%p\n", fcd.pLeftSideContext));
12995                     // write the new context over the old one on the LS
12996                     SafeWriteThreadContext(fcd.pLeftSideContext, &tempContext);
12997                 }
12998
12999                 // Write the new Fcd data to the LS
13000                 fcd.debugCounter = 0x1;
13001                 SafeWriteStruct(PTR_TO_CORDB_ADDRESS(pDebuggerWord), &fcd);
13002
13003                 fcd.debugCounter = 0;
13004                 SafeReadStruct(PTR_TO_CORDB_ADDRESS(pDebuggerWord), &fcd);
13005                 _ASSERTE(fcd.debugCounter == 1);
13006
13007                 DequeueUnmanagedEvent(pUnmanagedThread);
13008             }
13009
13010             _ASSERTE(m_cFirstChanceHijackedThreads > 0);
13011             m_cFirstChanceHijackedThreads--;
13012             if(m_cFirstChanceHijackedThreads == 0)
13013             {
13014                 m_state &= ~PS_HIJACKS_IN_PLACE;
13015             }
13016
13017             pUnmanagedThread->ClearState(CUTS_FirstChanceHijacked);
13018             pUnmanagedThread->ClearState(CUTS_BlockingForSync);
13019
13020             // if the user set the context it either was already applied (m2uHandoff hijack)
13021             // or is about to be applied when the hijack returns (sync hijack).
13022             // There may still a small window where it won't appear accurate that
13023             // we just have to live with
13024             pUnmanagedThread->ClearState(CUTS_HasContextSet);
13025         }
13026
13027         pW32EventThread->ForceDbgContinue(this, pUnmanagedThread, DBG_CONTINUE, false);
13028
13029         // We've handled this event. Skip further processing.
13030         goto LDone;
13031     }
13032
13033     case Reaction::cBreakpointRequiringHijack:
13034     {
13035         HRESULT hr = pUnmanagedThread->SetupFirstChanceHijack(EHijackReason::kM2UHandoff, &(pEvent->u.Exception.ExceptionRecord));
13036         _ASSERTE(SUCCEEDED(hr));
13037         pW32EventThread->ForceDbgContinue(this, pUnmanagedThread, DBG_CONTINUE, false);
13038         goto LDone;
13039     }
13040
13041     case Reaction::cInbandExceptionRetrigger:
13042     {
13043         // this should be unused now
13044         _ASSERTE(FALSE);
13045         _ASSERTE(pUnmanagedThread->HasIBEvent());
13046         CordbUnmanagedEvent* pUnmanagedEvent = pUnmanagedThread->IBEvent();
13047         _ASSERTE(pUnmanagedEvent->IsIBEvent());
13048         _ASSERTE(pUnmanagedEvent->IsEventContinuedUnhijacked());
13049         _ASSERTE(pUnmanagedEvent->IsDispatched());
13050         LOG((LF_CORDB, LL_INFO100000, "W32ET::W32EL: IB event completing, continuing ue=0x%p\n", pUnmanagedEvent));
13051
13052         DequeueUnmanagedEvent(pUnmanagedThread);
13053         // If this event came from RaiseException then flush the context to ensure we won't use it until we re-enter
13054         if(pUnmanagedEvent->m_owner->IsRaiseExceptionHijacked())
13055         {
13056             pUnmanagedEvent->m_owner->RestoreFromRaiseExceptionHijack();
13057             pUnmanagedEvent->m_owner->ClearRaiseExceptionEntryContext();
13058         }
13059         else // otherwise we should have been stepping
13060         {
13061             pUnmanagedThread->EndStepping();
13062         }
13063         pW32EventThread->ForceDbgContinue(this, pUnmanagedThread, 
13064             pUnmanagedEvent->IsExceptionCleared() ? DBG_CONTINUE : DBG_EXCEPTION_NOT_HANDLED, false);
13065         
13066         // We've handled this event. Skip further processing.
13067         goto LDone;
13068     }
13069
13070     case Reaction::cOOB:
13071     {
13072         // Don't care if this thread claimed to be suspended or not. Dispatch event anyways. After all,
13073         // OOB events can come at *any* time.
13074         
13075         // This thread may be suspended. We don't care.
13076         this->m_DbgSupport.m_TotalOOB++;
13077
13078         // Not an  inband event. This includes ALL non-exception events (including EXIT_THREAD) as
13079         // well as any exception that can't be hijacked (ex, an exception on the helper thread).
13080
13081         // If this is an exit thread or exit process event, then we need to mark the unmanaged thread as
13082         // exited for later.
13083         if ((pEvent->dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) ||
13084             (pEvent->dwDebugEventCode == EXIT_THREAD_DEBUG_EVENT))
13085         {
13086             pUnmanagedThread->SetState(CUTS_Deleted);
13087         }
13088
13089         // If we get an exit process or exit thread event on the helper thread, then we know we're loosing
13090         // the Left Side, so go ahead and remember that the helper thread has died.
13091         if (this->IsHelperThreadWorked(pUnmanagedThread->GetOSTid()))
13092         {
13093             if ((pEvent->dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) ||
13094                 (pEvent->dwDebugEventCode == EXIT_THREAD_DEBUG_EVENT))
13095             {
13096                 this->m_helperThreadDead = true;
13097             }
13098         }
13099
13100         // Queue the current out-of-band event.
13101         this->QueueOOBUnmanagedEvent(pUnmanagedThread, pEvent);
13102
13103         // Go ahead and dispatch the event if its the first one.
13104         if (this->m_outOfBandEventQueue == pUnmanagedThread->OOBEvent())
13105         {
13106             // Set this to true to indicate to Continue() that we're in the unamnaged callback.
13107             CordbUnmanagedEvent * pUnmanagedEvent = pUnmanagedThread->OOBEvent();
13108
13109             this->m_dispatchingOOBEvent = true;
13110
13111             pUnmanagedEvent->SetState(CUES_Dispatched);
13112
13113             this->Unlock();
13114
13115             // Handler should have been registered by now.
13116             _ASSERTE(this->m_cordb->m_unmanagedCallback != NULL);
13117
13118             // Call the callback with fIsOutOfBand = TRUE.
13119             {
13120                 PUBLIC_WIN32_CALLBACK_IN_THIS_SCOPE(this, pEvent, TRUE);
13121                 this->m_cordb->m_unmanagedCallback->DebugEvent(const_cast<DEBUG_EVENT*> (pEvent), TRUE);
13122             }
13123
13124             this->Lock();
13125
13126             // If m_dispatchingOOBEvent is false, that means that the user called Continue() from within
13127             // the callback. We know that we can go ahead and continue the process now.
13128             if (this->m_dispatchingOOBEvent == false)
13129             {
13130                 // Note: this call will dispatch more OOB events if necessary.
13131                 pW32EventThread->UnmanagedContinue(this, cOobUMContinue);
13132             }
13133             else
13134             {
13135                 // We're not dispatching anymore, so set this back to false.
13136                 this->m_dispatchingOOBEvent = false;
13137             }
13138         }
13139
13140         // We've handled this event. Skip further processing.
13141         goto LDone;
13142     }
13143     } // end Switch on Reaction
13144
13145     UNREACHABLE();
13146
13147 LDone:
13148     // Process Lock implicitly released by holder.
13149
13150     STRESS_LOG0(LF_CORDB, LL_INFO1000, "W32ET::W32EL: done processing event.\n");
13151
13152     return;
13153 }
13154
13155 //
13156 // Returns true if the exception is a flare from the left side, false otherwise.
13157 //
13158 bool CordbProcess::ExceptionIsFlare(DWORD exceptionCode, const void *exceptionAddress)
13159 {
13160     _ASSERTE(m_runtimeOffsetsInitialized);
13161
13162     // Can't have a flare if the left side isn't initialized
13163     if (m_initialized)
13164     {
13165         DebuggerIPCRuntimeOffsets *pRO = &m_runtimeOffsets;
13166
13167         // All flares are breakpoints...
13168         if (exceptionCode == STATUS_BREAKPOINT)
13169         {
13170             // Does the breakpoint address match a flare address?
13171             if ((exceptionAddress == pRO->m_signalHijackStartedBPAddr) ||
13172                 (exceptionAddress == pRO->m_excepForRuntimeHandoffStartBPAddr) ||
13173                 (exceptionAddress == pRO->m_excepForRuntimeHandoffCompleteBPAddr) ||
13174                 (exceptionAddress == pRO->m_signalHijackCompleteBPAddr) ||
13175                 (exceptionAddress == pRO->m_excepNotForRuntimeBPAddr) ||
13176                 (exceptionAddress == pRO->m_notifyRSOfSyncCompleteBPAddr))
13177                 return true;
13178         }
13179     }
13180
13181     return false;
13182 }
13183 #endif // FEATURE_INTEROP_DEBUGGING
13184
13185 // Allocate a buffer in the target and copy data into it.
13186 // 
13187 // Arguments:
13188 //    pDomain - an appdomain associated with the allocation request. 
13189 //    bufferSize - size of the buffer in bytes
13190 //    bufferFrom - local buffer of data (bufferSize bytes) to copy data from.
13191 //    ppRes - address into target of allocated buffer
13192 //    
13193 // Returns:
13194 //    S_OK on success, else error.
13195 HRESULT CordbProcess::GetAndWriteRemoteBuffer(CordbAppDomain *pDomain, unsigned int bufferSize, const void *bufferFrom, void **ppRes)
13196 {
13197     _ASSERTE(ppRes != NULL);
13198     *ppRes = NULL;
13199
13200     HRESULT hr = S_OK;
13201
13202     EX_TRY
13203     {
13204         TargetBuffer tbTarget = GetRemoteBuffer(bufferSize); // throws
13205         SafeWriteBuffer(tbTarget, (const BYTE*) bufferFrom); // throws
13206         
13207         // Succeeded.
13208         *ppRes = CORDB_ADDRESS_TO_PTR(tbTarget.pAddress);
13209     }
13210     EX_CATCH_HRESULT(hr);
13211     return hr;
13212 }
13213
13214 #ifdef FEATURE_INTEROP_DEBUGGING
13215
13216 //
13217 // Checks to see if the given second chance exception event actually signifies the death of the process due to a second
13218 // stack overflow special case.
13219 //
13220 // There are strange cases with stack overflow exceptions. If a nieve application catches a stack overflow exception and
13221 // handles it, without resetting the guard page, then the app will get an AV when it overflows the stack a second time. We
13222 // will get the first chance AV, but when we continue from it the OS won't run any SEH handlers, so our FCH won't
13223 // actually work. Instead, we'll get the AV back on second chance right away.
13224 //
13225 bool CordbProcess::IsSpecialStackOverflowCase(CordbUnmanagedThread *pUThread, const DEBUG_EVENT *pEvent)
13226 {
13227     _ASSERTE(pEvent->dwDebugEventCode == EXCEPTION_DEBUG_EVENT);
13228     _ASSERTE(pEvent->u.Exception.dwFirstChance == 0);
13229
13230     // If this is not an AV, it can't be our special case.
13231     if (pEvent->u.Exception.ExceptionRecord.ExceptionCode != STATUS_ACCESS_VIOLATION)
13232         return false;
13233
13234     // If the thread isn't already first chance hijacked, it can't be our special case.
13235     if (!pUThread->IsFirstChanceHijacked())
13236         return false;
13237
13238     // The first chance hijack didn't take, so we're not FCH anymore and we're not waiting for an answer
13239     // anymore... Note: by leaving this thread completely unhijacked, we'll report its true context, which is correct.
13240     pUThread->ClearState(CUTS_FirstChanceHijacked);
13241
13242     // The process is techincally dead as a door nail here, so we'll mark that the helper thread is dead so our managed
13243     // API bails nicely.
13244     m_helperThreadDead = true;
13245
13246     // Remember we're in our special case.
13247     pUThread->SetState(CUTS_HasSpecialStackOverflowCase);
13248
13249     // Now, remember the second chance AV event in the second IB event slot for this thread and add it to the end of the
13250     // IB event queue.
13251     QueueUnmanagedEvent(pUThread, pEvent);
13252
13253     // Note: returning true will ensure that the queued first chance AV for this thread is dispatched.
13254     return true;
13255 }
13256
13257 //-----------------------------------------------------------------------------
13258 // Longhorn broke ContinueDebugEvent.
13259 // In previous OS releases, DBG_CONTINUE would continue a  non-continuable exception.
13260 // In longhorn, we need to pass the DBG_FORCE_CONTINUE flag to do that.
13261 // Note that all CLR exceptions are non-continuable.
13262 // Now instead of DBG_CONTINUE, we need to pass DBG_FORCE_CONTINUE.
13263 //-----------------------------------------------------------------------------
13264
13265 // Currently we don't have headers for the longhorn winnt.h. So we need to privately declare
13266 // this here. We have a check such that if we do get headers, the value won't change underneath us.
13267 #define MY_DBG_FORCE_CONTINUE               ((DWORD   )0x00010003L)
13268 #ifndef DBG_FORCE_CONTINUE
13269 #define DBG_FORCE_CONTINUE MY_DBG_FORCE_CONTINUE
13270 #else
13271 static_assert_no_msg(DBG_FORCE_CONTINUE == MY_DBG_FORCE_CONTINUE);
13272 #endif
13273
13274 DWORD GetDbgContinueFlag()
13275 {
13276     // Currently, default to not using the new DBG_FORCE_CONTINUE flag.
13277     static ConfigDWORD fNoFlagKey;
13278     bool fNoFlag = fNoFlagKey.val(CLRConfig::UNSUPPORTED_DbgNoForceContinue) != 0;
13279
13280
13281     if (!fNoFlag)
13282     {
13283         return DBG_FORCE_CONTINUE;
13284     }
13285     else
13286     {
13287         return DBG_CONTINUE;
13288     }
13289 }
13290
13291
13292 // Some Interop bugs involve threads that land at a crazy IP. Since we're interop-debugging, we can't
13293 // attach a debugger to the LS. So we have some debug mode where we enable the SS flag and thus
13294 // produce a trace of where a thread is going.
13295 #ifdef _DEBUG
13296 void EnableDebugTrace(CordbUnmanagedThread *ut)
13297 {
13298     // To enable, attach w/ a debugger and either set fTrace==true, or setip.
13299     static bool fTrace = false;
13300     if (!fTrace)
13301         return;
13302
13303     // Give us a nop so that we can setip in the optimized case.
13304 #ifdef _TARGET_X86_
13305     __asm {
13306         nop
13307     }
13308 #endif
13309
13310     fTrace = true;
13311     CordbProcess *pProcess = ut->GetProcess();
13312
13313     // Get the context
13314     HRESULT hr = S_OK;
13315     DT_CONTEXT context;
13316     context.ContextFlags = DT_CONTEXT_FULL;
13317
13318
13319     hr = pProcess->GetThreadContext((DWORD) ut->m_id, sizeof(context), (BYTE*)&context);
13320     if (FAILED(hr))
13321         return;
13322
13323     // If the flag is already set, then don't set it again - that will just get confusing.
13324     if (IsSSFlagEnabled(&context))
13325     {
13326         return;
13327     }
13328     _ASSERTE(CORDbgGetIP(&context) != 0);
13329     SetSSFlag(&context);
13330
13331     // If SS flag not set, enable it. And remeber that it's us so we know how to handle
13332     // it when we get the debug event.
13333     hr = pProcess->SetThreadContext((DWORD)ut->m_id, sizeof(context), (BYTE*)&context);
13334     ut->SetState(CUTS_DEBUG_SingleStep);
13335 }
13336 #endif // _DEBUG
13337
13338 //-----------------------------------------------------------------------------
13339 // DoDbgContinue 
13340 //
13341 // Continues from a specific Win32 DEBUG_EVENT.
13342 //
13343 // Arguments:
13344 //    pProcess - The process to continue.
13345 //    pUnmanagedEvent - The event to continue.
13346 //
13347 //-----------------------------------------------------------------------------
13348 void CordbWin32EventThread::DoDbgContinue(CordbProcess *pProcess, 
13349                                           CordbUnmanagedEvent *pUnmanagedEvent)
13350 {
13351     _ASSERTE(pProcess->ThreadHoldsProcessLock());
13352     _ASSERTE(IsWin32EventThread());
13353     _ASSERTE(pUnmanagedEvent != NULL);
13354     _ASSERTE(!pUnmanagedEvent->IsEventContinuedUnhijacked());
13355
13356     STRESS_LOG3(LF_CORDB, LL_INFO1000,
13357          "W32ET::DDC: continue with ue=0x%p, thread=0x%p, tid=0x%x\n",
13358          pUnmanagedEvent,
13359          pUnmanagedEvent->m_owner,
13360          pUnmanagedEvent->m_owner->m_id);
13361
13362 #ifdef _DEBUG
13363     EnableDebugTrace(pUnmanagedEvent->m_owner);
13364 #endif
13365
13366
13367     if (pUnmanagedEvent->IsEventContinuedHijacked())
13368     {
13369         LOG((LF_CORDB, LL_INFO100000, "W32ET::DDC: Skiping DoDbgContinue because event was already"
13370             " continued hijacked, ue=0x%p\n", pUnmanagedEvent));
13371         return;
13372     }
13373
13374     BOOL threadIsHijacked = (pUnmanagedEvent->m_owner->IsFirstChanceHijacked() ||
13375                              pUnmanagedEvent->m_owner->IsGenericHijacked());
13376
13377     BOOL eventIsIB = (pUnmanagedEvent->m_owner->HasIBEvent() &&
13378                       pUnmanagedEvent->m_owner->IBEvent() == pUnmanagedEvent);
13379
13380     _ASSERTE((DWORD) pProcess->m_id == pUnmanagedEvent->m_currentDebugEvent.dwProcessId);
13381     _ASSERTE(pProcess->m_state & CordbProcess::PS_WIN32_STOPPED);
13382
13383     DWORD dwContType;
13384     if(eventIsIB)
13385     {
13386         // 3 cases here...
13387         // event was already hijacked
13388         if(threadIsHijacked)
13389         {
13390             LOG((LF_CORDB, LL_INFO100000, "W32ET::DDC: Continuing IB, already hijacked, ue=0x%p\n", pUnmanagedEvent));
13391             pUnmanagedEvent->SetState(CUES_EventContinuedHijacked);
13392             dwContType = !pUnmanagedEvent->m_owner->IsBlockingForSync() ? GetDbgContinueFlag() : DBG_EXCEPTION_NOT_HANDLED;
13393         }
13394         // event was not hijacked but has been dispatched
13395         else if(!threadIsHijacked && pUnmanagedEvent->IsDispatched())
13396         {
13397             LOG((LF_CORDB, LL_INFO100000, "W32ET::DDC: Continuing IB, not hijacked, ue=0x%p\n", pUnmanagedEvent));
13398             _ASSERTE(pUnmanagedEvent->IsDispatched());
13399             _ASSERTE(pUnmanagedEvent->IsEventUserContinued());
13400             _ASSERTE(!pUnmanagedEvent->IsEventContinuedUnhijacked());
13401             pUnmanagedEvent->SetState(CUES_EventContinuedUnhijacked);
13402             dwContType = pUnmanagedEvent->IsExceptionCleared() ? GetDbgContinueFlag() : DBG_EXCEPTION_NOT_HANDLED;
13403             
13404             // The event was never hijacked and so will never need to retrigger, get rid
13405             // of it right now. If it had been hijacked then we would dequeue it either after the
13406             // hijack complete flare or one instruction after that when it has had a chance to retrigger
13407             pProcess->DequeueUnmanagedEvent(pUnmanagedEvent->m_owner);
13408         }
13409         // event was not hijacked nor dispatched
13410         else // if(!threadIsHijacked && !pUnmanagedEvent->IsDispatched())
13411         {
13412             LOG((LF_CORDB, LL_INFO100000, "W32ET::DDC: Continuing IB, now hijacked, ue=0x%p\n", pUnmanagedEvent));
13413             HRESULT hr = pProcess->HijackIBEvent(pUnmanagedEvent);
13414             _ASSERTE(SUCCEEDED(hr));
13415             pUnmanagedEvent->SetState(CUES_EventContinuedHijacked);
13416             dwContType = !pUnmanagedEvent->m_owner->IsBlockingForSync() ? GetDbgContinueFlag() : DBG_EXCEPTION_NOT_HANDLED;
13417         }
13418     }
13419     else
13420     {
13421         LOG((LF_CORDB, LL_INFO100000, "W32ET::DDC: Continuing OB, ue=0x%p\n", pUnmanagedEvent));
13422         // we might actually be hijacked here, but if we are it should be for a previous IB event
13423         // we just mark all OB events as continued unhijacked
13424         pUnmanagedEvent->SetState(CUES_EventContinuedUnhijacked);
13425         dwContType = pUnmanagedEvent->IsExceptionCleared() ? GetDbgContinueFlag() : DBG_EXCEPTION_NOT_HANDLED;
13426     }
13427
13428     // If the exception is marked as unclearable, then make sure the continue type is correct and force the process
13429     // to terminate.
13430     if (pUnmanagedEvent->IsExceptionUnclearable())
13431     {
13432         TerminateProcess(pProcess->UnsafeGetProcessHandle(), pUnmanagedEvent->m_currentDebugEvent.u.Exception.ExceptionRecord.ExceptionCode);
13433         dwContType = DBG_EXCEPTION_NOT_HANDLED;
13434     }
13435
13436     // If we're continuing from the loader-bp, then send the managed attach here.
13437     // (Note this will only be set if the runtime was loaded when we first tried to attach).
13438     // We assume that the loader-bp is the 1st BP exception. This is naive,
13439     // since it's not 100% accurate (someone could CreateThread w/ a threadproc of DebugBreak).
13440     // But it's the best we can do.
13441     // Note that it's critical we do this BEFORE continuing the process.  If this is mixed-mode, we've already
13442     // told VS about this breakpoint, and so it's set the attach-complete event.  As soon as we continue this debug
13443     // event the process can start moving again, so the CLR needs to know to wait for a managed attach.
13444     DWORD dwEventCode = pUnmanagedEvent->m_currentDebugEvent.dwDebugEventCode;
13445     if (dwEventCode == EXCEPTION_DEBUG_EVENT)
13446     {
13447         EXCEPTION_DEBUG_INFO * pDebugInfo = &pUnmanagedEvent->m_currentDebugEvent.u.Exception;
13448         if (pDebugInfo->dwFirstChance && pDebugInfo->ExceptionRecord.ExceptionCode == STATUS_BREAKPOINT)
13449         {
13450             HRESULT hrIgnore = S_OK;
13451             EX_TRY
13452             {
13453                 LOG((LF_CORDB, LL_INFO1000, "W32ET::DDC: Continuing from LdrBp, doing managed attach.\n"));
13454                 pProcess->QueueManagedAttachIfNeededWorker();
13455             } 
13456             EX_CATCH_HRESULT(hrIgnore);
13457             SIMPLIFYING_ASSUMPTION(SUCCEEDED(hrIgnore));
13458         }
13459     }        
13460
13461     STRESS_LOG4(LF_CORDB, LL_INFO1000,
13462         "W32ET::DDC: calling ContinueDebugEvent(0x%x, 0x%x, 0x%x), process state=0x%x\n",
13463         pProcess->m_id, pUnmanagedEvent->m_owner->m_id, dwContType, pProcess->m_state);
13464
13465     // Actually continue the debug event
13466     pProcess->m_state &= ~CordbProcess::PS_WIN32_STOPPED;
13467     BOOL fSuccess = m_pNativePipeline->ContinueDebugEvent((DWORD)pProcess->m_id, (DWORD)pUnmanagedEvent->m_owner->m_id, dwContType);
13468
13469     // ContinueDebugEvent may 'fail' if we force kill the debuggee while stopped at the exit-process event.
13470     if (!fSuccess && (dwEventCode != EXIT_PROCESS_DEBUG_EVENT))
13471     {
13472         _ASSERTE(!"ContinueDebugEvent failed!");
13473         CORDBSetUnrecoverableError(pProcess, HRESULT_FROM_GetLastError(), 0);
13474         STRESS_LOG1(LF_CORDB, LL_INFO1000, "W32ET::DDC: Last error after ContinueDebugEvent is %d\n", GetLastError());
13475     }
13476
13477     // If this thread is marked for deletion (exit thread or exit process event on it), then we need to delete the
13478     // unmanaged thread object.
13479     if ((dwEventCode == EXIT_PROCESS_DEBUG_EVENT) || (dwEventCode == EXIT_THREAD_DEBUG_EVENT))
13480     {
13481         CordbUnmanagedThread * pUnmanagedThread = pUnmanagedEvent->m_owner;
13482         _ASSERTE(pUnmanagedThread->IsDeleted());
13483
13484
13485         // Thread may have a hijacked inband event on it. Thus it's actually running free from the OS perspective,
13486         // and fair game to be terminated. In that case, we need to auto-dequeue the event.
13487         // This will just prevent the RS from making the underlying call to ContinueDebugEvent on this thread
13488         // for the inband event. Since we've already lost the thread, that's actually exactly what we want.
13489         if (pUnmanagedThread->HasIBEvent())
13490         {
13491             pProcess->DequeueUnmanagedEvent(pUnmanagedThread);
13492         }
13493
13494         STRESS_LOG1(LF_CORDB, LL_INFO1000, "Removing thread 0x%x (%d) from process list\n", pUnmanagedThread->m_id);
13495         pProcess->m_unmanagedThreads.RemoveBase((ULONG_PTR)pUnmanagedThread->m_id);
13496     }
13497
13498
13499     // If we just continued from an exit process event, then its time to do the exit processing.
13500     if (dwEventCode == EXIT_PROCESS_DEBUG_EVENT)
13501     {
13502         pProcess->Unlock();
13503         ExitProcess(false); // not detach case
13504         pProcess->Lock();
13505     }
13506
13507 }
13508
13509 //---------------------------------------------------------------------------------------
13510 //
13511 // ForceDbgContinue continues from the last Win32 DEBUG_EVENT on the given thread, no matter what it was.
13512 //
13513 // Arguments:
13514 //      pProcess - process object to continue
13515 //      pUnmanagedThread - unmanaged thread object (maybe null if we're doing a raw cotninue)
13516 //      contType - continuation status (DBG_CONTINUE or DBG_EXCEPTION_NOT_HANDLED)
13517 //      fContinueProcess - do we resume hijacks?
13518 //
13519 void CordbWin32EventThread::ForceDbgContinue(CordbProcess *pProcess, CordbUnmanagedThread *pUnmanagedThread, DWORD contType,
13520                                              bool fContinueProcess)
13521 {
13522     _ASSERTE(pProcess->ThreadHoldsProcessLock());
13523     _ASSERTE(pUnmanagedThread != NULL);
13524     STRESS_LOG4(LF_CORDB, LL_INFO1000,
13525          "W32ET::FDC: force continue with 0x%x (%s), contProcess=%d, tid=0x%x\n",
13526          contType,
13527          (contType == DBG_CONTINUE) ? "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED",
13528          fContinueProcess,
13529          pUnmanagedThread->m_id);
13530
13531     if (fContinueProcess)
13532     {
13533         pProcess->ResumeHijackedThreads();
13534     }
13535
13536     if (contType == DBG_CONTINUE)
13537     {
13538         contType = GetDbgContinueFlag();
13539     }
13540
13541     _ASSERTE(pProcess->m_state & CordbProcess::PS_WIN32_STOPPED);
13542
13543     // Remove the Win32 stopped flag so long as the OOB event queue is empty. We're forcing a continue here, so by
13544     // definition this should be the case...
13545     _ASSERTE(pProcess->m_outOfBandEventQueue == NULL);
13546
13547     pProcess->m_state &= ~CordbProcess::PS_WIN32_STOPPED;
13548
13549     STRESS_LOG4(LF_CORDB, LL_INFO1000, "W32ET::FDC: calling ContinueDebugEvent(0x%x, 0x%x, 0x%x), process state=0x%x\n",
13550          pProcess->m_id, pUnmanagedThread->m_id, contType, pProcess->m_state);
13551
13552
13553     #ifdef _DEBUG
13554     EnableDebugTrace(pUnmanagedThread);
13555     #endif
13556     BOOL ret = m_pNativePipeline->ContinueDebugEvent((DWORD)pProcess->m_id, (DWORD)pUnmanagedThread->m_id, contType);
13557
13558     if (!ret)
13559     {
13560         // This could in theory fail from Process exit, but that really would only be on the DoDbgContinue path.
13561          _ASSERTE(!"ContinueDebugEvent failed #2!");
13562         STRESS_LOG1(LF_CORDB, LL_INFO1000, "W32ET::DDC: Last error after ContinueDebugEvent is %d\n", GetLastError());
13563     }
13564 }
13565 #endif // FEATURE_INTEROP_DEBUGGING
13566
13567 //
13568 // This is the thread's real thread proc. It simply calls to the
13569 // thread proc on the given object.
13570 //
13571 /*static*/ DWORD WINAPI CordbWin32EventThread::ThreadProc(LPVOID parameter)
13572 {
13573     CordbWin32EventThread* t = (CordbWin32EventThread*) parameter;
13574     INTERNAL_THREAD_ENTRY(t);
13575     t->ThreadProc();
13576     return 0;
13577 }
13578
13579
13580 //
13581 // Send a CreateProcess event to the Win32 thread to have it create us
13582 // a new process.
13583 //
13584 HRESULT CordbWin32EventThread::SendCreateProcessEvent(
13585                                   MachineInfo machineInfo,
13586                                   LPCWSTR programName,
13587                                   __in_z LPWSTR  programArgs,
13588                                   LPSECURITY_ATTRIBUTES lpProcessAttributes,
13589                                   LPSECURITY_ATTRIBUTES lpThreadAttributes,
13590                                   BOOL bInheritHandles,
13591                                   DWORD dwCreationFlags,
13592                                   PVOID lpEnvironment,
13593                                   LPCWSTR lpCurrentDirectory,
13594                                   LPSTARTUPINFOW lpStartupInfo,
13595                                   LPPROCESS_INFORMATION lpProcessInformation,
13596                                   CorDebugCreateProcessFlags corDebugFlags)
13597 {
13598     HRESULT hr = S_OK;
13599
13600     LockSendToWin32EventThreadMutex();
13601     LOG((LF_CORDB, LL_EVERYTHING, "CordbWin32EventThread::SCPE Called\n"));
13602     m_actionData.createData.machineInfo = machineInfo;
13603     m_actionData.createData.programName = programName;
13604     m_actionData.createData.programArgs = programArgs;
13605     m_actionData.createData.lpProcessAttributes = lpProcessAttributes;
13606     m_actionData.createData.lpThreadAttributes = lpThreadAttributes;
13607     m_actionData.createData.bInheritHandles = bInheritHandles;
13608     m_actionData.createData.dwCreationFlags = dwCreationFlags;
13609     m_actionData.createData.lpEnvironment = lpEnvironment;
13610     m_actionData.createData.lpCurrentDirectory = lpCurrentDirectory;
13611     m_actionData.createData.lpStartupInfo = lpStartupInfo;
13612     m_actionData.createData.lpProcessInformation = lpProcessInformation;
13613     m_actionData.createData.corDebugFlags = corDebugFlags;
13614
13615     // m_action is set last so that the win32 event thread can inspect
13616     // it and take action without actually having to take any
13617     // locks. The lock around this here is simply to prevent multiple
13618     // threads from making requests at the same time.
13619     m_action = W32ETA_CREATE_PROCESS;
13620
13621     BOOL succ = SetEvent(m_threadControlEvent);
13622
13623     if (succ)
13624     {
13625       DWORD ret = WaitForSingleObject(m_actionTakenEvent, INFINITE);
13626
13627         LOG((LF_CORDB, LL_EVERYTHING, "Process Handle is: %x, m_threadControlEvent is %x\n", 
13628              (UINT_PTR)m_actionData.createData.lpProcessInformation->hProcess, (UINT_PTR)m_threadControlEvent));
13629
13630         if (ret == WAIT_OBJECT_0)
13631             hr = m_actionResult;
13632         else
13633             hr = HRESULT_FROM_GetLastError();
13634     }
13635     else
13636         hr = HRESULT_FROM_GetLastError();
13637
13638     UnlockSendToWin32EventThreadMutex();
13639
13640     return hr;
13641 }
13642
13643
13644 //---------------------------------------------------------------------------------------
13645 //
13646 // Create a process
13647 //
13648 // Assumptions:
13649 //    This occurs on the win32 event thread. It is invokved via
13650 //    a message sent from code:CordbWin32EventThread::SendCreateProcessEvent 
13651 //
13652 // Notes:
13653 //    Create a new process. This is called in the context of the Win32
13654 //    event thread to ensure that if we're Win32 debugging the process
13655 //    that the same thread that waits for debugging events will be the
13656 //    thread that creates the process.
13657 //
13658 //---------------------------------------------------------------------------------------
13659 void CordbWin32EventThread::CreateProcess()
13660 {
13661     m_action = W32ETA_NONE;
13662     HRESULT hr = S_OK;
13663
13664     DWORD dwCreationFlags = m_actionData.createData.dwCreationFlags;
13665
13666     // If the creation flags has DEBUG_PROCESS in them, then we're
13667     // Win32 debugging this process. Otherwise, we have to create
13668     // suspended to give us time to setup up our side of the IPC
13669     // channel.
13670     BOOL fInteropDebugging   = 
13671 #if defined(FEATURE_INTEROP_DEBUGGING)
13672         (dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS));
13673 #else
13674         false; // Interop not supported.
13675 #endif
13676
13677     // Have Win32 create the process...
13678     hr = m_pNativePipeline->CreateProcessUnderDebugger(
13679                                       m_actionData.createData.machineInfo,
13680                                       m_actionData.createData.programName,
13681                                       m_actionData.createData.programArgs,
13682                                       m_actionData.createData.lpProcessAttributes,
13683                                       m_actionData.createData.lpThreadAttributes,
13684                                       m_actionData.createData.bInheritHandles,
13685                                       dwCreationFlags,
13686                                       m_actionData.createData.lpEnvironment,
13687                                       m_actionData.createData.lpCurrentDirectory,
13688                                       m_actionData.createData.lpStartupInfo,
13689                                       m_actionData.createData.lpProcessInformation);
13690
13691     if (SUCCEEDED(hr))
13692     {
13693         // Process ID is filled in after process is succesfully created.
13694         DWORD dwProcessId = m_actionData.createData.lpProcessInformation->dwProcessId;
13695
13696         RSUnsafeExternalSmartPtr<CordbProcess> pProcess;
13697         hr = m_pShim->InitializeDataTarget(dwProcessId);
13698
13699         if (SUCCEEDED(hr))
13700         {
13701             // To emulate V2 semantics, we pass 0 for the clrInstanceID into
13702             // OpenVirtualProcess. This will then connect to the first CLR
13703             // loaded.
13704             const ULONG64 cFirstClrLoaded = 0;
13705             hr = CordbProcess::OpenVirtualProcess(cFirstClrLoaded, m_pShim->GetDataTarget(), NULL, m_cordb, dwProcessId, m_pShim, &pProcess);
13706         }
13707
13708         // Shouldn't happen on a create, only an attach
13709         _ASSERTE(hr != CORDBG_E_DEBUGGER_ALREADY_ATTACHED);
13710
13711         // Remember the process in the global list of processes.
13712         if (SUCCEEDED(hr))
13713         {   
13714             EX_TRY
13715             {
13716                 // Mark if we're interop-debugging
13717                 if (fInteropDebugging)
13718                 {
13719                     pProcess->EnableInteropDebugging(); 
13720                 }
13721
13722                 m_cordb->AddProcess(pProcess); // will take ref if it succeeds
13723             } 
13724             EX_CATCH_HRESULT(hr);
13725         }
13726
13727         // If we're Win32 attached to this process, then increment the
13728         // proper count, otherwise add this process to the wait set
13729         // and resume the process's main thread.
13730         if (SUCCEEDED(hr))
13731         {
13732             _ASSERTE(m_pProcess == NULL);
13733             m_pProcess.Assign(pProcess);   
13734         }
13735     }
13736
13737
13738     //
13739     // Signal the hr to the caller.
13740     //
13741     m_actionResult = hr;
13742     SetEvent(m_actionTakenEvent);
13743 }
13744
13745
13746 //
13747 // Send a DebugActiveProcess event to the Win32 thread to have it attach to
13748 // a new process.
13749 //
13750 HRESULT CordbWin32EventThread::SendDebugActiveProcessEvent(
13751                                                   MachineInfo machineInfo,
13752                                                   DWORD pid,
13753                                                   bool fWin32Attach,
13754                                                   CordbProcess *pProcess)
13755 {
13756     HRESULT hr = S_OK;
13757
13758     LockSendToWin32EventThreadMutex();
13759
13760     m_actionData.attachData.machineInfo = machineInfo;
13761     m_actionData.attachData.processId = pid;
13762 #if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
13763     m_actionData.attachData.fWin32Attach = fWin32Attach;
13764 #endif
13765     m_actionData.attachData.pProcess = pProcess;
13766
13767     // m_action is set last so that the win32 event thread can inspect
13768     // it and take action without actually having to take any
13769     // locks. The lock around this here is simply to prevent multiple
13770     // threads from making requests at the same time.
13771     m_action = W32ETA_ATTACH_PROCESS;
13772
13773     BOOL succ = SetEvent(m_threadControlEvent);
13774
13775     if (succ)
13776     {
13777         DWORD ret = WaitForSingleObject(m_actionTakenEvent, INFINITE);
13778
13779         if (ret == WAIT_OBJECT_0)
13780             hr = m_actionResult;
13781         else
13782             hr = HRESULT_FROM_GetLastError();
13783     }
13784     else
13785         hr = HRESULT_FROM_GetLastError();
13786
13787     UnlockSendToWin32EventThreadMutex();
13788
13789     return hr;
13790 }
13791
13792 //-----------------------------------------------------------------------------
13793 // Is the given thread id a helper thread (real or worker?)
13794 //-----------------------------------------------------------------------------
13795 bool CordbProcess::IsHelperThreadWorked(DWORD tid)
13796 {
13797     // Check against the id gained by sniffing Thread-Create events.
13798     if (tid == this->m_helperThreadId)
13799     {
13800         return true;
13801     }
13802
13803     // Now check for potential datate in the IPC block. If not there,
13804     // then we know it can't be the helper.
13805     DebuggerIPCControlBlock * pDCB = this->GetDCB();
13806
13807     if (pDCB == NULL)
13808     {
13809         return false;
13810     }
13811
13812     // get the latest information from the LS DCB
13813     UpdateRightSideDCB();
13814     return
13815         (tid == pDCB->m_realHelperThreadId) ||
13816         (tid == pDCB->m_temporaryHelperThreadId);
13817
13818 }
13819
13820 //---------------------------------------------------------------------------------------
13821 //
13822 // Cleans up the Left Side's DCB after a failed attach attempt.
13823 //
13824 // Assumptions:
13825 //    Called when the left-site failed initialization
13826 //
13827 // Notes:
13828 //    This can be called multiple times.
13829 //---------------------------------------------------------------------------------------
13830 void CordbProcess::CleanupHalfBakedLeftSide()
13831 {
13832     if (GetDCB() != NULL)
13833     {
13834         EX_TRY
13835         {
13836             GetDCB()->m_rightSideIsWin32Debugger = false;
13837             UpdateLeftSideDCBField(&(GetDCB()->m_rightSideIsWin32Debugger), sizeof(GetDCB()->m_rightSideIsWin32Debugger));
13838
13839             if (m_pEventChannel != NULL)
13840             {
13841                 m_pEventChannel->Delete();
13842                 m_pEventChannel = NULL;
13843             }
13844         }
13845         EX_CATCH
13846         {
13847             _ASSERTE(!"Writing process memory failed, perhaps due to an unexpected disconnection from the target."); 
13848         }
13849         EX_END_CATCH(SwallowAllExceptions);
13850     }
13851
13852     // Close and null out the various handles and events, including our process handle m_handle.
13853     CloseIPCHandles();
13854
13855     m_cordb.Clear();
13856     
13857     // This process object is Dead-On-Arrival, so it doesn't really have anything to neuter.
13858     // But for safekeeping, we'll mark it as neutered.
13859     UnsafeNeuterDeadObject(); 
13860 }
13861
13862
13863 //---------------------------------------------------------------------------------------
13864 //
13865 // Attach to an existing process.
13866 //
13867 //
13868 // Assumptions:
13869 //    Called on W32Event Thread, in response to event sent by 
13870 //    code:CordbWin32EventThread::SendDebugActiveProcessEvent 
13871 //
13872 // Notes:
13873 //    Attach to a process. This is called in the context of the Win32
13874 //    event thread to ensure that if we're Win32 debugging the process
13875 //    that the same thread that waits for debugging events will be the
13876 //    thread that attaches the process.
13877 //
13878 //    @dbgtodo shim: this will be part of the shim
13879 //---------------------------------------------------------------------------------------
13880 void CordbWin32EventThread::AttachProcess()
13881 {
13882     _ASSERTE(IsWin32EventThread());
13883
13884     RSUnsafeExternalSmartPtr<CordbProcess> pProcess;
13885
13886     m_action = W32ETA_NONE;
13887
13888     HRESULT hr = S_OK;
13889
13890     DWORD dwProcessId = m_actionData.attachData.processId;
13891     bool fNativeAttachSucceeded = false;
13892
13893
13894     // Always do OS attach to the target.
13895     // By this point, the pid should be valid (because OpenProcess above), pending some race where the process just exited.
13896     // The OS will enforce that only 1 debugger is attached. 
13897     // Common failure paths here would be: access denied, double-attach    
13898     {
13899         hr = m_pNativePipeline->DebugActiveProcess(m_actionData.attachData.machineInfo,
13900                                                    dwProcessId);
13901         if (FAILED(hr))
13902         {
13903             goto LExit;
13904         }
13905         fNativeAttachSucceeded = true;
13906     }
13907
13908     
13909     hr = m_pShim->InitializeDataTarget(m_actionData.attachData.processId);
13910     if (FAILED(hr))
13911     {
13912         goto LExit;
13913     }
13914
13915     // To emulate V2 semantics, we pass 0 for the clrInstanceID into
13916     // OpenVirtualProcess. This will then connect to the first CLR
13917     // loaded.    
13918     {
13919         const ULONG64 cFirstClrLoaded = 0;
13920         hr = CordbProcess::OpenVirtualProcess(cFirstClrLoaded, m_pShim->GetDataTarget(), NULL, m_cordb, dwProcessId, m_pShim, &pProcess);   
13921         if (FAILED(hr))
13922         {
13923             goto LExit;
13924         }
13925     }
13926
13927     // Remember the process in the global list of processes.    
13928     // The caller back in code:Cordb::DebugActiveProcess will then get this by fetching it from the list.
13929
13930     EX_TRY
13931     {
13932         // Mark interop-debugging
13933         if (m_actionData.attachData.IsInteropDebugging())
13934         {
13935             pProcess->EnableInteropDebugging(); // Throwing
13936         }
13937
13938         m_cordb->AddProcess(pProcess); // will take ref if it succeeds
13939
13940
13941         // Queue fake Attach event for CreateProcess
13942         {
13943             PUBLIC_CALLBACK_IN_THIS_SCOPE0_NO_LOCK(pProcess);
13944             m_pShim->BeginQueueFakeAttachEvents();
13945         }
13946     } 
13947     EX_CATCH_HRESULT(hr);
13948     if (FAILED(hr))
13949     {
13950         goto LExit;
13951     }
13952
13953     _ASSERTE(m_pProcess == NULL);
13954     m_pProcess.Assign(pProcess);
13955     pProcess.Clear();     // ownership transfered to m_pProcess
13956
13957     // Should have succeeded if we got to this point.
13958     _ASSERTE(SUCCEEDED(hr));
13959
13960
13961 LExit:
13962     if (FAILED(hr))
13963     {        
13964         // If we succeed to do a native-attach, but then failed elsewhere, try to native-detach.
13965         if (fNativeAttachSucceeded)
13966         {
13967             m_pNativePipeline->DebugActiveProcessStop(dwProcessId);
13968         }
13969
13970         if (pProcess != NULL)
13971         {
13972             // Safe to call this even if the process wasn't added.
13973             m_cordb->RemoveProcess(pProcess);
13974             pProcess->CleanupHalfBakedLeftSide();
13975             pProcess.Clear();
13976         }
13977         m_pProcess.Clear();
13978     }
13979
13980     //
13981     // Signal the hr to the caller.
13982     //
13983     m_actionResult = hr;
13984     SetEvent(m_actionTakenEvent);
13985 }
13986
13987
13988 // Note that the actual 'DetachProcess' method is really ExitProcess with CW32ET_UNKNOWN_PROCESS_SLOT ==
13989 // processSlot
13990 HRESULT CordbWin32EventThread::SendDetachProcessEvent(CordbProcess *pProcess)
13991 {
13992     LOG((LF_CORDB, LL_INFO1000, "W32ET::SDPE\n"));
13993     HRESULT hr = S_OK;
13994
13995     LockSendToWin32EventThreadMutex();
13996
13997     m_actionData.detachData.pProcess = pProcess;
13998
13999     // m_action is set last so that the win32 event thread can inspect it and take action without actually
14000     // having to take any locks. The lock around this here is simply to prevent multiple threads from making
14001     // requests at the same time.
14002     m_action = W32ETA_DETACH;
14003
14004     BOOL succ = SetEvent(m_threadControlEvent);
14005
14006     if (succ)
14007     {
14008         DWORD ret = WaitForSingleObject(m_actionTakenEvent, INFINITE);
14009
14010         if (ret == WAIT_OBJECT_0)
14011             hr = m_actionResult;
14012         else
14013             hr = HRESULT_FROM_GetLastError();
14014     }
14015     else
14016         hr = HRESULT_FROM_GetLastError();
14017
14018     UnlockSendToWin32EventThreadMutex();
14019
14020     return hr;
14021 }
14022
14023 #ifdef FEATURE_INTEROP_DEBUGGING
14024 //
14025 // Send a UnmanagedContinue event to the Win32 thread to have it
14026 // continue from an unmanged debug event.
14027 //
14028 HRESULT CordbWin32EventThread::SendUnmanagedContinue(CordbProcess *pProcess,
14029                                                      EUMContinueType eContType)
14030 {
14031     HRESULT hr = S_OK;
14032
14033     // If this were being called on the win32 EventThread, we'd deadlock.
14034     _ASSERTE(!IsWin32EventThread());
14035
14036     // This can't hold the process lock, b/c we're making a cross-thread call,
14037     // and our target will need the process lock.
14038     _ASSERTE(!pProcess->ThreadHoldsProcessLock());
14039
14040     LockSendToWin32EventThreadMutex();
14041
14042     m_actionData.continueData.process = pProcess;
14043     m_actionData.continueData.eContType = eContType;
14044
14045     // m_action is set last so that the win32 event thread can inspect
14046     // it and take action without actually having to take any
14047     // locks. The lock around this here is simply to prevent multiple
14048     // threads from making requests at the same time.
14049     m_action = W32ETA_CONTINUE;
14050
14051     BOOL succ = SetEvent(m_threadControlEvent);
14052
14053     if (succ)
14054     {
14055         DWORD ret = WaitForSingleObject(m_actionTakenEvent, INFINITE);
14056
14057         if (ret == WAIT_OBJECT_0)
14058             hr = m_actionResult;
14059         else
14060             hr = HRESULT_FROM_GetLastError();
14061     }
14062     else
14063         hr = HRESULT_FROM_GetLastError();
14064
14065     UnlockSendToWin32EventThreadMutex();
14066
14067     return hr;
14068 }
14069
14070
14071 //
14072 // Handle unmanaged continue. Continue an unmanaged debug
14073 // event. Deferes to UnmanagedContinue. This is called in the context
14074 // of the Win32 event thread to ensure that if we're Win32 debugging
14075 // the process that the same thread that waits for debugging events
14076 // will be the thread that continues the process.
14077 //
14078 void CordbWin32EventThread::HandleUnmanagedContinue()
14079 {
14080     _ASSERTE(IsWin32EventThread());
14081
14082     m_action = W32ETA_NONE;
14083     HRESULT hr = S_OK;
14084
14085     // Continue the process
14086     CordbProcess *pProcess = m_actionData.continueData.process;
14087
14088     // If we lost the process object, we must have exited.
14089     if (m_pProcess != NULL)
14090     {
14091         _ASSERTE(m_pProcess != NULL);
14092         _ASSERTE(pProcess == m_pProcess);
14093
14094         _ASSERTE(!pProcess->ThreadHoldsProcessLock());
14095
14096         RSSmartPtr<CordbProcess> proc(pProcess);
14097         RSLockHolder ch(&pProcess->m_processMutex);
14098
14099         hr = UnmanagedContinue(pProcess, m_actionData.continueData.eContType);
14100     }
14101
14102     // Signal the hr to the caller.
14103     m_actionResult = hr;
14104     SetEvent(m_actionTakenEvent);
14105 }
14106
14107 //
14108 // Continue an unmanaged debug event. This is called in the context of the Win32 Event thread to ensure that the same
14109 // thread that waits for debug events will be the thread that continues the process.
14110 //
14111 HRESULT CordbWin32EventThread::UnmanagedContinue(CordbProcess *pProcess,
14112                                                  EUMContinueType eContType)
14113 {
14114     _ASSERTE(pProcess->ThreadHoldsProcessLock());
14115     _ASSERTE(IsWin32EventThread());
14116     _ASSERTE(m_pShim != NULL);
14117
14118     HRESULT hr = S_OK;
14119
14120     STRESS_LOG1(LF_CORDB, LL_INFO1000, "UM Continue. type=%d\n", eContType);
14121
14122     if (eContType == cOobUMContinue)
14123     {
14124         _ASSERTE(pProcess->m_outOfBandEventQueue != NULL);
14125
14126         // Dequeue the OOB event.
14127         CordbUnmanagedEvent *ue = pProcess->m_outOfBandEventQueue;
14128         CordbUnmanagedThread *ut = ue->m_owner;
14129         pProcess->DequeueOOBUnmanagedEvent(ut);
14130
14131         // Do a little extra work if that was an OOB exception event...
14132         hr = ue->m_owner->FixupAfterOOBException(ue);
14133         _ASSERTE(SUCCEEDED(hr));
14134
14135         // Continue from the event.
14136         DoDbgContinue(pProcess, ue);
14137
14138         // If there are more queued OOB events, dispatch them now.
14139         if (pProcess->m_outOfBandEventQueue != NULL)
14140             pProcess->DispatchUnmanagedOOBEvent();
14141
14142         // Note: if we previously skipped letting the entire process go on an IB continue due to a blocking OOB event,
14143         // and if the OOB event queue is now empty, then go ahead and let the process continue now...
14144         if ((pProcess->m_doRealContinueAfterOOBBlock == true) &&
14145             (pProcess->m_outOfBandEventQueue == NULL))
14146             goto doRealContinue;
14147     }
14148     else if (eContType == cInternalUMContinue)
14149     {
14150         // We're trying to get into a synced state which means we need the process running (potentially
14151         // with some threads hijacked) in order to have the helper thread do the sync.
14152         LOG((LF_CORDB, LL_INFO1000, "W32ET::UC: internal continue.\n"));
14153
14154         if (!pProcess->GetSynchronized())
14155         {
14156             LOG((LF_CORDB, LL_INFO1000, "W32ET::UC: internal continue, !sync'd.\n"));
14157             pProcess->ResumeUnmanagedThreads();
14158
14159             // the event we may need to hijack and continue;
14160             CordbUnmanagedEvent* pEvent = pProcess->m_lastQueuedUnmanagedEvent;
14161
14162             // It is possible to be stopped at either an IB or an OOB event here. We only want to
14163             // continue from an IB event here though
14164             if(pProcess->m_state & CordbProcess::PS_WIN32_STOPPED && pEvent != NULL &&
14165                 pEvent->IsEventWaitingForContinue())
14166             {
14167                 LOG((LF_CORDB, LL_INFO1000, "W32ET::UC: internal continue, frozen on IB event.\n"));
14168
14169                 // There should be a uncontinued IB event at the head of the queue
14170                 _ASSERTE(pEvent->IsIBEvent());
14171                 _ASSERTE(!pEvent->IsEventContinuedUnhijacked());
14172                 _ASSERTE(!pEvent->IsEventContinuedHijacked());
14173
14174                 // Ensure that the event is hijacked now (it may not have been before) so that the
14175                 // thread does not slip forward during the sync process. After that we can safely continue
14176                 // it.
14177                 pProcess->HijackIBEvent(pEvent);
14178                 m_pShim->GetWin32EventThread()->DoDbgContinue(pProcess, pEvent);
14179             }
14180         }
14181
14182         LOG((LF_CORDB, LL_INFO1000, "W32ET::UC: internal continue, done.\n"));
14183     }
14184     else
14185     {
14186         // If we're here, then we know 100% for sure that we've successfully gotten the managed continue event to the
14187         // Left Side, so we can stop force hijacking left over in-band events now. Note: if we had hijacked any such
14188         // events, they'll be dispatched below since they're properly queued.
14189         pProcess->m_specialDeferment = false;
14190
14191         // We don't actually do any work if there is an outstanding out-of-band event. When we do continue from the
14192         // out-of-band event, we'll do this work, too.
14193         if (pProcess->m_outOfBandEventQueue != NULL)
14194         {
14195             LOG((LF_CORDB, LL_INFO1000, "W32ET::UC: ignoring real continue due to block by out-of-band event(s).\n"));
14196
14197             _ASSERTE(pProcess->m_doRealContinueAfterOOBBlock == false);
14198             pProcess->m_doRealContinueAfterOOBBlock = true;
14199         }
14200         else
14201         {
14202 doRealContinue:
14203             // This is either the Frozen -> Running transition or a
14204             // Synced -> Running transition
14205             _ASSERTE(pProcess->m_outOfBandEventQueue == NULL);
14206             
14207
14208             pProcess->m_doRealContinueAfterOOBBlock = false;
14209
14210             LOG((LF_CORDB, LL_INFO1000, "W32ET::UC: continuing the process.\n"));
14211             // Dispatch any more queued in-band events, or if there are none then just continue the process.
14212             //
14213             // Note: don't dispatch more events if we've already sent up the ExitProcess event... those events are just
14214             // lost.
14215             if ((pProcess->HasUndispatchedNativeEvents()) && (pProcess->m_exiting == false))
14216             {
14217                 pProcess->DispatchUnmanagedInBandEvent();
14218             }
14219             else
14220             {
14221                 // If the unmanaged event queue is empty now, and the process is synchronized, and there are queued
14222                 // managed events, then go ahead and get more managed events dispatched.
14223                 //
14224                 // Note: don't dispatch more events if we've already sent up the ExitProcess event... those events are
14225                 // just lost.
14226                 if (pProcess->GetSynchronized() && (!m_pShim->GetManagedEventQueue()->IsEmpty()) && (pProcess->m_exiting == false))
14227                 {
14228                     if(pProcess->m_state & CordbProcess::PS_WIN32_STOPPED)
14229                     {
14230                         DoDbgContinue(pProcess, pProcess->m_lastDispatchedIBEvent);
14231                         
14232                         // This if should not be necessary, I am just being extra careful because this
14233                         // fix is going in late - see issue 818301
14234                         _ASSERTE(pProcess->m_lastDispatchedIBEvent != NULL);
14235                         if(pProcess->m_lastDispatchedIBEvent != NULL)
14236                         {
14237                             pProcess->m_lastDispatchedIBEvent->m_owner->InternalRelease();
14238                         pProcess->m_lastDispatchedIBEvent = NULL;
14239                     }
14240                     }
14241
14242                     // Now, get more managed events dispatched.
14243                     pProcess->SetSynchronized(false);
14244                     pProcess->MarkAllThreadsDirty();
14245                     m_cordb->ProcessStateChanged();
14246                 }
14247                 else
14248                 {
14249                     // free all the hijacked threads that hit native debug events
14250                     pProcess->ResumeHijackedThreads();
14251                     
14252                     // after continuing the here the process should be running completely
14253                     // free... no hijacks, no suspended threads, and of course not frozen
14254                     if(pProcess->m_state & CordbProcess::PS_WIN32_STOPPED)
14255                     {
14256                         DoDbgContinue(pProcess, pProcess->m_lastDispatchedIBEvent);
14257                         // This if should not be necessary, I am just being extra careful because this
14258                         // fix is going in late - see issue 818301
14259                         _ASSERTE(pProcess->m_lastDispatchedIBEvent != NULL);
14260                         if(pProcess->m_lastDispatchedIBEvent != NULL)
14261                         {
14262                             pProcess->m_lastDispatchedIBEvent->m_owner->InternalRelease();
14263                         pProcess->m_lastDispatchedIBEvent = NULL;
14264                     }
14265                 }
14266             }
14267             }
14268
14269             // Implicit Release on UT
14270         }
14271     }
14272
14273     return hr;
14274 }
14275 #endif // FEATURE_INTEROP_DEBUGGING
14276
14277 void ExitProcessWorkItem::Do()
14278 {
14279     STRESS_LOG1(LF_CORDB, LL_INFO1000, "ExitProcessWorkItem proc=%p\n", GetProcess());
14280
14281     // This is being called on the RCET.
14282     // That's the thread that dispatches managed events. Since it's calling us now, we know
14283     // it can't be dispatching a managed event, and so we don't need to both waiting for it
14284
14285     {
14286         // Get the SG lock here to coordinate against any other continues.
14287         RSLockHolder ch(GetProcess()->GetStopGoLock());
14288         RSLockHolder ch2(&(GetProcess()->m_processMutex));
14289
14290         LOG((LF_CORDB, LL_INFO1000,"W32ET::EP: ExitProcess callback\n"));
14291
14292         // We're synchronized now, so mark the process as such.
14293         GetProcess()->SetSynchronized(true);
14294         GetProcess()->IncStopCount();
14295
14296         // By the time we release the SG + Process locks here, the process object has been
14297         // marked as exiting + terminated (by the w32et which queued us). Future attemps to
14298         // continue should fail, and thus we should remain synchronized.
14299     }
14300
14301
14302     //  Just to be safe, neuter any children before the exit process callback.
14303     {
14304         RSLockHolder ch(GetProcess()->GetProcessLock());
14305
14306         // Release the process.
14307         GetProcess()->NeuterChildren();
14308     }
14309
14310     RSSmartPtr<Cordb> pCordb(NULL);
14311
14312     // There is a race condition here where the debuggee process is killed while we are processing a process
14313     // detach.  We queue the process exit event for the Win32 event thread before queueing the process detach
14314     // event.  By the time this function is executed, we may have neutered the CordbProcess already as a 
14315     // result of code:CordbProcess::Detach.  Detect that case here under the SG lock.
14316     {
14317         RSLockHolder ch(GetProcess()->GetStopGoLock());
14318         if (!GetProcess()->IsNeutered())
14319         {
14320             _ASSERTE(GetProcess()->m_cordb != NULL);
14321             pCordb.Assign(GetProcess()->m_cordb);
14322         }
14323     }
14324
14325     // Move this into Shim?
14326
14327     // Invoke the ExitProcess callback. This is very important since the a shell
14328     // may rely on it for proper shutdown and may hang if they don't get it.
14329     // We don't expect Cordbg to continue from this (we're certainly not going to wait for it).
14330     if ((pCordb != NULL) && (pCordb->m_managedCallback != NULL))
14331     {
14332         PUBLIC_CALLBACK_IN_THIS_SCOPE0_NO_LOCK(GetProcess());
14333         pCordb->m_managedCallback->ExitProcess(GetProcess());
14334     }
14335
14336     // This CordbProcess object now has no reservations against a client calling ICorDebug::Terminate.
14337     // That call may race against the CordbProcess::Neuter below, but since we already neutered the children,
14338     // that neuter call will not do anything interesting that will conflict with Terminate.
14339     
14340     LOG((LF_CORDB, LL_INFO1000,"W32ET::EP: returned from ExitProcess callback\n"));
14341
14342     {
14343         RSLockHolder ch(GetProcess()->GetStopGoLock());
14344
14345         // Release the process.
14346         GetProcess()->Neuter();
14347     }
14348
14349     // Our dtor will release the Process object.
14350     // This may be the final release on the process.
14351 }
14352
14353
14354 //---------------------------------------------------------------------------------------
14355 //
14356 // Handles process exiting and detach cases
14357 //
14358 // Arguments:
14359 //    fDetach - true if detaching, false if process is exiting.
14360 //
14361 // Return Value:
14362 //    The type of the next argument in the signature,
14363 //    normalized.
14364 //
14365 // Assumptions:
14366 //    On exit, the process has already exited and we detected this by either an EXIT_PROCESS
14367 //    native debug event, or by waiting on the process handle.
14368 //    On detach, the process is stil live.
14369 //
14370 // Notes:
14371 //    ExitProcess is called when a process exits or detaches.
14372 //    This does our final cleanup and removes the process from our wait sets.
14373 //    We're either here because we're detaching (fDetach == TRUE), or because the process has really exited,
14374 //    and we're doing shutdown logic.
14375 //
14376 //---------------------------------------------------------------------------------------
14377 void CordbWin32EventThread::ExitProcess(bool fDetach)
14378 {
14379     INTERNAL_API_ENTRY(this);
14380
14381     // Consider the following when you're modifying this function:
14382     // - The OS can kill the debuggee at any time.
14383     // - ExitProcess can race with detach.
14384
14385     LOG((LF_CORDB, LL_INFO1000,"W32ET::EP: begin ExitProcess, detach=%d\n", fDetach));
14386
14387
14388     // For the Mac remote debugging transport, DebugActiveProcessStop() is a nop.  The transport will be
14389     // shut down later when we neuter the CordbProcess.
14390 #if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
14391     // @dbgtodo shim: this is a primitive workaround for interop-detach
14392     // Eventually, the Debugger owns the detach pipeline, so this won't be necessary.
14393     if (fDetach && (m_pProcess != NULL))
14394     {
14395         HRESULT hr = m_pNativePipeline->DebugActiveProcessStop(m_pProcess->GetPid());
14396
14397         // We don't expect detach to fail (we check earlier for common conditions that
14398         // may cause it to fail)
14399         SIMPLIFYING_ASSUMPTION(SUCCEEDED(hr));
14400         if( FAILED(hr) )
14401         {
14402             m_actionResult = hr;
14403             SetEvent(m_actionTakenEvent);
14404             return;
14405         }
14406     }
14407 #endif // !FEATURE_DBGIPC_TRANSPORT_DI
14408
14409
14410     // We don't really care if we're on the Win32 thread or not here. We just want to be sure that
14411     // the LS Exit case and the Detach case both occur on the same thread. This makes it much easier
14412     // to assert that if we exit while detaching, EP is only called once.
14413     // If we ever decide to make the RCET listen on the LS process handle for EP(exit), then we should also
14414     // make the EP(detach) handled on the RCET (via DoFavor() ).
14415     _ASSERTE(IsWin32EventThread());
14416
14417     // So either the Exit case or Detach case must happen first.
14418     // 1) If Detach first, then LS process is removed from wait set and so EP(Exit) will never happen
14419     //    because we check wait set after returning from EP(Detach).
14420     // 2) If Exit is first, m_pProcess gets set=NULL. EP(detach) will still get called, so explicitly check that.
14421     if (fDetach && ((m_pProcess == NULL) || m_pProcess->m_terminated))
14422     {
14423         // m_terminated is only set after the LS exits.
14424         // So the only way (fDetach && m_terminated) is true is if the LS exited while detaching. In that case
14425         // we already called EP(exit) and we don't want to call it again for EP(detach). So return here.
14426         LOG((LF_CORDB, LL_INFO1000,"W32ET::EP: In EP(detach), but EP(exit) already called. Early failure\n"));
14427
14428         m_actionResult = CORDBG_E_PROCESS_TERMINATED;
14429         SetEvent(m_actionTakenEvent);
14430
14431         return;
14432     }
14433
14434     // We null m_pProcess at the end here, so
14435     // Only way we could get here w/ null process is if we're called twice. We can only be called
14436     // by detach or exit. Can't detach twice, can't exit twice, so must have been one of each.
14437     // If exit is first, we got removed from the wait set, so 2nd call must be detach and we'd catch
14438     // that above. If detach is first, we'd get removed from the wait set and so exit would never happen.
14439     _ASSERTE(m_pProcess != NULL);
14440     _ASSERTE(!m_pProcess->ThreadHoldsProcessLock());
14441
14442
14443
14444     // Mark the process teminated. After this, the RCET will never call FlushQueuedEvents. It will
14445     // ignore all events it receives (including a SyncComplete) and the RCET also does not listen
14446     // to terminated processes (so ProcessStateChange() won't cause a FQE either).
14447     m_pProcess->Terminating(fDetach);
14448
14449     // Take care of the race where the process exits right after the user calls Continue() from the last
14450     // managed event but before the handler has actually returned.
14451     //
14452     // Also, To get through this lock means that either:
14453     // 1. FlushQueuedEvents is not currently executing and no one will call FQE.
14454     // 2. FQE is exiting but is in the middle of a callback (so AreDispatchingEvent = true)
14455     //
14456     m_pProcess->Lock();
14457
14458     m_pProcess->m_exiting = true;
14459
14460     if (fDetach)
14461     {
14462         m_pProcess->SetSynchronized(false);
14463     }
14464
14465     // If we are exiting, we *must* dispatch the ExitProcess callback, but we will delete all the events
14466     // in the queue and not bother dispatching anything else. If (and only if) we are currently dispatching
14467     // an event, then we will wait while that event is finished before invoking ExitProcess.
14468     // (Note that a dispatched event has already been removed from the queue)
14469
14470     // Remove the process from the global list of processes.
14471     m_cordb->RemoveProcess(m_pProcess);
14472
14473     if (fDetach)
14474     {
14475         // Signal the hr to the caller.
14476         LOG((LF_CORDB, LL_INFO1000,"W32ET::EP: Detach: send result back!\n"));
14477
14478         m_actionResult = S_OK;
14479         SetEvent(m_actionTakenEvent);
14480     }
14481
14482     m_pProcess->Unlock();
14483
14484     // Delete all queued events
14485     m_pProcess->DeleteQueuedEvents();
14486
14487
14488     // If we're detaching, then the Detach already neutered everybody, so nothing here.
14489     // If we're exiting, then we still need to neuter things, but we can't do that on this thread,
14490     // so we queue it. We also need to dispatch an exit process callback. We'll queue that onto the RCET
14491     // and dispatch it inband w/the other callbacks.
14492     if (!fDetach)
14493     {
14494 #ifdef FEATURE_PAL
14495         // Cleanup the transport pipe and semaphore files that might be left by the target (LS) process.
14496         m_pNativePipeline->CleanupTargetProcess();
14497 #endif
14498         ExitProcessWorkItem * pItem = new (nothrow) ExitProcessWorkItem(m_pProcess);
14499         if (pItem != NULL)
14500         {
14501             m_cordb->m_rcEventThread->QueueAsyncWorkItem(pItem);
14502         }
14503     }
14504
14505     // This will remove the process from our wait lists (so that we don't send multiple ExitProcess events).
14506     m_pProcess.Clear();
14507 }
14508
14509
14510 //
14511 // Start actually creates and starts the thread.
14512 //
14513 HRESULT CordbWin32EventThread::Start()
14514 {
14515     HRESULT hr = S_OK;
14516     if (m_threadControlEvent == NULL)
14517         return E_INVALIDARG;
14518
14519     // Create the thread suspended to make sure that m_threadId is set
14520     // before CordbWin32EventThread::ThreadProc runs
14521     // Stack size = 0x80000 = 512KB
14522     m_thread = CreateThread(NULL, 0x80000, &CordbWin32EventThread::ThreadProc,
14523                             (LPVOID) this, CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, &m_threadId);
14524
14525     if (m_thread == NULL)
14526         return HRESULT_FROM_GetLastError();
14527
14528     DWORD succ = ResumeThread(m_thread);
14529     if (succ == (DWORD)-1)
14530         return HRESULT_FROM_GetLastError();
14531     return hr;
14532 }
14533
14534
14535 //
14536 // Stop causes the thread to stop receiving events and exit. It
14537 // waits for it to exit before returning.
14538 //
14539 HRESULT CordbWin32EventThread::Stop()
14540 {
14541     HRESULT hr = S_OK;
14542
14543     // m_pProcess may be NULL from CordbWin32EventThread::ExitProcess
14544
14545     // Can't block on W32ET while holding the process-lock since the W32ET may need that to exit.
14546     // But since m_pProcess may be null, we can't enforce that.
14547
14548     if (m_thread != NULL)
14549     {
14550         LockSendToWin32EventThreadMutex();
14551         m_action = W32ETA_NONE;
14552         m_run = FALSE;
14553
14554         SetEvent(m_threadControlEvent);
14555         UnlockSendToWin32EventThreadMutex();
14556
14557         DWORD ret = WaitForSingleObject(m_thread, INFINITE);
14558
14559         if (ret != WAIT_OBJECT_0)
14560             hr = HRESULT_FROM_GetLastError();
14561     }
14562
14563     m_pProcess.Clear();
14564     m_cordb.Clear();
14565
14566     return hr;
14567 }
14568
14569
14570
14571
14572
14573
14574
14575
14576 // Allocate a buffer of cbBuffer bytes in the target.
14577 // 
14578 // Arguments:
14579 //     cbBuffer - count of bytes for the buffer.
14580 //     
14581 // Returns:
14582 //     a TargetBuffer describing the new memory region in the target.
14583 //     Throws on error.
14584 TargetBuffer CordbProcess::GetRemoteBuffer(ULONG cbBuffer)
14585 {
14586     INTERNAL_SYNC_API_ENTRY(this); //
14587
14588     // Create and initialize the event as synchronous
14589     DebuggerIPCEvent event;
14590     InitIPCEvent(&event,
14591                  DB_IPCE_GET_BUFFER,
14592                  true,
14593                  VMPTR_AppDomain::NullPtr());
14594
14595     // Indicate the buffer size wanted
14596     event.GetBuffer.bufSize = cbBuffer;
14597
14598     // Make the request, which is synchronous
14599     HRESULT hr = SendIPCEvent(&event, sizeof(event));
14600     IfFailThrow(hr);
14601     _ASSERTE(event.type == DB_IPCE_GET_BUFFER_RESULT);
14602
14603     IfFailThrow(event.GetBufferResult.hr);
14604
14605     // The request succeeded. Return the newly allocated range.
14606     return TargetBuffer(event.GetBufferResult.pBuffer, cbBuffer);    
14607 }
14608
14609 /*
14610  * This will release a previously allocated left side buffer.
14611  */
14612 HRESULT CordbProcess::ReleaseRemoteBuffer(void **ppBuffer)
14613 {
14614     INTERNAL_SYNC_API_ENTRY(this); //
14615
14616     _ASSERTE(m_pShim != NULL);
14617
14618     // Create and initialize the event as synchronous
14619     DebuggerIPCEvent event;
14620     InitIPCEvent(&event,
14621                  DB_IPCE_RELEASE_BUFFER,
14622                  true,
14623                  VMPTR_AppDomain::NullPtr());
14624
14625     // Indicate the buffer to release
14626     event.ReleaseBuffer.pBuffer = (*ppBuffer);
14627
14628     // Make the request, which is synchronous
14629     HRESULT hr = SendIPCEvent(&event, sizeof(event));
14630     TESTANDRETURNHR(hr);
14631
14632     (*ppBuffer) = NULL;
14633
14634     // Indicate success
14635     return event.ReleaseBufferResult.hr;
14636 }
14637
14638 HRESULT CordbProcess::SetDesiredNGENCompilerFlags(DWORD dwFlags)
14639 {
14640     PUBLIC_API_ENTRY(this);
14641     FAIL_IF_NEUTERED(this);
14642
14643 #if defined(FEATURE_PREJIT)
14644     if ((dwFlags != CORDEBUG_JIT_DEFAULT) && (dwFlags != CORDEBUG_JIT_DISABLE_OPTIMIZATION))
14645     {
14646         return E_INVALIDARG;
14647     }
14648
14649     CordbProcess *pProcess = GetProcess();
14650     ATT_REQUIRE_STOPPED_MAY_FAIL(pProcess);
14651     HRESULT  hr = S_OK;
14652     EX_TRY
14653     {
14654         // Left-side checks that this is a valid time to set the Ngen flags.
14655         hr = pProcess->GetDAC()->SetNGENCompilerFlags(dwFlags);
14656         if (!SUCCEEDED(hr) && GetShim() != NULL)
14657         {
14658             // Emulate V2 error semantics. 
14659             hr = GetShim()->FilterSetNgenHresult(hr);
14660         }
14661     }
14662     EX_CATCH_HRESULT(hr);
14663     return hr;
14664
14665 #else  // !FEATURE_PREJIT
14666     return CORDBG_E_NGEN_NOT_SUPPORTED;
14667
14668 #endif // FEATURE_PREJIT
14669 }
14670
14671 HRESULT CordbProcess::GetDesiredNGENCompilerFlags(DWORD *pdwFlags )
14672 {
14673     PUBLIC_API_ENTRY(this);
14674     FAIL_IF_NEUTERED(this);
14675     VALIDATE_POINTER_TO_OBJECT(pdwFlags, DWORD*);
14676     *pdwFlags = 0;
14677
14678     CordbProcess *pProcess = GetProcess();
14679     ATT_REQUIRE_STOPPED_MAY_FAIL(pProcess);
14680     HRESULT  hr = S_OK;
14681     EX_TRY
14682     {
14683         hr = pProcess->GetDAC()->GetNGENCompilerFlags(pdwFlags);
14684     }
14685     EX_CATCH_HRESULT(hr);
14686     return hr;
14687 }
14688
14689 //-----------------------------------------------------------------------------
14690 // Get an ICorDebugReference Value for the GC handle.
14691 // handle - raw bits for the GC handle.
14692 // pOutHandle
14693 //-----------------------------------------------------------------------------
14694 HRESULT CordbProcess::GetReferenceValueFromGCHandle(
14695     UINT_PTR gcHandle,
14696     ICorDebugReferenceValue **pOutValue)
14697 {
14698     PUBLIC_API_ENTRY(this);
14699     FAIL_IF_NEUTERED(this);
14700     ATT_REQUIRE_STOPPED_MAY_FAIL(this);
14701     VALIDATE_POINTER_TO_OBJECT(pOutValue, ICorDebugReferenceValue*);
14702
14703     *pOutValue = NULL;
14704     HRESULT hr = S_OK;
14705
14706     EX_TRY
14707     {
14708         if (gcHandle == NULL)
14709         {
14710             ThrowHR(CORDBG_E_BAD_REFERENCE_VALUE);
14711         }
14712         
14713         IDacDbiInterface* pDAC = GetProcess()->GetDAC();
14714         VMPTR_OBJECTHANDLE vmObjHandle = pDAC->GetVmObjectHandle(gcHandle);
14715         if(!pDAC->IsVmObjectHandleValid(vmObjHandle))
14716         {
14717             ThrowHR(CORDBG_E_BAD_REFERENCE_VALUE);
14718         }
14719         ULONG appDomainId = pDAC->GetAppDomainIdFromVmObjectHandle(vmObjHandle);
14720         VMPTR_AppDomain vmAppDomain = pDAC->GetAppDomainFromId(appDomainId);
14721
14722         RSLockHolder lockHolder(GetProcessLock());
14723         CordbAppDomain * pAppDomain = LookupOrCreateAppDomain(vmAppDomain);
14724         lockHolder.Release();
14725
14726         // Now that we finally have the AppDomain, we can go ahead and get a ReferenceValue
14727         // from the ObjectHandle.
14728         hr = CordbReferenceValue::BuildFromGCHandle(pAppDomain, vmObjHandle, pOutValue);
14729         _ASSERTE(SUCCEEDED(hr) == (*pOutValue != NULL));
14730         IfFailThrow(hr);
14731     }
14732     EX_CATCH_HRESULT(hr);
14733     return hr;
14734 }
14735
14736 //-----------------------------------------------------------------------------
14737 // Return count of outstanding GC handles held by CordbHandleValue objects
14738 LONG CordbProcess::OutstandingHandles()
14739 {
14740     return m_cOutstandingHandles;
14741 }
14742
14743 //-----------------------------------------------------------------------------
14744 // Increment the outstanding handle count for code:CordbProces::OutstandingHandles
14745 // This is the inverse of code:CordbProces::DecrementOutstandingHandles
14746 void CordbProcess::IncrementOutstandingHandles()
14747 {
14748     _ASSERTE(ThreadHoldsProcessLock());
14749     m_cOutstandingHandles++;
14750 }
14751
14752 //-----------------------------------------------------------------------------
14753 // Decrement the outstanding handle count for code:CordbProces::OutstandingHandles
14754 // This is the inverse of code:CordbProces::IncrementOutstandingHandles
14755 void CordbProcess::DecrementOutstandingHandles()
14756 {
14757     _ASSERTE(ThreadHoldsProcessLock());
14758     m_cOutstandingHandles--;
14759 }
14760
14761
14762 /*
14763  * IsReadyForDetach
14764  *
14765  * This method encapsulates all logic for deciding if it is ok for a debugger to
14766  * detach from the process at this time.
14767  *
14768  * Parameters: None.
14769  *
14770  * Returns: S_OK if it is ok to detach, else a specific HRESULT describing why it
14771  *   is not ok to detach.
14772  *
14773  */
14774 HRESULT CordbProcess::IsReadyForDetach()
14775 {
14776     INTERNAL_API_ENTRY(this);
14777
14778     // Always safe to detach in V3 case.
14779     if (m_pShim == NULL)
14780     {
14781         return S_OK;
14782     }
14783
14784     // If not initialized yet, then there are no detach liabilities.
14785     if (!m_initialized)
14786     {
14787         return S_OK;
14788     }
14789
14790     RSLockHolder lockHolder(&this->m_processMutex);
14791
14792     //
14793     // If there are any outstanding func-evals then fail the detach.
14794     //
14795     if (OutstandingEvalCount() != 0)
14796     {
14797         return CORDBG_E_DETACH_FAILED_OUTSTANDING_EVALS;
14798     }
14799
14800     // V2 didn't check outstanding handles (code:CordbProcess::OutstandingHandles)
14801     // because it could automatically clean those up on detach.
14802
14803     //
14804     // If there are any outstanding steppers then fail the detach.
14805     //
14806     if (m_steppers.IsInitialized() && (m_steppers.GetCount() > 0))
14807     {
14808         return CORDBG_E_DETACH_FAILED_OUTSTANDING_STEPPERS;
14809     }
14810
14811     //
14812     // If there are any outstanding breakpoints then fail the detach.
14813     //
14814     HASHFIND foundAppDomain;
14815     CordbAppDomain *pAppDomain = m_appDomains.FindFirst(&foundAppDomain);
14816
14817     while (pAppDomain != NULL)
14818     {
14819         if (pAppDomain->m_breakpoints.IsInitialized() && (pAppDomain->m_breakpoints.GetCount() > 0))
14820         {
14821             return CORDBG_E_DETACH_FAILED_OUTSTANDING_BREAKPOINTS;
14822         }
14823
14824         // Check for any outstanding EnC modules.
14825         HASHFIND foundModule;
14826         CordbModule * pModule = pAppDomain->m_modules.FindFirst(&foundModule);
14827         while (pModule != NULL)
14828         {
14829             if (pModule->m_EnCCount > 0)
14830             {
14831                 return CORDBG_E_DETACH_FAILED_ON_ENC;
14832             }
14833             pModule = pAppDomain->m_modules.FindNext(&foundModule);
14834         }
14835
14836
14837         pAppDomain = m_appDomains.FindNext(&foundAppDomain);
14838     }
14839
14840     // If we're using the shim, give a chance to early-out if the OS doesn't support detach
14841     // so that the user can continue to debug in that case.
14842     // Ideally we'd just rely on the failure from DebugActiveProcessStop, but by then it's too late
14843     // to recover.  This function is our only chance to distinguish between graceful detach failures
14844     // and hard detach failures (after which the process object is neutered).
14845     if (m_pShim != NULL)
14846     {
14847 #if !defined(FEATURE_CORESYSTEM) // CORESYSTEM TODO
14848         HModuleHolder hKernel32;
14849         hKernel32 = WszLoadLibrary(W("kernel32"));
14850         if (hKernel32 == NULL)
14851             return HRESULT_FROM_GetLastError();
14852         typedef BOOL (*DebugActiveProcessStopSig) (DWORD);
14853         DebugActiveProcessStopSig pDebugActiveProcessStop = 
14854             reinterpret_cast<DebugActiveProcessStopSig>(GetProcAddress(hKernel32, "DebugActiveProcessStop"));
14855         if (pDebugActiveProcessStop == NULL)
14856             return COR_E_PLATFORMNOTSUPPORTED;
14857 #endif
14858     }    
14859
14860     return S_OK;
14861 }
14862
14863
14864 /*
14865  * Look for any thread which was last seen in the specified AppDomain.  
14866  * The CordbAppDomain object is about to be neutered due to an AD Unload
14867  * So the thread must no longer be considered to be in that domain.
14868  * Note that this is a workaround due to the existance of the (possibly incorrect) 
14869  * cached AppDomain value.  Ideally we would remove the cached value entirely
14870  * and there would be no need for this.
14871  * 
14872  * @dbgtodo: , appdomain: We should remove CordbThread::m_pAppDomain in the V3 architecture.
14873  * If we need the thread's current domain, we should get it accurately with DAC.
14874  */
14875 void CordbProcess::UpdateThreadsForAdUnload(CordbAppDomain * pAppDomain)
14876 {
14877     INTERNAL_API_ENTRY(this);
14878
14879     // If we're doing an AD unload then we should have already seen the ATTACH 
14880     // notification for the default domain.
14881     //_ASSERTE( m_pDefaultAppDomain != NULL );
14882     // @dbgtodo appdomain: fix Default domain invariants with DAC-izing Appdomain work.
14883     
14884     RSLockHolder lockHolder(GetProcessLock());
14885     
14886     CordbThread* t;
14887     HASHFIND find;
14888
14889     // We don't need to prepopulate here (to collect LS state) because we're just updating RS state.
14890     for (t =  m_userThreads.FindFirst(&find);
14891          t != NULL;
14892          t =  m_userThreads.FindNext(&find))
14893     {
14894         if( t->GetAppDomain() == pAppDomain )
14895         {
14896             // This thread cannot actually be in this AppDomain anymore (since it's being 
14897             // unloaded).  Reset it to point to the default AppDomain
14898             t->m_pAppDomain = m_pDefaultAppDomain;
14899         }
14900     }
14901 }
14902
14903 // CordbProcess::LookupClass
14904 // Looks up a previously constructed CordbClass instance without creating. May return NULL if the 
14905 // CordbClass instance doesn't exist.
14906 // Argument: (in) vmDomainFile - pointer to the domainfile for the module
14907 //           (in) mdTypeDef    - metadata token for the class
14908 // Return value: pointer to a previously created CordbClass instance or NULL in none exists
14909 CordbClass * CordbProcess::LookupClass(ICorDebugAppDomain * pAppDomain, VMPTR_DomainFile vmDomainFile, mdTypeDef classToken)
14910 {
14911     _ASSERTE(ThreadHoldsProcessLock());
14912
14913     if (pAppDomain != NULL)
14914     {
14915         CordbModule * pModule = ((CordbAppDomain *)pAppDomain)->m_modules.GetBase(VmPtrToCookie(vmDomainFile));
14916         if (pModule != NULL)
14917         {
14918             return pModule->LookupClass(classToken);
14919         }
14920     }
14921     return NULL;
14922 } // CordbProcess::LookupClass
14923
14924 //---------------------------------------------------------------------------------------
14925 // Look for a specific module in the process. 
14926 //
14927 // Arguments:
14928 //    vmDomainFile - non-null module to lookup
14929 // 
14930 // Returns:
14931 //    a CordbModule object for the given cookie. Object may be from the cache, or created
14932 //    lazily. 
14933 //    Never returns null.  Throws on error.
14934 //
14935 // Notes:
14936 //    A VMPTR_DomainFile has appdomain affinity, but is ultimately scoped to a process.
14937 //    So if we get a raw VMPTR_DomainFile (eg, from the stackwalker or from some other
14938 //    lookup function), then we need to do a process wide lookup since we don't know which 
14939 //    appdomain it's in. If you know the appdomain, you can use code:CordbAppDomain::LookupOrCreateModule.
14940 //    
14941 CordbModule * CordbProcess::LookupOrCreateModule(VMPTR_DomainFile vmDomainFile)
14942 {
14943     INTERNAL_API_ENTRY(this);
14944     
14945     RSLockHolder lockHolder(GetProcess()->GetProcessLock());
14946     _ASSERTE(!vmDomainFile.IsNull());
14947
14948     DomainFileInfo data;
14949     GetDAC()->GetDomainFileData(vmDomainFile, &data); // throws
14950     
14951     CordbAppDomain * pAppDomain = LookupOrCreateAppDomain(data.vmAppDomain);
14952     return pAppDomain->LookupOrCreateModule(vmDomainFile);
14953 }
14954
14955 //---------------------------------------------------------------------------------------
14956 // Determine if the process has any in-band queued events which have not been dispatched
14957 // 
14958 // Returns:
14959 //    TRUE iff there are undispatched IB events
14960 //
14961 #ifdef FEATURE_INTEROP_DEBUGGING
14962 BOOL CordbProcess::HasUndispatchedNativeEvents()
14963 {
14964     INTERNAL_API_ENTRY(this);
14965     
14966     CordbUnmanagedEvent* pEvent = m_unmanagedEventQueue;
14967     while(pEvent != NULL && pEvent->IsDispatched())
14968     {
14969         pEvent = pEvent->m_next;
14970     }
14971
14972     return pEvent != NULL;
14973 }
14974 #endif
14975
14976 //---------------------------------------------------------------------------------------
14977 // Determine if the process has any in-band queued events which have not been user continued
14978 // 
14979 // Returns:
14980 //    TRUE iff there are user uncontinued IB events
14981 //
14982 #ifdef FEATURE_INTEROP_DEBUGGING
14983 BOOL CordbProcess::HasUserUncontinuedNativeEvents()
14984 {
14985     INTERNAL_API_ENTRY(this);
14986     
14987     CordbUnmanagedEvent* pEvent = m_unmanagedEventQueue;
14988     while(pEvent != NULL && pEvent->IsEventUserContinued())
14989     {
14990         pEvent = pEvent->m_next;
14991     }
14992
14993     return pEvent != NULL;
14994 }
14995 #endif
14996
14997 //---------------------------------------------------------------------------------------
14998 // Hijack the thread which had this event. If the thread is already hijacked this method
14999 // has no effect.
15000 // 
15001 // Arguments:
15002 //    pUnmanagedEvent - the debug event which requires us to hijack
15003 //
15004 // Returns:
15005 //    S_OK on success, failing HRESULT if the hijack could not be set up
15006 //
15007 #ifdef FEATURE_INTEROP_DEBUGGING
15008 HRESULT CordbProcess::HijackIBEvent(CordbUnmanagedEvent * pUnmanagedEvent)
15009 {
15010     // Can't hijack after the event has already been continued hijacked
15011     _ASSERTE(!pUnmanagedEvent->IsEventContinuedHijacked());
15012     // Can only hijack IB events
15013     _ASSERTE(pUnmanagedEvent->IsIBEvent());
15014     
15015     // If we already hijacked the event then there is nothing left to do
15016     if(pUnmanagedEvent->m_owner->IsFirstChanceHijacked() ||
15017         pUnmanagedEvent->m_owner->IsGenericHijacked())
15018     {
15019         return S_OK;
15020     }
15021
15022     ResetEvent(this->m_leftSideUnmanagedWaitEvent);
15023     if (pUnmanagedEvent->m_currentDebugEvent.u.Exception.dwFirstChance)
15024     {
15025         HRESULT hr = pUnmanagedEvent->m_owner->SetupFirstChanceHijackForSync();
15026         SIMPLIFYING_ASSUMPTION(SUCCEEDED(hr));
15027         return hr;
15028     }
15029     else // Second chance exceptions must be generic hijacked.
15030     {
15031         HRESULT hr = pUnmanagedEvent->m_owner->SetupGenericHijack(pUnmanagedEvent->m_currentDebugEvent.dwDebugEventCode, &pUnmanagedEvent->m_currentDebugEvent.u.Exception.ExceptionRecord);
15032         SIMPLIFYING_ASSUMPTION(SUCCEEDED(hr));
15033         return hr;
15034     }
15035 }
15036 #endif
15037
15038 // Sets a bitfield reflecting the managed debugging state at the time of
15039 // the jit attach.
15040 HRESULT CordbProcess::GetAttachStateFlags(CLR_DEBUGGING_PROCESS_FLAGS *pFlags)
15041 {
15042     HRESULT hr = S_OK;
15043     PUBLIC_REENTRANT_API_BEGIN(this)
15044     {
15045         if(pFlags == NULL)
15046             hr = E_POINTER;
15047         else
15048             *pFlags = GetDAC()->GetAttachStateFlags();
15049     }
15050     PUBLIC_API_END(hr);
15051
15052     return hr;
15053 }
15054
15055 // Determine if this version of ICorDebug is compatibile with the ICorDebug in the specified major CLR version
15056 bool CordbProcess::IsCompatibleWith(DWORD clrMajorVersion)
15057 {
15058     // The debugger versioning policy is that debuggers generally need to opt-in to supporting major new 
15059     // versions of the CLR.  Often new versions of the CLR violate some invariant that previous debuggers assume
15060     // (eg. hot/cold splitting in Whidbey, multiple CLRs in a process in CLR v4), and neither VS or the CLR
15061     // teams generally want the support burden of forward compatibility.
15062
15063     //
15064     // If this assert is firing for you, its probably because the major version
15065     // number of the clr.dll has changed. This assert is here to remind you to do a bit of other
15066     // work you may not have realized you needed to do so that our versioning works smoothly
15067     // for debugging. You probably want to contact the CLR DST team if you are a
15068     // non-debugger person hitting this. DON'T JUST DELETE THIS ASSERT!!! 
15069     //
15070     // 1) You should ensure new versions of all ICorDebug users in DevDiv (VS Debugger, MDbg, etc.)
15071     //    are using a creation path that explicitly specifies that they support this new major 
15072     //    version of the CLR.
15073     // 2) You should file an issue to track blocking earlier debuggers from targetting this
15074     //    version of the CLR (i.e. update requiredVersion to the new CLR major
15075     //    version).  To enable a smooth internal transition, this often isn't done until absolutely
15076     //    necessary (sometimes as late as Beta2).
15077     // 3) You can consider updating the CLR_ID guid used by the shim to recognize a CLR, but only
15078     //    if it's important to completely hide newer CLRs from the shim.  The expectation now 
15079     //    is that we won't need to do this (i.e. we'd like VS to give a nice error message about
15080     //    needed a newer version of the debugger, rather than just acting as if a process has no CLR).
15081     // 4) Update this assert so that it no longer fires for your new CLR version or any of
15082     //    the previous versions, but don't delete the assert...
15083     //    the next CLR version after yours will probably need the same reminder
15084
15085     _ASSERTE_MSG(clrMajorVersion <= 4,
15086         "Found major CLR version greater than 4 in mscordbi.dll from CLRv4 - contact CLRDST");
15087
15088     // This knob lets us enable forward compatibility for internal scenarios, and also simulate new 
15089     // versions of the runtime for testing the failure user-experience in a version of the debugger 
15090     // before it is shipped.
15091     // We don't want to risk customers getting this, so for RTM builds this must be CHK-only.
15092     // To aid in internal transition, we may temporarily enable this in RET builds, but when
15093     // doing so must file a bug to track making it CHK only again before RTM.
15094     // For example, Dev10 Beta2 shipped with this knob, but it was made CHK-only at the start of RC.
15095     // In theory we might have a point release someday where we break debugger compat, but
15096     // it seems unlikely and since this knob is unsupported anyway we can always extend it
15097     // then (support reading a string value, etc.).  So for now we just map the number
15098     // to the major CLR version number.
15099     DWORD requiredVersion = 0;
15100 #ifdef _DEBUG
15101     requiredVersion = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_Debugging_RequiredVersion);
15102 #endif
15103
15104     // If unset (the only supported configuration), then we require a debugger designed for CLRv4
15105     //  for desktop, where we do not allow forward compat.
15106     // For SL, we allow forward compat.  Right now, that means SLv2+ debugger requests can be
15107     //  honored for SLv4.
15108     if (requiredVersion <= 0)
15109     {
15110         requiredVersion = 2;
15111     }
15112
15113     // Compare the version we were created for against the minimum required
15114     return (clrMajorVersion >= requiredVersion);
15115 }
15116
15117 bool CordbProcess::IsThreadSuspendedOrHijacked(ICorDebugThread * pICorDebugThread)
15118 {
15119     // An RS lock can be held while this is called. Specifically,
15120     // CordbThread::EnumerateChains may be on the stack, and it uses
15121     // ATT_REQUIRE_STOPPED_MAY_FAIL, which holds the CordbProcess::m_StopGoLock lock for
15122     // its entire duration. As a result, this needs to be considered a reentrant API. See
15123     // comments above code:PrivateShimCallbackHolder for more info.
15124     PUBLIC_REENTRANT_API_ENTRY_FOR_SHIM(this);
15125     
15126     CordbThread * pCordbThread = static_cast<CordbThread *> (pICorDebugThread);
15127     return GetDAC()->IsThreadSuspendedOrHijacked(pCordbThread->m_vmThreadToken);
15128 }