Update license headers
[platform/upstream/coreclr.git] / src / debug / di / rsstackwalk.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 // RsStackWalk.cpp
6 // 
7
8 //
9 // This file contains the implementation of the V3 managed stackwalking API.
10 // 
11 // ======================================================================================
12
13 #include "stdafx.h"
14 #include "primitives.h"
15
16
17 //---------------------------------------------------------------------------------------
18 //
19 // Constructor for CordbStackWalk.
20 //
21 // Arguments:
22 //    pCordbThread - the thread on which this stackwalker is created
23 //
24
25 CordbStackWalk::CordbStackWalk(CordbThread * pCordbThread)
26   : CordbBase(pCordbThread->GetProcess(), 0, enumCordbStackWalk),
27     m_pCordbThread(pCordbThread),
28     m_pSFIHandle(NULL),    
29     m_cachedSetContextFlag(SET_CONTEXT_FLAG_ACTIVE_FRAME),
30     m_cachedHR(S_OK),
31     m_fIsOneFrameAhead(false)
32 {
33     m_pCachedFrame.Clear();
34 }
35
36 void CordbStackWalk::Init()
37 {
38     CordbProcess * pProcess = GetProcess();
39     m_lastSyncFlushCounter = pProcess->m_flushCounter;
40
41     IDacDbiInterface * pDAC = pProcess->GetDAC();
42     pDAC->CreateStackWalk(m_pCordbThread->m_vmThreadToken, 
43                           &m_context, 
44                           &m_pSFIHandle);
45
46     // see the function header of code:CordbStackWalk::CheckForLegacyHijackCase
47     CheckForLegacyHijackCase();
48
49     // Add itself to the neuter list. 
50     m_pCordbThread->GetRefreshStackNeuterList()->Add(GetProcess(), this);
51 }
52
53 // ----------------------------------------------------------------------------
54 // CordbStackWalk::CheckForLegacyHijackCase
55 //
56 // Description: 
57 // @dbgtodo  legacy interop debugging - In the case of an unhandled hardware exception, the
58 // thread will be hijacked to code:Debugger::GenericHijackFunc, which the stackwalker doesn't know how to
59 // unwind. We can teach the stackwalker to recognize that hijack stub, but since it's going to be deprecated
60 // anyway, it's not worth the effort. So we check for the hijack CONTEXT here and use it as the CONTEXT. This
61 // check should be removed when we are completely
62 // out-of-process.
63 //
64
65 void CordbStackWalk::CheckForLegacyHijackCase()
66 {
67 #if defined(FEATURE_INTEROP_DEBUGGING)
68     CordbProcess * pProcess = GetProcess();
69
70     // Only do this if we have a shim and we are interop-debugging.
71     if ((pProcess->GetShim() != NULL) &&
72         pProcess->IsInteropDebugging())
73     {
74         // And only if we have a CordbUnmanagedThread and we are hijacked to code:Debugger::GenericHijackFunc
75         CordbUnmanagedThread * pUT = pProcess->GetUnmanagedThread(m_pCordbThread->GetVolatileOSThreadID());
76         if (pUT != NULL)
77         {
78             if (pUT->IsFirstChanceHijacked() || pUT->IsGenericHijacked())
79             {
80                 // The GetThreadContext function hides the effects of hijacking and returns the unhijacked context
81                 m_context.ContextFlags = DT_CONTEXT_FULL;
82                 pUT->GetThreadContext(&m_context);
83                 IDacDbiInterface * pDAC = GetProcess()->GetDAC();
84                 pDAC->SetStackWalkCurrentContext(m_pCordbThread->m_vmThreadToken,
85                                                  m_pSFIHandle, 
86                                                  SET_CONTEXT_FLAG_ACTIVE_FRAME, 
87                                                  &m_context);
88             }
89         }
90     }
91 #endif // FEATURE_INTEROP_DEBUGGING
92 }
93
94 //---------------------------------------------------------------------------------------
95 //
96 // Destructor for CordbStackWalk.
97 //
98 // Notes:
99 //    We don't really need to do anything here since the CordbStackWalk should have been neutered already.
100 //
101
102 CordbStackWalk::~CordbStackWalk()
103 {
104     _ASSERTE(IsNeutered());
105 }
106
107 //---------------------------------------------------------------------------------------
108 //
109 // This function resets all the state on a CordbStackWalk and releases all the memory.
110 // It is used for neutering and refreshing.
111 //
112
113 void CordbStackWalk::DeleteAll()
114 {
115     _ASSERTE(GetProcess()->GetProcessLock()->HasLock());
116
117     // delete allocated memory
118     if (m_pSFIHandle)
119     {
120         HRESULT hr = S_OK;
121         EX_TRY
122         {
123 #if defined(FEATURE_DBGIPC_TRANSPORT_DI)
124             // For Mac debugging, it's not safe to call into the DAC once
125             // code:INativeEventPipeline::TerminateProcess is called.  This is because the transport will not
126             // work anymore.  The sole purpose of calling DeleteStackWalk() is to release the resources and
127             // memory allocated for the stackwalk.  In the remote debugging case, the memory is allocated in
128             // the debuggee process.  If the process is already terminated, then it's ok to skip the call.
129             if (!GetProcess()->m_exiting)
130 #endif // FEATURE_DBGIPC_TRANSPORT_DI
131             {
132                 // This Delete call shouldn't actually throw. Worst case, the DDImpl leaked memory. 
133                 GetProcess()->GetDAC()->DeleteStackWalk(m_pSFIHandle);
134             }
135         }
136         EX_CATCH_HRESULT(hr);
137         SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr);
138         m_pSFIHandle = NULL;
139     }
140
141     // clear out the cached frame
142     m_pCachedFrame.Clear();
143     m_cachedHR = S_OK;
144     m_fIsOneFrameAhead = false;
145 }
146
147 //---------------------------------------------------------------------------------------
148 //
149 // Release all memory used by the stackwalker.
150 //
151 //
152 // Notes:
153 //    CordbStackWalk is neutered by CordbThread or CleanupStack().
154 //
155
156 void CordbStackWalk::Neuter()
157 {
158     if (IsNeutered())
159     {
160         return;
161     }
162
163     DeleteAll();
164     CordbBase::Neuter();
165 }
166
167 // standard QI function
168 HRESULT CordbStackWalk::QueryInterface(REFIID id, void **pInterface)
169 {
170     if (id == IID_ICorDebugStackWalk)
171     {
172         *pInterface = static_cast<ICorDebugStackWalk*>(this);
173     }
174     else if (id == IID_IUnknown)
175     {
176         *pInterface = static_cast<IUnknown*>(static_cast<ICorDebugStackWalk*>(this));
177     }
178     else
179     {
180         *pInterface = NULL;
181         return E_NOINTERFACE;
182     }
183
184     ExternalAddRef();
185     return S_OK;
186 }
187
188 //---------------------------------------------------------------------------------------
189 //
190 // Refreshes all the state stored on the CordbStackWalk.  This is necessary because sending IPC events to
191 // the LS flushes the DAC cache, and m_pSFIHandle is allocated entirely in DAC memory.  So, we keep track
192 // of whether we have sent an IPC event and refresh the CordbStackWalk if necessary.
193 //
194 // Notes:
195 //    Throws on error.
196 //
197
198 void CordbStackWalk::RefreshIfNeeded()
199 {
200     CordbProcess * pProcess = GetProcess();
201     _ASSERTE(pProcess->GetProcessLock()->HasLock());
202
203     // check if we need to refresh
204     if (m_lastSyncFlushCounter != pProcess->m_flushCounter)
205     {
206         // Make a local copy of the CONTEXT here.  DeleteAll() will delete the CONTEXT on the cached frame,
207         // and CreateStackWalk() actually uses the CONTEXT buffer we pass to it.
208         DT_CONTEXT ctx;
209         if (m_fIsOneFrameAhead)
210         {
211             ctx = *(m_pCachedFrame->GetContext());
212         }
213         else
214         {
215             ctx = m_context;
216         }
217
218         // clear all the state
219         DeleteAll();
220
221         // create a new stackwalk handle
222         pProcess->GetDAC()->CreateStackWalk(m_pCordbThread->m_vmThreadToken, 
223                                             &m_context, 
224                                             &m_pSFIHandle);
225
226         // advance the stackwalker to where we originally were
227         SetContextWorker(m_cachedSetContextFlag, sizeof(DT_CONTEXT), reinterpret_cast<BYTE *>(&ctx));
228
229         // update the sync counter
230         m_lastSyncFlushCounter = pProcess->m_flushCounter;
231     }
232 } // CordbStackWalk::RefreshIfNeeded()
233
234 //---------------------------------------------------------------------------------------
235 //
236 // Retrieves the CONTEXT of the current frame.
237 //
238 // Arguments:
239 //    contextFlags   - context flags used to determine the required size for the buffer 
240 //    contextBufSize - size of the CONTEXT buffer
241 //    pContextSize   - out parameter; returns the size required for the CONTEXT buffer
242 //    pbContextBuf   - the CONTEXT buffer
243 //
244 // Return Value:
245 //    Return S_OK on success.
246 //    Return CORDBG_E_PAST_END_OF_STACK if we are already at the end of the stack.
247 //    Return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) if the buffer is too small.
248 //    Return E_FAIL on other failures.
249 //
250
251 HRESULT CordbStackWalk::GetContext(ULONG32   contextFlags,
252                                    ULONG32   contextBufSize,
253                                    ULONG32 * pContextSize,
254                                    BYTE      pbContextBuf[])
255 {
256     HRESULT hr = S_OK;
257     PUBLIC_REENTRANT_API_BEGIN(this)            
258     {        
259         RefreshIfNeeded();
260
261         // set the required size for the CONTEXT buffer
262         if (pContextSize != NULL)
263         {
264             *pContextSize = ContextSizeForFlags(contextFlags);
265         }
266
267         // If all the user wants to know is the CONTEXT size, then we are done.
268         if ((contextBufSize != 0) && (pbContextBuf != NULL))
269         {
270             if (contextBufSize < 4)
271             {
272                 ThrowWin32(ERROR_INSUFFICIENT_BUFFER);
273             }
274             
275             DT_CONTEXT * pContext = reinterpret_cast<DT_CONTEXT *>(pbContextBuf);
276
277             // Some helper functions that examine the context expect the flags to be initialized.
278             pContext->ContextFlags = contextFlags;
279
280             // check the size of the incoming buffer
281             if (!CheckContextSizeForBuffer(contextBufSize, pbContextBuf))
282             {
283                 ThrowWin32(ERROR_INSUFFICIENT_BUFFER);
284             }
285
286             // Check if we are one frame ahead.  If so, returned the CONTEXT on the cached frame.
287             if (m_fIsOneFrameAhead)
288             {
289                 if (m_pCachedFrame != NULL)
290                 {
291                     const DT_CONTEXT * pSrcContext = m_pCachedFrame->GetContext();
292                     _ASSERTE(pSrcContext);
293                     CORDbgCopyThreadContext(pContext, pSrcContext);
294                 }
295                 else
296                 {
297                     // We encountered a problem when we were trying to initialize the CordbNativeFrame.
298                     // However, the problem occurred after we have unwound the current frame.
299                     // What do we do here?  We don't have the CONTEXT anymore.
300                     _ASSERTE(FAILED(m_cachedHR));
301                     ThrowHR(m_cachedHR);
302                 }
303             }
304             else
305             {
306                 // No easy way out in this case.  We have to call the DDI.
307                 IDacDbiInterface * pDAC = GetProcess()->GetDAC();
308
309                 IDacDbiInterface::FrameType ft = pDAC->GetStackWalkCurrentFrameInfo(m_pSFIHandle, NULL);
310                 if (ft == IDacDbiInterface::kInvalid)
311                 {
312                     ThrowHR(E_FAIL);
313                 }
314                 else if (ft == IDacDbiInterface::kAtEndOfStack)
315                 {
316                     ThrowHR(CORDBG_E_PAST_END_OF_STACK);
317                 }
318                 else if (ft == IDacDbiInterface::kExplicitFrame)
319                 {
320                     ThrowHR(CORDBG_E_NO_CONTEXT_FOR_INTERNAL_FRAME);
321                 }
322                 else
323                 {
324                     // We always store the current CONTEXT, so just copy it into the buffer.
325                     CORDbgCopyThreadContext(pContext, &m_context);
326                 }
327             }
328         }
329     }
330     PUBLIC_REENTRANT_API_END(hr);
331     return hr;
332 }
333
334 //---------------------------------------------------------------------------------------
335 //
336 // Set the stackwalker to the specified CONTEXT.
337 //
338 // Arguments:
339 //    flag        - context flags used to determine the size of the CONTEXT
340 //    contextSize - the size of the CONTEXT
341 //    context     - the CONTEXT as a byte array
342 //
343 // Return Value:
344 //    Return S_OK on success.
345 //    Return E_INVALIDARG if context is NULL
346 //    Return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) if the CONTEXT is too small.
347 //    Return E_FAIL on other failures.
348 //
349
350 HRESULT CordbStackWalk::SetContext(CorDebugSetContextFlag flag, ULONG32 contextSize, BYTE context[])
351 {
352     HRESULT hr = S_OK;
353     PUBLIC_REENTRANT_API_BEGIN(this)
354     {
355         RefreshIfNeeded();
356         SetContextWorker(flag, contextSize, context);
357     }
358     PUBLIC_REENTRANT_API_END(hr);
359     return hr;
360 }
361
362 //---------------------------------------------------------------------------------------
363 //
364 // Refer to the comment for code:CordbStackWalk::SetContext
365 //
366
367 void CordbStackWalk::SetContextWorker(CorDebugSetContextFlag flag, ULONG32 contextSize, BYTE context[])
368 {
369     if (context == NULL)
370     {
371         ThrowHR(E_INVALIDARG);
372     }
373
374     if (!CheckContextSizeForBuffer(contextSize, context))
375     {
376         ThrowWin32(ERROR_INSUFFICIENT_BUFFER);
377     }
378
379     // invalidate the cache
380     m_pCachedFrame.Clear();
381     m_cachedHR = S_OK;
382     m_fIsOneFrameAhead = false;
383
384     DT_CONTEXT * pSrcContext = reinterpret_cast<DT_CONTEXT *>(context);
385
386     // Check the incoming CONTEXT using a temporary CONTEXT buffer before updating our real CONTEXT buffer.
387     // The incoming CONTEXT is not required to have all the bits set in its CONTEXT flags, so only update
388     // the registers specified by the CONTEXT flags.  Note that CORDbgCopyThreadContext() honours the CONTEXT 
389     // flags on both the source and the destination CONTEXTs when it copies them.
390     DT_CONTEXT tmpCtx = m_context;
391     tmpCtx.ContextFlags |= pSrcContext->ContextFlags;
392     CORDbgCopyThreadContext(&tmpCtx, pSrcContext);
393
394     IDacDbiInterface * pDAC = GetProcess()->GetDAC();
395     IfFailThrow(pDAC->CheckContext(m_pCordbThread->m_vmThreadToken, &tmpCtx));
396                        
397     // At this point we have done all of our checks to verify that the incoming CONTEXT is sane, so we can
398     // update our internal CONTEXT buffer.
399     m_context = tmpCtx;
400     m_cachedSetContextFlag = flag;
401
402     pDAC->SetStackWalkCurrentContext(m_pCordbThread->m_vmThreadToken,
403                                      m_pSFIHandle,                                      
404                                      flag, 
405                                      &m_context);
406 }
407
408 //---------------------------------------------------------------------------------------
409 //
410 // Helper to perform all the necessary operations when we unwind, including:
411 //     1) Unwind
412 //     2) Save the new unwound CONTEXT
413 //
414 // Return Value:
415 //    Return TRUE if we successfully unwind to the next frame.
416 //    Return FALSE if there is no more frame to walk.
417 //    Throw on error.
418 //
419
420 BOOL CordbStackWalk::UnwindStackFrame()
421 {
422     CordbProcess * pProcess = GetProcess();
423     _ASSERTE(pProcess->GetProcessLock()->HasLock());
424
425     IDacDbiInterface * pDAC = pProcess->GetDAC();
426     BOOL retVal = pDAC->UnwindStackWalkFrame(m_pSFIHandle);
427
428     // Now that we have unwound, make sure we update the CONTEXT buffer to reflect the current stack frame.
429     // This call is safe regardless of whether the unwind is successful or not.
430     pDAC->GetStackWalkCurrentContext(m_pSFIHandle, &m_context);
431
432     return retVal;
433 } // CordbStackWalk::UnwindStackWalkFrame
434
435 //---------------------------------------------------------------------------------------
436 //
437 // Unwind the stackwalker to the next frame.
438 //
439 // Return Value:
440 //    Return S_OK on success.
441 //    Return CORDBG_E_FAIL_TO_UNWIND_FRAME if the unwind fails.
442 //    Return CORDBG_S_AT_END_OF_STACK if we have reached the end of the stack as a result of this unwind.
443 //    Return CORDBG_E_PAST_END_OF_STACK if we are already at the end of the stack to begin with.
444 //
445
446 HRESULT CordbStackWalk::Next()
447 {
448     HRESULT hr = S_OK;
449     PUBLIC_REENTRANT_API_BEGIN(this)
450     {
451         RefreshIfNeeded();
452         if (m_fIsOneFrameAhead)
453         {
454             // We have already unwound to the next frame when we materialize the CordbNativeFrame 
455             // for the current frame.  So we just need to clear the cache because we are already at
456             // the next frame.
457             if (m_pCachedFrame != NULL)
458             {
459                 m_pCachedFrame.Clear();
460             }
461             m_cachedHR = S_OK;
462             m_fIsOneFrameAhead = false;
463         }
464         else
465         {
466             IDacDbiInterface * pDAC = GetProcess()->GetDAC();
467             IDacDbiInterface::FrameType ft = IDacDbiInterface::kInvalid;
468
469             ft = pDAC->GetStackWalkCurrentFrameInfo(this->m_pSFIHandle, NULL);
470             if (ft == IDacDbiInterface::kAtEndOfStack)
471             {
472                 ThrowHR(CORDBG_E_PAST_END_OF_STACK);
473             }
474
475             // update the cahced flag to indicate that we have reached an unwind CONTEXT
476             m_cachedSetContextFlag = SET_CONTEXT_FLAG_UNWIND_FRAME;
477
478             if (UnwindStackFrame())
479             {
480                 hr = S_OK;
481             }
482             else
483             {
484                 hr = CORDBG_S_AT_END_OF_STACK;
485             }
486         }
487     }
488     PUBLIC_REENTRANT_API_END(hr);
489     return hr;
490 }
491
492 //---------------------------------------------------------------------------------------
493 //
494 // Retrieves an ICDFrame corresponding to the current frame:
495 // Stopped At           Out Parameter       Return Value
496 // ----------           -------------       ------------
497 // explicit frame       CordbInternalFrame  S_OK
498 // managed stack frame  CordbNativeFrame    S_OK
499 // native stack frame   NULL                S_FALSE
500 //
501 // Arguments:
502 //    ppFrame - out parameter; return the ICDFrame
503 //
504 // Return Value:
505 //    On success return the HRs above.
506 //    Return CORDBG_E_PAST_END_OF_STACK if we are already at the end of the stack.
507 //    Return E_INVALIDARG if ppFrame is NULL
508 //    Return E_FAIL on other errors.
509 //
510 // Notes:
511 //    This is just a wrapper with an EX_TRY/EX_CATCH_HRESULT for GetFrameWorker().
512 //
513
514 HRESULT CordbStackWalk::GetFrame(ICorDebugFrame ** ppFrame)
515 {
516     HRESULT hr = S_OK;
517     PUBLIC_REENTRANT_API_NO_LOCK_BEGIN(this)
518     {
519         ATT_REQUIRE_STOPPED_MAY_FAIL_OR_THROW(GetProcess(), ThrowHR);
520         RSLockHolder lockHolder(GetProcess()->GetProcessLock());
521
522         RefreshIfNeeded();
523         hr = GetFrameWorker(ppFrame);
524     }
525     PUBLIC_REENTRANT_API_END(hr);
526
527     if (FAILED(hr))
528     {
529         if (m_fIsOneFrameAhead && (m_pCachedFrame == NULL))
530         {
531             // We encountered a problem when we try to materialize a CordbNativeFrame.
532             // Cache the failure HR so that we can return it later if the caller
533             // calls GetFrame() again or GetContext().
534             m_cachedHR = hr;
535         }
536     }
537
538     return hr;
539 }
540
541 //---------------------------------------------------------------------------------------
542 //
543 // Refer to the comment for code:CordbStackWalk::GetFrame
544 //
545
546 HRESULT CordbStackWalk::GetFrameWorker(ICorDebugFrame ** ppFrame)
547 {
548     _ASSERTE(GetProcess()->GetProcessLock()->HasLock());
549
550     if (ppFrame == NULL)
551     {
552         ThrowHR(E_INVALIDARG);
553     }
554     *ppFrame = NULL;
555
556     RSInitHolder<CordbFrame> pResultFrame(NULL);
557
558     if (m_fIsOneFrameAhead)
559     {
560         if (m_pCachedFrame != NULL)
561         {
562             pResultFrame.Assign(m_pCachedFrame);
563             pResultFrame.TransferOwnershipExternal(ppFrame);
564             return S_OK;
565         }
566         else
567         {
568             // We encountered a problem when we were trying to initialize the CordbNativeFrame.
569             // However, the problem occurred after we have unwound the current frame.
570             // Whatever error code we return, it should be the same one GetContext() returns.
571             _ASSERTE(FAILED(m_cachedHR));
572             ThrowHR(m_cachedHR);
573         }
574     }
575
576     IDacDbiInterface * pDAC = NULL;
577     DebuggerIPCE_STRData frameData;
578     ZeroMemory(&frameData, sizeof(frameData));
579     IDacDbiInterface::FrameType ft = IDacDbiInterface::kInvalid;
580
581     pDAC = GetProcess()->GetDAC();
582     ft = pDAC->GetStackWalkCurrentFrameInfo(m_pSFIHandle, &frameData);
583
584     if (ft == IDacDbiInterface::kInvalid) 
585     {
586         STRESS_LOG1(LF_CORDB, LL_INFO1000, "CSW::GFW - invalid stackwalker (%p)", this);
587         ThrowHR(E_FAIL);
588     }
589     else if (ft == IDacDbiInterface::kAtEndOfStack)
590     {
591         STRESS_LOG1(LF_CORDB, LL_INFO1000, "CSW::GFW - past end of stack (%p)", this);
592         ThrowHR(CORDBG_E_PAST_END_OF_STACK);
593     }
594     else if (ft == IDacDbiInterface::kNativeStackFrame)
595     {
596         STRESS_LOG1(LF_CORDB, LL_INFO1000, "CSW::GFW - native stack frame (%p)", this);
597         return S_FALSE;
598     }
599     else if (ft == IDacDbiInterface::kExplicitFrame)
600     {
601         STRESS_LOG1(LF_CORDB, LL_INFO1000, "CSW::GFW - explicit frame (%p)", this);
602
603         // We no longer expect to get internal frames by unwinding.
604         GetProcess()->TargetConsistencyCheck(false);
605     }
606     else if (ft == IDacDbiInterface::kManagedStackFrame)
607     {
608         _ASSERTE(frameData.eType == DebuggerIPCE_STRData::cMethodFrame);
609
610         HRESULT hr = S_OK;
611
612         // In order to find the FramePointer on x86, we need to unwind to the next frame.
613         // Technically, only x86 needs to do this, because the x86 runtime stackwalker doesn't uwnind
614         // one frame ahead of time.  However, we are doing this on all platforms to keep things simple.
615         BOOL fSuccess = UnwindStackFrame();
616         (void)fSuccess; //prevent "unused variable" error from GCC
617         _ASSERTE(fSuccess);
618
619         m_fIsOneFrameAhead = true;
620 #if defined(DBG_TARGET_X86)
621         frameData.fp = pDAC->GetFramePointer(m_pSFIHandle);
622 #endif // DBG_TARGET_X86
623
624         // currentFuncData contains general information about the method.  
625         // It has no information about any particular jitted instance of the method.
626         DebuggerIPCE_FuncData * pFuncData = &(frameData.v.funcData);
627
628         // currentJITFuncData contains information about the current jitted instance of the method 
629         // on the stack.
630         DebuggerIPCE_JITFuncData * pJITFuncData = &(frameData.v.jitFuncData);
631
632         // Lookup the appdomain that the thread was in when it was executing code for this frame. We pass this
633         // to the frame when we create it so we can properly resolve locals in that frame later.
634         CordbAppDomain * pCurrentAppDomain = GetProcess()->LookupOrCreateAppDomain(frameData.vmCurrentAppDomainToken);
635         _ASSERTE(pCurrentAppDomain != NULL);
636
637         // Lookup the module
638         CordbModule* pModule = pCurrentAppDomain->LookupOrCreateModule(pFuncData->vmDomainFile);
639         PREFIX_ASSUME(pModule != NULL);
640
641         // Create or look up a CordbNativeCode.  There is one for each jitted instance of a method, 
642         // and we may have multiple instances because of generics.
643         CordbNativeCode * pNativeCode = pModule->LookupOrCreateNativeCode(pFuncData->funcMetadataToken,
644                                                                           pJITFuncData->vmNativeCodeMethodDescToken,
645                                                                           pJITFuncData->nativeStartAddressPtr);
646         IfFailThrow(hr);
647
648         // The native code object will create the function object if needed
649         CordbFunction * pFunction = pNativeCode->GetFunction();
650
651         // A CordbFunction is theoretically the uninstantiated method, yet for back-compat we allow
652         // debuggers to assume that it corresponds to exactly 1 native code blob. In order for
653         // an open generic function to know what native code to give back, we attach an arbitrary
654         // native code that we located through code inspection.
655         // Note that not all CordbFunction objects get created via stack traces because you can also
656         // create them by name. In that case you still won't get code for Open generic functions
657         // because we will never have attached one and the lookup by token is insufficient. This
658         // behavior mimics our 2.0 debugging behavior though so its not a regression.
659         pFunction->NotifyCodeCreated(pNativeCode);
660
661         IfFailThrow(hr);
662
663         _ASSERTE((pFunction != NULL) && (pNativeCode != NULL));
664
665         // initialize the auxiliary info required for funclets
666         CordbMiscFrame miscFrame(pJITFuncData);
667
668         // Create the native frame.
669         CordbNativeFrame* pNativeFrame = new CordbNativeFrame(m_pCordbThread,
670                                                               frameData.fp,
671                                                               pNativeCode,
672                                                               pJITFuncData->nativeOffset,
673                                                               &(frameData.rd),
674                                                               frameData.v.taAmbientESP,
675                                                               !!frameData.quicklyUnwound,
676                                                               pCurrentAppDomain,
677                                                               &miscFrame,
678                                                               &(frameData.ctx));
679
680         pResultFrame.Assign(static_cast<CordbFrame *>(pNativeFrame));
681         m_pCachedFrame.Assign(static_cast<CordbFrame *>(pNativeFrame));
682
683         // @dbgtodo  dynamic language debugging
684         // If we are dealing with a dynamic method (e.g. an IL stub, a LCG method, etc.), 
685         // then we don't have the metadata or the debug info (sequence points, etc.).  
686         // This means that we can't do anything meaningful with a CordbJITILFrame anyway,
687         // so let's not create the CordbJITILFrame at all.  Note that methods created with
688         // RefEmit are okay, i.e. they have metadata.
689         
690         //     The check for IsNativeImpl() != CordbFunction::kNativeOnly catches an odd profiler
691         // case. A profiler can rewrite assemblies at load time so that a P/invoke becomes a
692         // regular managed method. mscordbi isn't yet designed to handle runtime metadata
693         // changes, so it still thinks the method is a p/invoke. If we only relied on
694         // frameData.v.fNoMetadata which is populated by the DAC, that will report
695         // FALSE (the method does have metadata/IL now). However pNativeCode->LoadNativeInfo
696         // is going to check DBI's metadata and calculate this is a p/invoke, which will
697         // throw an exception that the method isn't IL.
698         //     Ideally we probably want to expose the profiler's change to the method,
699         // however that will take significant work. Part of that is correctly detecting and
700         // updating metadata in DBI, part is determinging if/how the debugger is notified,
701         // and part is auditing mscordbi to ensure that anything we cached based on the
702         // old metadata is correctly invalidated.
703         //     Since this is a late fix going into a controlled servicing release I have
704         // opted for a much narrower fix. Doing the check for IsNativeImpl() != CordbFunction::kNativeOnly
705         // will continue to treat our new method as though it was a p/invoke, and the
706         // debugger will not provide IL for it. The debugger can't inspect within the profiler
707         // modified method, but at least the error won't leak out to interfere with inspection
708         // of the callstack as a whole.
709         if (!frameData.v.fNoMetadata && 
710             pNativeCode->GetFunction()->IsNativeImpl() != CordbFunction::kNativeOnly)
711         {
712             pNativeCode->LoadNativeInfo();
713
714             // By design, when a managed exception occurs we return the sequence point containing the faulting 
715             // instruction in the leaf frame. In the past we didn't always achieve this, 
716             // but we are being more deliberate about this behavior now. 
717
718             // If jsutAfterILThrow is true, it means nativeOffset points to the return address of IL_Throw
719             // (or another JIT exception helper) after an exception has been thrown. 
720             // In such cases we want to adjust nativeOffset, so it will point an actual exception callsite. 
721             // By subtracting STACKWALK_CONTROLPC_ADJUST_OFFSET from nativeOffset you can get 
722             // an address somewhere inside CALL instruction. 
723             // This ensures more consistent placement of exception line highlighting in Visual Studio
724             DWORD nativeOffsetToMap = pJITFuncData->jsutAfterILThrow ?
725                                (DWORD)pJITFuncData->nativeOffset - STACKWALK_CONTROLPC_ADJUST_OFFSET :
726                                (DWORD)pJITFuncData->nativeOffset;
727             CorDebugMappingResult mappingType;
728             ULONG uILOffset = pNativeCode->GetSequencePoints()->MapNativeOffsetToIL(
729                     nativeOffsetToMap,
730                     &mappingType);
731
732             // Find or create the IL Code, and the pJITILFrame.
733             RSExtSmartPtr<CordbILCode> pCode;
734                 
735             // The code for populating CordbFunction ILCode looks really bizzare... it appears to only grab the
736             // correct version of the IL if that is still the current EnC version yet it is populated deliberately
737             // late bound at which point the latest version may be different. In fact even here the latest version
738             // could already be different, but this is no worse than what the code used to do
739             hr = pFunction->GetILCode(&pCode);
740             IfFailThrow(hr);
741             _ASSERTE(pCode != NULL);
742
743             // We populate the code for ReJit eagerly to make sure we still have it if the profiler removes the
744             // instrumentation later. Of course the only way it will still be accesible to our caller is if he
745             // saves a pointer to the ILCode. 
746             // I'm not sure if ignoring rejit for mini-dumps is the right call long term, but we aren't doing
747             // anything special to collect the memory at dump time so we better be prepared to not fetch it here.
748             // We'll attempt to treat it as not being instrumented, though I suspect the abstraction is leaky.
749             RSSmartPtr<CordbReJitILCode> pReJitCode;
750             EX_TRY_ALLOW_DATATARGET_MISSING_MEMORY
751             {
752                 VMPTR_ReJitInfo reJitInfo = VMPTR_ReJitInfo::NullPtr();
753                 IfFailThrow(GetProcess()->GetDAC()->GetReJitInfo(pJITFuncData->vmNativeCodeMethodDescToken, pJITFuncData->nativeStartAddressPtr, &reJitInfo));
754                 if (!reJitInfo.IsNull())
755                 {
756                     VMPTR_SharedReJitInfo sharedReJitInfo = VMPTR_SharedReJitInfo::NullPtr();
757                     IfFailThrow(GetProcess()->GetDAC()->GetSharedReJitInfo(reJitInfo, &sharedReJitInfo));
758                     IfFailThrow(pFunction->LookupOrCreateReJitILCode(sharedReJitInfo, &pReJitCode));
759                 }
760             }
761             EX_END_CATCH_ALLOW_DATATARGET_MISSING_MEMORY                                
762
763
764
765             RSInitHolder<CordbJITILFrame> pJITILFrame(new CordbJITILFrame(pNativeFrame, 
766                                                                 pCode,
767                                                                 uILOffset,
768                                                                 mappingType,
769                                                                 frameData.v.exactGenericArgsToken,
770                                                                 frameData.v.dwExactGenericArgsTokenIndex,
771                                                                 !!frameData.v.fVarArgs,
772                                                                 pReJitCode));
773
774             // Initialize the frame.  This is a nop if the method is not a vararg method.
775             hr = pJITILFrame->Init();
776             IfFailThrow(hr);            
777             
778             pNativeFrame->m_JITILFrame.Assign(pJITILFrame);
779             pJITILFrame.ClearAndMarkDontNeuter();
780         }
781
782         STRESS_LOG3(LF_CORDB, LL_INFO1000, "CSW::GFW - managed stack frame (%p): CNF - 0x%p, CJILF - 0x%p", 
783                     this, pNativeFrame, pNativeFrame->m_JITILFrame.GetValue());
784     } // kManagedStackFrame
785     else if (ft == IDacDbiInterface::kNativeRuntimeUnwindableStackFrame)
786     {
787         _ASSERTE(frameData.eType == DebuggerIPCE_STRData::cRuntimeNativeFrame);
788
789         // In order to find the FramePointer on x86, we need to unwind to the next frame.
790         // Technically, only x86 needs to do this, because the x86 runtime stackwalker doesn't uwnind
791         // one frame ahead of time.  However, we are doing this on all platforms to keep things simple.
792         BOOL fSuccess = UnwindStackFrame();
793         (void)fSuccess; //prevent "unused variable" error from GCC
794         _ASSERTE(fSuccess);
795
796         m_fIsOneFrameAhead = true;
797 #if defined(DBG_TARGET_X86)
798         frameData.fp = pDAC->GetFramePointer(m_pSFIHandle);
799 #endif // DBG_TARGET_X86
800
801         // Lookup the appdomain that the thread was in when it was executing code for this frame. We pass this
802         // to the frame when we create it so we can properly resolve locals in that frame later.
803         CordbAppDomain * pCurrentAppDomain = 
804             GetProcess()->LookupOrCreateAppDomain(frameData.vmCurrentAppDomainToken);
805         _ASSERTE(pCurrentAppDomain != NULL);
806
807         CordbRuntimeUnwindableFrame * pRuntimeFrame = new CordbRuntimeUnwindableFrame(m_pCordbThread,
808                                                                                       frameData.fp, 
809                                                                                       pCurrentAppDomain,
810                                                                                       &(frameData.ctx));
811
812         pResultFrame.Assign(static_cast<CordbFrame *>(pRuntimeFrame));
813         m_pCachedFrame.Assign(static_cast<CordbFrame *>(pRuntimeFrame));
814
815         STRESS_LOG2(LF_CORDB, LL_INFO1000, "CSW::GFW - runtime unwindable stack frame (%p): 0x%p", 
816                     this, pRuntimeFrame);
817     }
818
819     pResultFrame.TransferOwnershipExternal(ppFrame);
820
821     return S_OK;
822 }