Skip to content

Commit c93c89d

Browse files
committed
Profiler fixes dotnet#2
1 parent a6f73a1 commit c93c89d

9 files changed

+67
-10
lines changed

src/coreclr/inc/dacvars.h

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ DEFINE_DACVAR(DWORD, dac__g_TlsIndex, g_TlsIndex)
116116
#ifdef FEATURE_EH_FUNCLETS
117117
DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pEHClass, ::g_pEHClass)
118118
DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pExceptionServicesInternalCallsClass, ::g_pExceptionServicesInternalCallsClass)
119+
DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pStackFrameIteratorClass, ::g_pStackFrameIteratorClass)
119120
DEFINE_DACVAR(BOOL, dac__g_isNewExceptionHandlingEnabled, ::g_isNewExceptionHandlingEnabled)
120121
#endif
121122

src/coreclr/vm/appdomain.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1402,6 +1402,7 @@ void SystemDomain::LoadBaseSystemClasses()
14021402
#ifdef FEATURE_EH_FUNCLETS
14031403
g_pEHClass = CoreLibBinder::GetClass(CLASS__EH);
14041404
g_pExceptionServicesInternalCallsClass = CoreLibBinder::GetClass(CLASS__EXCEPTIONSERVICES_INTERNALCALLS);
1405+
g_pStackFrameIteratorClass = CoreLibBinder::GetClass(CLASS__STACKFRAMEITERATOR);
14051406
#endif
14061407

14071408
// Make sure that FCall mapping for Monitor.Enter is initialized. We need it in case Monitor.Enter is used only as JIT helper.

src/coreclr/vm/corelib.h

+1
Original file line numberDiff line numberDiff line change
@@ -1188,6 +1188,7 @@ DEFINE_METHOD(EH, RH_THROW_EX, RhThrowEx, SM_Obj_RefExInfo_RetVoid)
11881188
DEFINE_METHOD(EH, RH_THROWHW_EX, RhThrowHwEx, SM_UInt_RefExInfo_RetVoid)
11891189
DEFINE_METHOD(EH, RH_RETHROW, RhRethrow, SM_RefExInfo_RefExInfo_RetVoid)
11901190
DEFINE_CLASS(EXCEPTIONSERVICES_INTERNALCALLS, ExceptionServices, InternalCalls)
1191+
DEFINE_CLASS(STACKFRAMEITERATOR, Runtime, StackFrameIterator)
11911192
#endif // FEATURE_EH_FUNCLETS
11921193

11931194
#ifndef FOR_ILLINK

src/coreclr/vm/exceptionhandling.cpp

+34-10
Original file line numberDiff line numberDiff line change
@@ -8200,7 +8200,11 @@ extern "C" bool QCALLTYPE SfiInit(StackFrameIterator* pThis, CONTEXT* pStackwalk
82008200
else
82018201
{
82028202
EEToProfilerExceptionInterfaceWrapper::ExceptionSearchCatcherFound(pMD);
8203-
EEToProfilerExceptionInterfaceWrapper::ExceptionSearchFunctionLeave(pMD);
8203+
if (pExInfo->m_pMDToReport != NULL)
8204+
{
8205+
EEToProfilerExceptionInterfaceWrapper::ExceptionSearchFunctionLeave(pExInfo->m_pMDToReport);
8206+
pExInfo->m_pMDToReport = NULL;
8207+
}
82048208

82058209
// We don't need to do anything special for continuable exceptions after calling
82068210
// this callback. We are going to start unwinding anyway.
@@ -8233,7 +8237,7 @@ extern "C" bool QCALLTYPE SfiInit(StackFrameIterator* pThis, CONTEXT* pStackwalk
82338237
!(pExInfo->m_exception == CLRException::GetPreallocatedStackOverflowException());
82348238

82358239
pExInfo->m_stackTraceInfo.AppendElement(canAllocateMemory, NULL, GetRegdisplaySP(pExInfo->m_frameIter.m_crawl.GetRegisterSet()), pMD, &pExInfo->m_frameIter.m_crawl);
8236-
}
8240+
}
82378241
}
82388242
}
82398243
StackWalkAction retVal = pThis->Next();
@@ -8244,6 +8248,7 @@ extern "C" bool QCALLTYPE SfiInit(StackFrameIterator* pThis, CONTEXT* pStackwalk
82448248
if (pExInfo->m_passNumber == 1)
82458249
{
82468250
EEToProfilerExceptionInterfaceWrapper::ExceptionSearchFunctionEnter(pMD);
8251+
pExInfo->m_pMDToReport = pMD;
82478252

82488253
// Notify the debugger that we are on the first pass for a managed exception.
82498254
// Note that this callback is made for every managed frame.
@@ -8252,6 +8257,7 @@ extern "C" bool QCALLTYPE SfiInit(StackFrameIterator* pThis, CONTEXT* pStackwalk
82528257
else
82538258
{
82548259
EEToProfilerExceptionInterfaceWrapper::ExceptionUnwindFunctionEnter(pMD);
8260+
pExInfo->m_pMDToReport = pMD;
82558261
}
82568262

82578263
pExInfo->m_sfLowBound = GetRegdisplaySP(pThis->m_crawl.GetRegisterSet());
@@ -8296,15 +8302,24 @@ extern "C" bool QCALLTYPE SfiNext(StackFrameIterator* pThis, uint* uExCollideCla
82968302

82978303
ExInfo* pExInfo = pThis->GetNextExInfo();
82988304
ExInfo* pTopExInfo = pThread->GetExceptionState()->GetCurrentExInfo();
8305+
bool isCollided = false;
82998306

83008307
MethodDesc *pMD = pThis->m_crawl.GetFunction();
83018308
if (pTopExInfo->m_passNumber == 1)
83028309
{
8303-
EEToProfilerExceptionInterfaceWrapper::ExceptionSearchFunctionLeave(pMD);
8310+
if (pTopExInfo->m_pMDToReport != NULL)
8311+
{
8312+
EEToProfilerExceptionInterfaceWrapper::ExceptionSearchFunctionLeave(pTopExInfo->m_pMDToReport);
8313+
pTopExInfo->m_pMDToReport = NULL;
8314+
}
83048315
}
83058316
else
83068317
{
8307-
EEToProfilerExceptionInterfaceWrapper::ExceptionUnwindFunctionLeave(pMD);
8318+
if (pTopExInfo->m_pMDToReport != NULL)
8319+
{
8320+
EEToProfilerExceptionInterfaceWrapper::ExceptionUnwindFunctionLeave(pTopExInfo->m_pMDToReport);
8321+
pTopExInfo->m_pMDToReport = NULL;
8322+
}
83088323
}
83098324

83108325
// Check for reverse pinvoke (but eliminate the case when the caller is managed) or CallDescrWorkerInternal.
@@ -8434,6 +8449,7 @@ extern "C" bool QCALLTYPE SfiNext(StackFrameIterator* pThis, uint* uExCollideCla
84348449
else
84358450
{
84368451
*uExCollideClauseIdx = pExInfo->m_idxCurClause;
8452+
isCollided = true;
84378453
pExInfo->m_kind = (ExKind)((uint8_t)pExInfo->m_kind | (uint8_t)ExKind::SupersededFlag);
84388454

84398455
// Unwind until we hit the frame of the prevExInfo
@@ -8471,15 +8487,23 @@ extern "C" bool QCALLTYPE SfiNext(StackFrameIterator* pThis, uint* uExCollideCla
84718487
pMD = pThis->m_crawl.GetFunction();
84728488
if (pTopExInfo->m_passNumber == 1)
84738489
{
8474-
EEToProfilerExceptionInterfaceWrapper::ExceptionSearchFunctionEnter(pMD);
8475-
8476-
// Notify the debugger that we are on the first pass for a managed exception.
8477-
// Note that this callback is made for every managed frame.
8478-
EEToDebuggerExceptionInterfaceWrapper::FirstChanceManagedException(pThread, GetControlPC(pThis->m_crawl.GetRegisterSet()), GetRegdisplaySP(pThis->m_crawl.GetRegisterSet()));
8490+
// TODO: skip this and the related ...Leave for collided Unwind - maybe move this to the AppendElement above?
8491+
if (!isCollided)
8492+
{
8493+
EEToProfilerExceptionInterfaceWrapper::ExceptionSearchFunctionEnter(pMD);
8494+
pTopExInfo->m_pMDToReport = pMD;
8495+
// Notify the debugger that we are on the first pass for a managed exception.
8496+
// Note that this callback is made for every managed frame.
8497+
EEToDebuggerExceptionInterfaceWrapper::FirstChanceManagedException(pThread, GetControlPC(pThis->m_crawl.GetRegisterSet()), GetRegdisplaySP(pThis->m_crawl.GetRegisterSet()));
8498+
}
84798499
}
84808500
else
84818501
{
8482-
EEToProfilerExceptionInterfaceWrapper::ExceptionUnwindFunctionEnter(pMD);
8502+
if (!isCollided)
8503+
{
8504+
EEToProfilerExceptionInterfaceWrapper::ExceptionUnwindFunctionEnter(pMD);
8505+
pTopExInfo->m_pMDToReport = pMD;
8506+
}
84838507
}
84848508

84858509
Exit:;

src/coreclr/vm/exinfo.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ void ExInfo::Init()
113113
m_StackAddress = this;
114114
DestroyExceptionHandle();
115115
m_hThrowable = NULL;
116+
m_ExceptionCode = 0;
117+
m_pMDToReport = NULL;
116118

117119
// By default, mark the tracker as not having delivered the first
118120
// chance exception notification

src/coreclr/vm/exinfo.h

+1
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ struct ExInfo
254254
EHClauseInfo m_EHClauseInfo;
255255
ExceptionFlags m_ExceptionFlags;
256256
DWORD m_ExceptionCode;
257+
MethodDesc *m_pMDToReport;
257258

258259
#ifndef TARGET_UNIX
259260
EHWatsonBucketTracker m_WatsonBucketTracker;

src/coreclr/vm/proftoeeinterfaceimpl.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -8073,6 +8073,17 @@ StackWalkAction ProfilerStackWalkCallback(CrawlFrame *pCf, PROFILER_STACK_WALK_D
80738073
CONTEXT builtContext;
80748074
#endif
80758075

8076+
//
8077+
// Skip all managed exception handling functions
8078+
//
8079+
if (pFunc != NULL && (
8080+
(pFunc->GetMethodTable() == g_pEHClass) ||
8081+
(pFunc->GetMethodTable() == g_pExceptionServicesInternalCallsClass) ||
8082+
(pFunc->GetMethodTable() == g_pStackFrameIteratorClass)))
8083+
{
8084+
return SWA_CONTINUE;
8085+
}
8086+
80768087
//
80778088
// For Unmanaged-to-managed transitions we get a NativeMarker back, which we want
80788089
// to return to the profiler as the context seed if it wants to walk the unmanaged
@@ -8091,6 +8102,18 @@ StackWalkAction ProfilerStackWalkCallback(CrawlFrame *pCf, PROFILER_STACK_WALK_D
80918102
return SWA_CONTINUE;
80928103
}
80938104

8105+
if (g_isNewExceptionHandlingEnabled && !pCf->IsFrameless() && InlinedCallFrame::FrameHasActiveCall(pCf->GetFrame()))
8106+
{
8107+
// Skip new exception handling helpers
8108+
InlinedCallFrame *pInlinedCallFrame = (InlinedCallFrame *)pCf->GetFrame();
8109+
PTR_NDirectMethodDesc pMD = pInlinedCallFrame->m_Datum;
8110+
TADDR datum = dac_cast<TADDR>(pMD);
8111+
if ((datum & (TADDR)InlinedCallFrameMarker::Mask) == (TADDR)InlinedCallFrameMarker::ExceptionHandlingHelper)
8112+
{
8113+
return SWA_CONTINUE;
8114+
}
8115+
}
8116+
80948117
//
80958118
// If this is not a transition of any sort and not a managed
80968119
// method, ignore it.
@@ -8114,6 +8137,8 @@ StackWalkAction ProfilerStackWalkCallback(CrawlFrame *pCf, PROFILER_STACK_WALK_D
81148137
{
81158138
frameInfo.funcID = NULL;
81168139
frameInfo.extraArg = NULL;
8140+
// TODO: fixme - intermediate native frames should likely be reported
8141+
//return SWA_CONTINUE;
81178142
}
81188143

81198144
frameInfo.IP = currentIP;

src/coreclr/vm/vars.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ MethodTable* g_pCastHelpers;
110110
#ifdef FEATURE_EH_FUNCLETS
111111
GPTR_IMPL(MethodTable, g_pEHClass);
112112
GPTR_IMPL(MethodTable, g_pExceptionServicesInternalCallsClass);
113+
GPTR_IMPL(MethodTable, g_pStackFrameIteratorClass);
113114
GVAL_IMPL(bool, g_isNewExceptionHandlingEnabled);
114115
#endif
115116

src/coreclr/vm/vars.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ GVAL_DECL(DWORD, g_TlsIndex);
392392
#ifdef FEATURE_EH_FUNCLETS
393393
GPTR_DECL(MethodTable, g_pEHClass);
394394
GPTR_DECL(MethodTable, g_pExceptionServicesInternalCallsClass);
395+
GPTR_DECL(MethodTable, g_pStackFrameIteratorClass);
395396
GVAL_DECL(bool, g_isNewExceptionHandlingEnabled);
396397
#endif
397398

0 commit comments

Comments
 (0)