/SimpleProfiler/ProfilerCallback.cpp
C++ | 3763 lines | 2653 code | 656 blank | 454 comment | 465 complexity | 68615634c6ae5989cfe5c63df722da55 MD5 | raw file
Possible License(s): GPL-3.0, MIT, CC-BY-SA-3.0
Large files files are truncated, but you can click here to view the full file
- // ==++==
- //
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //
- // ==--==
- /****************************************************************************************
- * File:
- * ProfilerCallBack.cpp
- *
- * Description:
- * Implements ICorProfilerCallback. Logs every event of interest to a file on disc.
- *
- ***************************************************************************************/
-
- #undef _WIN32_WINNT
- #define _WIN32_WINNT 0x0403
-
- #include <windows.h>
- #include <share.h>
-
- #include "basehlp.h"
- #include "basehlp.hpp"
-
- #include "ProfilerInfo.h"
- #include "ProfilerCallback.h"
-
- ProfilerCallback *g_pCallbackObject; // global reference to callback object
- /***************************************************************************************
- ******************** ********************
- ******************** Global Functions Used for Thread Support ********************
- ******************** ********************
- ***************************************************************************************/
-
- /* static __stdcall */
- DWORD __stdcall ThreadStub( void *pObject )
- {
- ((ProfilerCallback *)pObject)->_ThreadStubWrapper();
-
- return 0;
-
- } // _GCThreadStub
-
-
-
- /***************************************************************************************
- ******************** ********************
- ******************** Global Functions Used by Function Hooks ********************
- ******************** ********************
- ***************************************************************************************/
-
- //
- // The functions EnterStub, LeaveStub and TailcallStub are wrappers. The use of
- // of the extended attribute "__declspec( naked )" does not allow a direct call
- // to a profiler callback (e.g., ProfilerCallback::Enter( functionID )).
- //
- // The enter/leave function hooks must necessarily use the extended attribute
- // "__declspec( naked )". Please read the corprof.idl for more details.
- //
-
- EXTERN_C void __stdcall EnterStub(FunctionID functionID,
- UINT_PTR clientData,
- COR_PRF_FRAME_INFO frameInfo,
- COR_PRF_FUNCTION_ARGUMENT_INFO *argumentInfo)
- {
- ProfilerCallback::Enter( functionID, clientData, frameInfo, argumentInfo );
-
- } // EnterStub
-
-
- EXTERN_C void __stdcall LeaveStub( FunctionID functionID, COR_PRF_FUNCTION_ARGUMENT_RANGE *retvalRange )
- {
- ProfilerCallback::Leave( functionID, retvalRange );
-
- } // LeaveStub
-
-
- EXTERN_C void __stdcall TailcallStub( FunctionID functionID )
- {
- ProfilerCallback::Tailcall( functionID );
-
- } // TailcallStub
-
-
- #ifdef _X86_
-
- void __declspec( naked ) EnterNaked2(FunctionID funcId,
- UINT_PTR clientData,
- COR_PRF_FRAME_INFO frameInfo,
- COR_PRF_FUNCTION_ARGUMENT_INFO *argumentInfo)
- {
-
- __asm
- {
- PUSH EBP
- MOV EBP, ESP
-
- PUSH EAX
- PUSH ECX
- PUSH EDX
-
- }
-
- EnterStub(funcId, clientData, frameInfo, argumentInfo);
-
- __asm
- {
- POP EDX
- POP ECX
- POP EAX
-
- MOV ESP, EBP
- POP EBP
-
- RET 10H
- }
-
- } // EnterNaked
-
- void __declspec( naked ) LeaveNaked2(FunctionID funcId,
- UINT_PTR clientData,
- COR_PRF_FRAME_INFO frameInfo,
- COR_PRF_FUNCTION_ARGUMENT_RANGE *retvalRange)
- {
- __asm
- {
- PUSH EBP
- MOV EBP, ESP
-
- PUSH EAX
- PUSH ECX
- PUSH EDX
- }
-
- LeaveStub(funcId, retvalRange);
-
- __asm
- {
- POP EDX
- POP ECX
- POP EAX
-
- MOV ESP, EBP
- POP EBP
-
- RET 10H
- }
- } // LeaveNaked
-
-
- void __declspec( naked ) TailcallNaked2(FunctionID funcId,
- UINT_PTR clientData,
- COR_PRF_FRAME_INFO frameInfo)
- {
- __asm
- {
- push eax
- push ecx
- push edx
- push [esp + 16]
- call TailcallStub
- pop edx
- pop ecx
- pop eax
- ret 12
- }
- } // TailcallNaked
-
- #elif defined(_AMD64_)
- // these are linked in AMD64 assembly (amd64\asmhelpers.asm)
- EXTERN_C void EnterNaked2(FunctionID funcId,
- UINT_PTR clientData,
- COR_PRF_FRAME_INFO frameInfo,
- COR_PRF_FUNCTION_ARGUMENT_INFO *argumentInfo);
- EXTERN_C void LeaveNaked2(FunctionID funcId,
- UINT_PTR clientData,
- COR_PRF_FRAME_INFO frameInfo,
- COR_PRF_FUNCTION_ARGUMENT_RANGE *retvalRange);
- EXTERN_C void TailcallNaked2(FunctionID funcId,
- UINT_PTR clientData,
- COR_PRF_FRAME_INFO frameInfo);
- #endif // _X86_
-
- /***************************************************************************************
- ******************** ********************
- ******************** ProfilerCallBack Implementation ********************
- ******************** ********************
- ***************************************************************************************/
-
-
- /* public */
-
- ProfilerCallback::ProfilerCallback() :
- PrfInfo(),
- m_path( NULL ),
- m_status_path( NULL),
- m_refCount( 0 ),
- m_stream( NULL ),
- m_dwShutdown( 0 ),
- m_bShutdown( FALSE ),
- m_dwProcessId( NULL ),
- m_filter( NULL ),
- m_filterLen( 0 ),
- m_pGCHost( NULL ),
- m_includeSystem( FALSE ),
- m_traceEvent( FALSE ),
- m_traceParameter( FALSE )
- {
- HRESULT hr = S_OK;
-
- //TEXT_OUTLN( "Turning off profiling for child processes" )
- SetEnvironmentVariableW(L"Cor_Enable_Profiling", L"0x0");
-
- //
- // initializations
- //
- if (!InitializeCriticalSectionAndSpinCount( &m_criticalSection, 10000 ))
- hr = E_FAIL;
- if (!InitializeCriticalSectionAndSpinCount( &g_criticalSection, 10000 ))
- hr = E_FAIL;
-
- g_pCallbackObject = this;
- m_dwProcessId = GetCurrentProcessId();
-
- //
- // define in which mode you will operate
- //
- strcpy_s( m_logFileName, ARRAY_LEN(m_logFileName), FILENAME );
- _ProcessEnvVariables();
-
- if (SUCCEEDED(hr) )
- {
- //
- // open the correct file stream fo dump the logging information
- //
- m_stream = _fsopen((m_path != NULL) ? m_path : m_logFileName, "a+", _SH_DENYWR);
- hr = ( m_stream == NULL ) ? E_FAIL : S_OK;
- if ( SUCCEEDED( hr ))
- {
- setvbuf(m_stream, NULL, _IOFBF, 32768);
- LogToAnyInternal( "SimpleProfiler\n");
- }
- else {
- TEXT_OUTLN( "Unable to open log file - No log will be produced" );
- }
- }
-
- if(FAILED(hr))
- {
- m_dwEventMask = COR_PRF_MONITOR_NONE;
- }
-
- } // ctor
-
-
- /* public */
- ProfilerCallback::~ProfilerCallback()
- {
- LogToAnyInternal( "~SimpleProfiler\n");
-
- if ( m_path != NULL )
- {
- delete[] m_path;
- m_path = NULL;
- }
-
- if ( m_filter != NULL )
- {
- delete[] m_filter;
- m_filter = NULL;
- }
-
- if ( m_stream != NULL )
- {
- fflush( m_stream );
- fclose( m_stream );
- m_stream = NULL;
- }
-
- m_pFunctionTable.clear();
- m_pClassTable.clear();
-
- DeleteCriticalSection( &m_criticalSection );
- DeleteCriticalSection( &g_criticalSection );
-
- g_pCallbackObject = NULL;
-
- m_pFunctionTable.clear();
- m_pClassTable.clear();
- m_pClassNameTable.clear();
- m_pModuleTable.clear();
-
- } // dtor
-
-
- /* public */
- ULONG ProfilerCallback::AddRef()
- {
- return InterlockedIncrement( &m_refCount );
-
- } // ProfilerCallback::AddRef
-
-
- /* public */
- ULONG ProfilerCallback::Release()
- {
- long refCount;
- refCount = InterlockedDecrement( &m_refCount );
- if ( refCount == 0 )
- delete this;
- return refCount;
-
- } // ProfilerCallback::Release
-
-
- /* public */
- HRESULT ProfilerCallback::QueryInterface( REFIID riid, void **ppInterface )
- {
- if ( riid == IID_IUnknown )
- *ppInterface = static_cast<IUnknown *>( this );
-
- else if ( riid == IID_ICorProfilerCallback )
- *ppInterface = static_cast<ICorProfilerCallback *>( this );
-
- else if ( riid == IID_ICorProfilerCallback2 )
- *ppInterface = static_cast<ICorProfilerCallback2 *>( this );
-
- else
- {
- *ppInterface = NULL;
-
- return E_NOINTERFACE;
- }
-
- reinterpret_cast<IUnknown *>( *ppInterface )->AddRef();
-
- return S_OK;
-
- } // ProfilerCallback::QueryInterface
-
-
- /* public static */
- HRESULT ProfilerCallback::CreateObject( REFIID riid, void **ppInterface )
- {
- HRESULT hr = E_NOINTERFACE;
-
- *ppInterface = NULL;
- if ( (riid == IID_IUnknown)
- || (riid == IID_ICorProfilerCallback2)
- || (riid == IID_ICorProfilerCallback) )
- {
- ProfilerCallback *pProfilerCallback;
-
- pProfilerCallback = new ProfilerCallback();
- if ( pProfilerCallback != NULL )
- {
- hr = S_OK;
-
- pProfilerCallback->AddRef();
- *ppInterface = static_cast<ICorProfilerCallback *>( pProfilerCallback );
- }
- else
- hr = E_OUTOFMEMORY;
- }
-
- return hr;
-
- } // ProfilerCallback::CreateObject
-
-
- IGCHost *GetGCHost()
- {
- ICorRuntimeHost *pCorHost = NULL;
-
- CoInitializeEx(NULL, COINIT_MULTITHREADED);
-
- HRESULT hr = CoCreateInstance( CLSID_CorRuntimeHost,
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_ICorRuntimeHost,
- (void**)&pCorHost );
-
- if (SUCCEEDED(hr))
- {
- IGCHost *pGCHost = NULL;
-
- hr = pCorHost->QueryInterface(IID_IGCHost, (void**)&pGCHost);
-
- if (SUCCEEDED(hr))
- return pGCHost;
- else
- printf("Could not QueryInterface hr = %x\n", hr);
- }
- else
- printf("Could not CoCreateInstanceEx hr = %x\n", hr);
-
- return NULL;
- }
-
- /* public */
-
- HRESULT ProfilerCallback::Initialize( IUnknown *pICorProfilerInfoUnk )
- {
- HRESULT hr;
-
- hr = pICorProfilerInfoUnk->QueryInterface( IID_ICorProfilerInfo,
- (void **)&m_pProfilerInfo );
- if ( SUCCEEDED( hr ) )
- {
- hr = pICorProfilerInfoUnk->QueryInterface( IID_ICorProfilerInfo2,
- (void **)&m_pProfilerInfo2 );
- }else{
- Failure( "QueryInterface for ICorProfilerInfo FAILED" );
- }
-
- if ( SUCCEEDED( hr ) )
- {
- //printf("event mask = %x\n", m_dwEventMask);
- hr = m_pProfilerInfo2->SetEventMask( m_dwEventMask );
-
- if ( SUCCEEDED( hr ) )
- {
- #if defined(_X86_)
- hr = m_pProfilerInfo2->SetEnterLeaveFunctionHooks2( EnterNaked2,
- LeaveNaked2,
- TailcallNaked2 );
- #elif defined(_AMD64_)
- hr = m_pProfilerInfo2->SetEnterLeaveFunctionHooks2( (FunctionEnter2 *)EnterNaked2,
- (FunctionLeave2 *)LeaveNaked2,
- (FunctionTailcall2 *)TailcallNaked2 );
- #else
- hr = m_pProfilerInfo2->SetEnterLeaveFunctionHooks2( (FunctionEnter2 *)&EnterStub,
- (FunctionLeave2 *)&LeaveStub,
- (FunctionTailcall2 *)&TailcallStub );
- #endif // defined(_X86_) || defined(_AMD64_)
-
- if ( SUCCEEDED( hr ) )
- {
- Sleep(100); // Give the threads a chance to read any signals that are already set.
- }
- else
- Failure( "ICorProfilerInfo::SetEnterLeaveFunctionHooks() FAILED" );
- }
- else
- Failure( "SetEventMask for Profiler FAILED" );
- }
- else
- {
- Failure( "QueryInterface for ICorProfilerInfo2 FAILED" );
- Failure( "Allocation for Profiler FAILED" );
- }
-
- if(m_traceEvent) {
- LogToAny("Initialize\n");
- }
- return S_OK;
-
- } // ProfilerCallback::Initialize
-
-
- /* public */
- HRESULT ProfilerCallback::Shutdown()
- {
- m_dwShutdown++;
-
- if(m_traceEvent) {
- LogToAny("Shutdown\n");
- }
- return S_OK;
-
- } // ProfilerCallback::Shutdown
-
-
- /* public */
- HRESULT ProfilerCallback::DllDetachShutdown()
- {
- //
- // If no shutdown occurs during DLL_DETACH, release the callback
- // interface pointer. This scenario will more than likely occur
- // with any interop related program (e.g., a program that is
- // comprised of both managed and unmanaged components).
- //
- m_dwShutdown++;
- if ( (m_dwShutdown == 1) && (g_pCallbackObject != NULL) )
- {
- g_pCallbackObject->Release();
- g_pCallbackObject = NULL;
- }
-
- return S_OK;
-
- } // ProfilerCallback::DllDetachShutdown
-
- /* public */
-
- __forceinline void ProfilerCallback::Enter( FunctionID functionID,
- UINT_PTR clientData,
- COR_PRF_FRAME_INFO frameInfo,
- COR_PRF_FUNCTION_ARGUMENT_INFO *argumentInfo )
- {
- FunctionInfo *pFunctionInfo = NULL;
- pFunctionInfo = g_pCallbackObject->m_pFunctionTable[functionID];
-
- if(pFunctionInfo != NULL && g_pCallbackObject->_IsNeedToLog(pFunctionInfo->m_name) &&
- (g_pCallbackObject->m_traceEvent || g_pCallbackObject->m_traceParameter)
- )
- {
- g_pCallbackObject->LogToAny("> %S",
- pFunctionInfo->m_name);
-
- if(g_pCallbackObject->m_traceParameter)
- {
- g_pCallbackObject->LogToAny("(");
-
- HRESULT hr;
- mdMethodDef methodDef;
- IMetaDataImport *mdi = NULL;
-
- hr = g_pCallbackObject->m_pProfilerInfo->GetTokenAndMetaDataFromFunction(
- functionID,
- IID_IMetaDataImport,
- (IUnknown**) &mdi,
- &methodDef);
-
- // output parameter list
- if(SUCCEEDED(hr) && mdi)
- {
- hr = g_pCallbackObject->TraceParameterList( pFunctionInfo,
- argumentInfo, g_pCallbackObject->m_pProfilerInfo2, mdi);
- }
-
- g_pCallbackObject->LogToAny(") %S", pFunctionInfo->m_pReturnInfo->m_typeName);
-
- if(mdi) mdi->Release();
- }
-
- g_pCallbackObject->LogToAny("\n");
- }
-
- } // ProfilerCallback::Enter
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceParameterList(
- FunctionInfo* pFunctionInfo,
- COR_PRF_FUNCTION_ARGUMENT_INFO *argumentInfo,
- ICorProfilerInfo2 *cpi,
- IMetaDataImport *mdi)
- {
- HRESULT hr = S_OK;
- if(pFunctionInfo->m_argCount == 0) return hr;
-
- // output parameters
- int offset = argumentInfo->numRanges - pFunctionInfo->m_argCount;
- for(ULONG i = 0;
- i < pFunctionInfo->m_argCount;
- i++)
- {
- hr = TraceParameter(
- &(argumentInfo->ranges[i + offset]), pFunctionInfo->m_ppParamInfo[i], cpi, mdi);
-
- if(i < pFunctionInfo->m_argCount - 1) LogToAny(", ");
-
- }
-
- return hr;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceParameter(
- COR_PRF_FUNCTION_ARGUMENT_RANGE *range,
- ParameterInfo *pParameterInfo,
- ICorProfilerInfo2 *cpi,
- IMetaDataImport *mdi)
- {
- HRESULT hr = S_OK;
- // get argument direction
- PWCHAR direction;
- if(!pParameterInfo->m_isByRef)
- direction = L"";
- else if(IsPdOut(pParameterInfo->m_attributes) != 0)
- direction = L"out ";
- else
- direction = L"ref ";
-
- // output
- LogToAny("%S%S %S", direction, pParameterInfo->m_typeName, pParameterInfo->m_name);
-
- // no out parameters on enter
- if(IsPdOut(pParameterInfo->m_attributes) == 0)
- {
- LogToAny("=");
-
- hr = TraceValue(
- pParameterInfo->m_isByRef ? *(PUINT_PTR)(range->startAddress) : range->startAddress,
- cpi, mdi,
- pParameterInfo);
- }
-
- return hr;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceValue(
- UINT_PTR startAddress,
- ICorProfilerInfo2 *cpi,
- IMetaDataImport *mdi,
- ParameterInfo *pParameterInfo)
- {
- /*if(pParameterInfo->m_def == mdTokenNil || pParameterInfo->m_def == 0xffffffff)
- {
- LogToAny("?");
- return S_OK;
- }*/
-
- if(pParameterInfo->m_isArray) {
- return TraceArray(*(PUINT_PTR)(startAddress), cpi, mdi, pParameterInfo);
- }
-
- switch(pParameterInfo->m_type)
- {
- case ELEMENT_TYPE_STRING:
- return TraceString(*(PUINT_PTR)startAddress, cpi);
- case ELEMENT_TYPE_BOOLEAN:
- return TraceBoolean(startAddress);
- case ELEMENT_TYPE_CHAR:
- return TraceChar(startAddress);
- case ELEMENT_TYPE_I1:
- return TraceSByte(startAddress);
- case ELEMENT_TYPE_U1:
- return TraceByte(startAddress);
- case ELEMENT_TYPE_I2:
- return TraceShort(startAddress);
- case ELEMENT_TYPE_U2:
- return TraceUShort(startAddress);
- case ELEMENT_TYPE_I4:
- return TraceInt(startAddress);
- case ELEMENT_TYPE_U4:
- return TraceUInt(startAddress);
- case ELEMENT_TYPE_I8:
- return TraceLong(startAddress);
- case ELEMENT_TYPE_U8:
- return TraceULong(startAddress);
- case ELEMENT_TYPE_R4:
- return TraceFloat(startAddress);
- case ELEMENT_TYPE_R8:
- return TraceDouble(startAddress);
- case ELEMENT_TYPE_VALUETYPE:
- return TraceStruct(startAddress, cpi, mdi, pParameterInfo, NULL, NULL, mdTokenNil);
- case ELEMENT_TYPE_CLASS:
- return TraceClass(*(PUINT_PTR)(startAddress), cpi, mdi, pParameterInfo);
- case ELEMENT_TYPE_OBJECT:
- return TraceObject(startAddress, cpi, mdi, pParameterInfo);
- /*
- case ELEMENT_TYPE_PTR:
- case ELEMENT_TYPE_ARRAY:
- case ELEMENT_TYPE_I:
- case ELEMENT_TYPE_U:
- case ELEMENT_TYPE_OBJECT:
- case ELEMENT_TYPE_SZARRAY:
- case ELEMENT_TYPE_FNPTR:
- case ELEMENT_TYPE_MAX:
- case ELEMENT_TYPE_END:
- case ELEMENT_TYPE_BYREF:
- case ELEMENT_TYPE_PINNED:
- case ELEMENT_TYPE_SENTINEL:
- case ELEMENT_TYPE_CMOD_OPT:
- case ELEMENT_TYPE_MODIFIER:
- case ELEMENT_TYPE_CMOD_REQD:
- case ELEMENT_TYPE_TYPEDBYREF:
- */
- case ELEMENT_TYPE_VOID:
- break;
- default:
- LogToAny("?");
- break;
- }
-
- return S_OK;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceObject(
- UINT_PTR startAddress,
- ICorProfilerInfo2 *cpi,
- IMetaDataImport *mdiRef,
- ParameterInfo *pParameterInfo)
- {
- //__asm { int 3 }
- bool traced = false;
- ObjectID oid = *(ObjectID *)startAddress;
- ClassID classId = NULL;
- HRESULT hr = cpi->GetClassFromObject(oid, &classId);
- if(SUCCEEDED(hr)) {
- ClassInfo *pClassInfo = m_pClassTable[classId];
- if(pClassInfo != NULL) {
- CorElementType type;
- type = _GetElementTypeFromClassName(pClassInfo->m_name);
- if(type <= ELEMENT_TYPE_R8 || type == ELEMENT_TYPE_I || type == ELEMENT_TYPE_U || type == ELEMENT_TYPE_END) {
- ULONG32 bufferOffset = 0;
- hr = cpi->GetBoxClassLayout(classId, &bufferOffset);
- if(SUCCEEDED(hr)) {
- oid = oid + bufferOffset;
- if(type == ELEMENT_TYPE_END) {
- type = ELEMENT_TYPE_VALUETYPE;
- }
- }else{
- if(type == ELEMENT_TYPE_END) {
- type = ELEMENT_TYPE_CLASS;
- hr = S_OK;
- }
- }
- }
- if(SUCCEEDED(hr)) {
- switch(type)
- {
- case ELEMENT_TYPE_STRING:
- hr = TraceString(oid, cpi);traced = true;break;
- case ELEMENT_TYPE_BOOLEAN:
- hr = TraceBoolean(oid);traced = true;break;
- case ELEMENT_TYPE_CHAR:
- hr = TraceChar(oid);traced = true;break;
- case ELEMENT_TYPE_I1:
- hr = TraceSByte(oid);traced = true;break;
- case ELEMENT_TYPE_U1:
- hr = TraceByte(oid);traced = true;break;
- case ELEMENT_TYPE_I2:
- hr = TraceShort(oid);traced = true;break;
- case ELEMENT_TYPE_U2:
- hr = TraceUShort(oid);traced = true;break;
- case ELEMENT_TYPE_I4:
- hr = TraceInt(oid);traced = true;break;
- case ELEMENT_TYPE_U4:
- hr = TraceUInt(oid);traced = true;break;
- case ELEMENT_TYPE_I8:
- hr = TraceLong(oid);traced = true;break;
- case ELEMENT_TYPE_U8:
- hr = TraceULong(oid);traced = true;break;
- case ELEMENT_TYPE_R4:
- hr = TraceFloat(oid);traced = true;break;
- case ELEMENT_TYPE_R8:
- hr = TraceDouble(oid);traced = true;break;
- case ELEMENT_TYPE_VALUETYPE:
- hr = TraceStruct(oid, cpi, mdiRef, pParameterInfo, NULL, classId, pClassInfo->m_classToken);traced = true;break;
- case ELEMENT_TYPE_CLASS:
- hr = TraceClass(oid, cpi, mdiRef, pParameterInfo);traced = true;break;
- default:
- hr = E_FAIL; break;
- }//end switch
- }
- if(!traced) LogToAny("?");
- LogToAny("(%S)", pClassInfo->m_name);
- }//end pClassInfo!=NULL
- }
- return hr;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceArray(
- ObjectID oid,
- ICorProfilerInfo2 *cpi,
- IMetaDataImport *mdiRef,
- ParameterInfo *pParameterInfo)
- {
- ULONG32 dim = 1;
- ULONG32 *dimSizes = new ULONG32[dim];
- int *dimLowerBounds = new int[dim];
- BYTE **ppData = new BYTE*[dim];
- //__asm { int 3 }
-
- HRESULT hr = cpi->GetArrayObjectInfo(oid, dim, dimSizes, dimLowerBounds, ppData);
- if(SUCCEEDED(hr)) {
- ULONG32 dimSize = dimSizes[0];
- ULONG32 dimLowerBound = dimLowerBounds[0];
- BYTE *pData = ppData[0];
- LogToAny("{");
- for(ULONG32 i=dimLowerBound; i<dimSize; i++) {
- switch(pParameterInfo->m_type) {
- case ELEMENT_TYPE_STRING:
- TraceString(*(ObjectID *)pData, cpi);
- pData += sizeof(ObjectID);
- break;
- case ELEMENT_TYPE_BOOLEAN:
- TraceBoolean((UINT_PTR)pData);
- pData += sizeof(bool);
- break;
- case ELEMENT_TYPE_CHAR:
- TraceChar((UINT_PTR)pData);
- pData += sizeof(WCHAR);
- break;
- case ELEMENT_TYPE_I1:
- TraceSByte((UINT_PTR)pData);
- pData += sizeof(char);
- break;
- case ELEMENT_TYPE_U1:
- TraceByte((UINT_PTR)pData);
- pData += sizeof(unsigned char);
- break;
- case ELEMENT_TYPE_I2:
- TraceShort((UINT_PTR)pData);
- pData += sizeof(short);
- break;
- case ELEMENT_TYPE_U2:
- TraceUShort((UINT_PTR)pData);
- pData += sizeof(unsigned short);
- break;
- case ELEMENT_TYPE_I4:
- TraceInt((UINT_PTR)pData);
- pData += sizeof(int);
- break;
- case ELEMENT_TYPE_U4:
- TraceUInt((UINT_PTR)pData);
- pData += sizeof(unsigned int);
- break;
- case ELEMENT_TYPE_I8:
- TraceLong((UINT_PTR)pData);
- pData += sizeof(long long);
- break;
- case ELEMENT_TYPE_U8:
- TraceULong((UINT_PTR)pData);
- pData += sizeof(unsigned long long);
- break;
- case ELEMENT_TYPE_R4:
- TraceFloat((UINT_PTR)pData);
- pData += sizeof(float);
- break;
- case ELEMENT_TYPE_R8:
- TraceDouble((UINT_PTR)pData);
- pData += sizeof(double);
- break;
- case ELEMENT_TYPE_VALUETYPE:
- {
- ULONG size = 0;
- TraceStruct((UINT_PTR)pData, cpi, mdiRef, pParameterInfo, &size, NULL, mdTokenNil);
- if(size < 0) {
- LogToAny("Cannot determine struct size.");
- break;
- }else{
- pData += size; // how to get size of struct?
- }
- }
- break;
- case ELEMENT_TYPE_CLASS:
- TraceClass(*(ObjectID *)pData, cpi, mdiRef, pParameterInfo);
- pData += sizeof(ObjectID);
- break;
- case ELEMENT_TYPE_OBJECT:
- TraceObject((UINT_PTR)pData, cpi, mdiRef, pParameterInfo);
- pData += sizeof(ObjectID);
- break;
- default:
- LogToAny("?");
- break;
- }
- if(i<dimSize-1) LogToAny(",");
- }
- LogToAny("}");
- }
- return hr;
- }
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceULong(UINT_PTR startAddress)
- {
- LogToAny("%u", *(unsigned long long *)startAddress);
- return S_OK;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceLong(UINT_PTR startAddress)
- {
- LogToAny("%d", *(long long *)startAddress);
- return S_OK;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceUInt(UINT_PTR startAddress)
- {
- LogToAny("%u", *(unsigned int *)startAddress);
- return S_OK;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceInt(UINT_PTR startAddress)
- {
- LogToAny("%d", *(int *)startAddress);
- return S_OK;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceUShort(UINT_PTR startAddress)
- {
- LogToAny("%u", *(unsigned short *)startAddress);
- return S_OK;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceShort(UINT_PTR startAddress)
- {
- LogToAny("%d", *(short *)startAddress);
- return S_OK;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceByte(UINT_PTR startAddress)
- {
- LogToAny("%u", *(unsigned char *)startAddress);
- return S_OK;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceSByte(UINT_PTR startAddress)
- {
- LogToAny("%d", *(char *)startAddress);
- return S_OK;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceChar(UINT_PTR startAddress)
- {
- LogToAny("'%c'", *(char*)startAddress);
- return S_OK;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceBoolean(UINT_PTR startAddress)
- {
- if((*(bool*)startAddress))
- {
- LogToAny("true");
- }else{
- LogToAny("false");
- }
- return S_OK;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceFloat(UINT_PTR startAddress)
- {
- LogToAny("%f", *(float*)startAddress);
- return S_OK;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceDouble(UINT_PTR startAddress)
- {
- LogToAny("%f", *(double*)startAddress);
- return S_OK;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceString(
- ObjectID oid,
- ICorProfilerInfo2 *cpi)
- {
- if(oid == mdTokenNil || oid == 0xffffffff)
- {
- LogToAny("null");
- return S_OK;
- }
-
- //if(oid <= 0xFF) { // how to check whether ObjectID is valid?
- // LogToAny("?");
- // return S_OK;
- //}
-
- // get string
- ULONG bufferOffset=0;
- ULONG stringLengthOffset=0;
- ULONG bufferLengthOffset=0;
- HRESULT hr = cpi->GetStringLayout(&bufferLengthOffset, &stringLengthOffset, &bufferOffset);
- if(SUCCEEDED(hr))
- {
- __try {
- LPWSTR buffer = (LPWSTR) (oid + bufferOffset);
- DWORD bufferLength = *((DWORD *)(oid + bufferLengthOffset));
- DWORD stringLength = *((DWORD *)(oid + stringLengthOffset));
- LogToAny("\"%S\"", buffer);
- }__except(ExceptionFilter(GetExceptionCode(), GetExceptionInformation())){
- LogToAny("?");
- }
- }else{
- LogToAny("?");
- }
- return hr;
- }
-
- int ProfilerCallback::ExceptionFilter(unsigned int code, struct _EXCEPTION_POINTERS *ep) {
- if (code == EXCEPTION_ACCESS_VIOLATION) {
- return EXCEPTION_EXECUTE_HANDLER;
- } else {
- return EXCEPTION_CONTINUE_SEARCH;
- };
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::TraceClass(
- ObjectID oid,
- ICorProfilerInfo2 *cpi,
- IMetaDataImport *mdiRef,
- ParameterInfo *pParameterInfo)
- {
- //__asm { int 3 }
-
- HRESULT hr = S_OK;
- int fieldCnt = 0;
- IMetaDataImport *mdi = mdiRef;
-
- // get class for object
- ClassID classId = NULL;
- hr = cpi->GetClassFromObject(oid, &classId);
- ClassInfo *pClassInfo = NULL;
- if(SUCCEEDED(hr)) {
- pClassInfo = m_pClassTable[classId];
- }
- if(pClassInfo==NULL) {
- LogToAny("?");
- return E_FAIL;
- }
-
- LogToAny("{");
-
- bool isRef = (pParameterInfo->m_moduleId != pClassInfo->m_moduleID);
- if(isRef) {
- ModuleInfo *pModuleInfo = m_pModuleTable[pClassInfo->m_moduleID];
- if(pModuleInfo != NULL) {
- mdi = pModuleInfo->GetMDI();
- }
- }
-
- if(SUCCEEDED(hr) && classId != NULL)
- {
- ULONG fieldOffsetCount = 0;
- hr = cpi->GetClassLayout(
- classId,
- NULL, 0, &fieldOffsetCount, NULL);
-
- if(fieldOffsetCount != 0) {
-
- COR_FIELD_OFFSET* fieldOffset = new COR_FIELD_OFFSET[fieldOffsetCount];
-
- hr = cpi->GetClassLayout(
- classId,
- fieldOffset, fieldOffsetCount, &fieldOffsetCount, NULL);
-
- // output fields
- if(SUCCEEDED(hr))
- {
- for(ULONG i=0; i < fieldOffsetCount; i++)
- {
- ParameterInfo *pFieldParam = new ParameterInfo(fieldOffset[i].ridOfField);
- // get field name and prepare type info from metadata
- PCCOR_SIGNATURE sigBlob;
- ULONG sigBlobSize;
-
- hr = mdi->GetFieldProps(
- fieldOffset[i].ridOfField, NULL,
- pFieldParam->m_name, MAX_LENGTH, // get field name
- NULL, NULL, // acutal size of name, not relevant here
- &sigBlob, &sigBlobSize, // field metadata
- NULL, NULL, NULL);
-
- // get type and typename
- if(SUCCEEDED(hr))
- {
-
- // make sure metadata describes a field and move forward in metadata
- if(*sigBlob++ == IMAGE_CEE_CS_CALLCONV_FIELD)
- {}
-
- // get kind of type (primitive, class, ...) and type name
- pFieldParam->m_type = GetType(sigBlob, pFieldParam->m_isByRef, pFieldParam->m_typeDef, pFieldParam->m_isArray);
- hr = GetTypeName(pFieldParam->m_typeName, MAX_LENGTH, pFieldParam->m_type, pFieldParam->m_typeDef, mdi);
- if(SUCCEEDED(hr) && pFieldParam->m_isArray)
- wcscat_s(pFieldParam->m_name, L"[]");
- }
-
- // output
- if(SUCCEEDED(hr))
- {
- if(fieldCnt++ > 0)
- LogToAny(", ");
- LogToAny("%S %S=", pFieldParam->m_typeName, pFieldParam->m_name);
-
- if(pClassInfo->IsValidField(mdi, fieldOffset[i].ridOfField)) {
- switch(pFieldParam->m_type) {
- case ELEMENT_TYPE_VALUETYPE:
- case ELEMENT_TYPE_CLASS:
- LogToAny("?");
- break;
- default:
- TraceValue(
- oid + fieldOffset[i].ulOffset,
- cpi, mdi, pFieldParam);
- break;
- }
- }else{
- LogToAny("?");
- }
- }
-
- if(pFieldParam != NULL)
- delete pFieldParam;
- }
- }else{
- LogToAny("err=0x%p", hr);
- }
-
- if(fieldOffset)
- delete [] fieldOffset;
-
- } //end of numFields != 0
-
- }//end
-
- LogToAny("}");
- return hr;
- }
-
- HRESULT ProfilerCallback::GetStructParamInfo(ICorProfilerInfo2 *cpi,
- IMetaDataImport **mdiRef,
- ParameterInfo *pParameterInfo,
- ClassID &classId,
- mdTypeDef &typeDef)
- {
- HRESULT hr = S_OK;
- typeDef = pParameterInfo->m_typeDef;
- bool isRef = (TypeFromToken( typeDef ) == mdtTypeRef);
-
- classId = NULL;
- // get class id
- if(isRef) {
- ClassInfo *pClassInfo = m_pClassNameTable[Hash(pParameterInfo->m_typeName)];
- if(pClassInfo != NULL) {
- classId = pClassInfo->m_id;
- }
-
- IMetaDataImport *pMetaDataImportRef = NULL;
- mdTypeDef classToken;
- hr = (*mdiRef)->ResolveTypeRef(typeDef, IID_IMetaDataImport, (IUnknown **)&pMetaDataImportRef, &classToken);
- if (hr == S_OK)
- {
- *mdiRef = pMetaDataImportRef;
- typeDef = classToken;
- }
-
- }else{
- hr = cpi->GetClassFromToken(pParameterInfo->m_moduleId, typeDef, &classId);
- if(!SUCCEEDED(hr))
- classId = NULL;
- }
- return hr;
- }
-
- HRESULT ProfilerCallback::TraceStruct(
- UINT_PTR startAddress,
- ICorProfilerInfo2 *cpi,
- IMetaDataImport *mdiRef,
- ParameterInfo *pParameterInfo,
- ULONG *pcSize,
- ClassID classIdIn,
- mdTypeDef typeDefIn
- )
- {
- HRESULT hr = S_OK;
- int fieldCnt = 0;
- mdTypeDef typeDef = pParameterInfo->m_typeDef;
- IMetaDataImport *mdi = mdiRef;
- ClassID classId = NULL;
-
- if(classIdIn != NULL && typeDefIn != mdTokenNil) {
- classId = classIdIn;
- typeDef = typeDefIn;
- }else{
- hr = GetStructParamInfo(cpi, &mdi, pParameterInfo, classId, typeDef);
- }
-
- ClassInfo *pClassInfo = NULL;
- if(classId != NULL) {
- pClassInfo = m_pClassTable[classId];
- }
- if(pClassInfo == NULL) {
- LogToAny("?");
- return E_FAIL;
- }
-
- ULONG structSize = 0;
-
- LogToAny("{");
-
- {
- ULONG fieldOffsetCount = 0;
- if(SUCCEEDED(hr)) {
- hr = cpi->GetClassLayout(
- classId,
- NULL, 0, &fieldOffsetCount, NULL);
- }
-
- if(SUCCEEDED(hr) && fieldOffsetCount != 0) {
-
- //__asm { int 3 }
-
- COR_FIELD_OFFSET* fieldOffset = new COR_FIELD_OFFSET[fieldOffsetCount];
- hr = cpi->GetClassLayout(
- classId,
- fieldOffset, fieldOffsetCount, &fieldOffsetCount, NULL);
-
- // output fields
- if(SUCCEEDED(hr))
- {
- for(ULONG i=0; i < fieldOffsetCount; i++)
- {
- ParameterInfo *pFieldParam = new ParameterInfo(fieldOffset[i].ridOfField);
- // get field name and prepare type info from metadata
- PCCOR_SIGNATURE sigBlob;
- ULONG sigBlobSize;
-
- hr = mdi->GetFieldProps(
- fieldOffset[i].ridOfField, NULL,
- pFieldParam->m_name, MAX_LENGTH, // get field name
- NULL, NULL, // acutal size of name, not relevant here
- &sigBlob, &sigBlobSize, // field metadata
- NULL, NULL, NULL);
-
- // get type and typename
- if(SUCCEEDED(hr))
- {
- // make sure metadata describes a field and move forward in metadata
- if(*sigBlob++ == IMAGE_CEE_CS_CALLCONV_FIELD)
- {}
-
- // get kind of type (primitive, class, ...) and type name
- pFieldParam->m_type = GetType(sigBlob, pFieldParam->m_isByRef, pFieldParam->m_typeDef, pFieldParam->m_isArray);
- hr = GetTypeName(pFieldParam->m_typeName, MAX_LENGTH, pFieldParam->m_type, pFieldParam->m_typeDef, mdi);
- if(SUCCEEDED(hr) && pFieldParam->m_isArray)
- wcscat_s(pFieldParam->m_name, L"[]");
- }
-
- // output
- if(SUCCEEDED(hr))
- {
- ULONG typeSize = GetElementTypeSize(pFieldParam->m_type);
- if(typeSize < 0)
- structSize = -1;
- if(structSize>=0)
- structSize += typeSize;
-
- if(fieldCnt++ > 0)
- LogToAny(", ");
- LogToAny("%S %S=", pFieldParam->m_typeName, pFieldParam->m_name);
-
- //__asm { int 3 }
-
- if(pClassInfo->IsValidField(mdi, fieldOffset[i].ridOfField)) {
- switch(pFieldParam->m_type) {
- case ELEMENT_TYPE_VALUETYPE:
- case ELEMENT_TYPE_CLASS:
- LogToAny("?");
- break;
- default:
- TraceValue(
- startAddress + fieldOffset[i].ulOffset,
- cpi, mdi, pFieldParam);
- break;
- }
- }else{
- LogToAny("?");
- }
- }
- }
- }else{
- LogToAny("err=0x%p", hr);
- }
-
- } //end of numFields != 0
- else if(!SUCCEEDED(hr)) {
- LogToAny("err=0x%p", hr);
- }
- }
-
- LogToAny("}");
-
- if(pcSize != NULL) *pcSize = structSize;
- return hr;
- }
-
- // ----------------------------------------------------------------------------
- CorElementType ProfilerCallback::GetType(
- PCCOR_SIGNATURE& sigBlob,
- bool &isByRef,
- mdTypeDef &typeDef,
- bool &isArray)
- {
- CorElementType type = (CorElementType) *sigBlob++;
-
- isByRef = (ELEMENT_TYPE_BYREF == type);
-
- if(isByRef)
- type = (CorElementType) *sigBlob++;
-
- isArray = (ELEMENT_TYPE_SZARRAY == type);
-
- if(isArray)
- type = (CorElementType) *sigBlob++;
-
- typeDef = mdTypeDefNil;
-
- if(ELEMENT_TYPE_VALUETYPE == type || ELEMENT_TYPE_CLASS == type)
- {
- sigBlob += CorSigUncompressToken(sigBlob, &typeDef);
- }
-
- return type;
- }
-
- // ----------------------------------------------------------------------------
- HRESULT ProfilerCallback::GetTypeName(
- PWCHAR name,
- ULONG size,
- CorElementType type,
- mdTypeDef typeDef,
- IMetaDataImport *mdi)
- {
- HRESULT hr = S_OK;
-
- switch(type)
- {
- case ELEMENT_TYPE_VALUETYPE:
- case ELEMENT_TYPE_CLASS:
- if ( TypeFromToken( typeDef ) == mdtTypeRef )
- {
- hr = mdi->GetTypeRefProps(
- typeDef, NULL,
- name, MAX_LENGTH, NULL);
- }
- else
- {
- hr = mdi->GetTypeDefProps(
- typeDef,
- name, MAX_LENGTH, NULL, NULL, NULL);
- }
- if(!SUCCEEDED(hr))
- {
- name[0] = '\0';
- }
- break;
- default:
- {
- _GetNameFromElementType(type, name, size);
- }
- break;
- }
-
- return hr;
- }
-
- /* public */
- __forceinline void ProfilerCallback::Leave( FunctionID functionID, COR_PRF_FUNCTION_ARGUMENT_RANGE *retvalRange )
- {
- FunctionInfo *pFunctionInfo = NULL;
- pFunctionInfo = g_pCallbackObject->m_pFunctionTable[functionID];
-
- if(pFunctionInfo != NULL && g_pCallbackObject->_IsNeedToLog(pFunctionInfo->m_name) &&
- (g_pCallbackObject->m_traceEvent || g_pCallbackObject->m_traceParameter)
- )
- {
- g_pCallbackObject->LogToAny("< %S",
- pFunctionInfo->m_name);
-
- if(g_pCallbackObject->m_traceParameter)
- {
- g_pCallbackObject->LogToAny(" %S",
- pFunctionInfo->m_pReturnInfo->m_typeName);
-
- HRESULT hr;
- mdMethodDef methodDef;
- IMetaDataImport *mdi = NULL;
-
- if(pFunctionInfo->m_pReturnInfo->m_type != ELEMENT_TYPE_VOID)
- {
- hr = g_pCallbackObject->m_pProfilerInfo->GetTokenAndMetaDataFromFunction(
- functionID,
- IID_IMetaDataImport,
- (IUnknown**) &mdi,
- &methodDef);
-
- if(SUCCEEDED(hr) && mdi != NULL) {
- g_pCallbackObject->LogToAny("=");
- hr = g_pCallbackObject->TraceValue(
- pFunctionInfo->m_pReturnInfo->m_isByRef ? *(PUINT_PTR)(retvalRange->startAddress) : retvalRange->startAddress,
- g_pCallbackObject->m_pProfilerInfo2, mdi,
- pFunctionInfo->m_pReturnInfo);
- }
- }
- }
-
- g_pCallbackObject->LogToAny("\n");
- }
-
- } // ProfilerCallback::Leave
-
- /* public */
- void ProfilerCallback::Tailcall( FunctionID functionID )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( g_pCallbackObject->m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
-
- if(g_pCallbackObject->m_traceEvent) {
- g_pCallbackObject->LogToAny("Tailcall: FunctionID=0x%p\n", functionID);
- }
-
- } // ProfilerCallback::Tailcall
-
- /* public */
- HRESULT ProfilerCallback::ModuleLoadFinished( ModuleID moduleID,
- HRESULT hrStatus )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
-
- try
- {
- if(SUCCEEDED(hrStatus)) {
- AddModule(moduleID);
- }
- }
- catch ( BaseException *exception )
- {
- exception->ReportFailure();
- delete exception;
- Failure();
- }
-
- if(m_traceEvent) {
- ModuleInfo *pModuleInfo = m_pModuleTable[moduleID];
- if(pModuleInfo != NULL)
- LogToAny( "ModuleLoadFinished: ModuleID=0x%p, Name=%S, Address=0x%p\n",
- moduleID,
- pModuleInfo->m_name,
- pModuleInfo->m_loadAddress
- );
- }
- return S_OK;
-
- } // ProfilerCallback::ModuleLoadFinished
-
- /* public */
- HRESULT ProfilerCallback::JITCompilationStarted( FunctionID functionID,
- BOOL fIsSafeToBlock )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
-
- try
- {
- AddFunction( functionID );
- }
- catch ( BaseException *exception )
- {
- exception->ReportFailure();
- delete exception;
- Failure();
- }
-
- if(m_traceEvent) {
- FunctionInfo *pFunctionInfo = m_pFunctionTable[functionID];
- if(pFunctionInfo != NULL)
- LogToAny("JITCompilationStarted: FunctionID=0x%p, Name=%S\n", functionID, pFunctionInfo->m_name);
- }
-
- return S_OK;
-
- } // ProfilerCallback::JITCompilationStarted
-
-
- /* public */
- HRESULT ProfilerCallback::JITCachedFunctionSearchStarted( FunctionID functionID,
- BOOL *pbUseCachedFunction )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
-
- // use the pre-jitted function
- *pbUseCachedFunction = TRUE;
-
- try
- {
- AddFunction( functionID );
- }
- catch ( BaseException *exception )
- {
- exception->ReportFailure();
- delete exception;
- Failure();
- }
-
- if(m_traceEvent) {
- FunctionInfo *pFunctionInfo = m_pFunctionTable[functionID];
- if(pFunctionInfo != NULL)
- LogToAny("JITCachedFunctionSearchStarted: FunctionID=0x%p, Name=%S\n", functionID, pFunctionInfo->m_name);
- }
-
- return S_OK;
-
- } // ProfilerCallback::JITCachedFunctionSearchStarted
-
- /* public */
- HRESULT ProfilerCallback::JITCompilationFinished( FunctionID functionID,
- HRESULT hrStatus,
- BOOL fIsSafeToBlock )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
-
- if(m_traceEvent) {
- LogToAny("JITCompilationFinished: FunctionID=0x%p\n", functionID);
- }
-
- return S_OK;
-
- } // ProfilerCallback::JITCompilationFinished
-
-
- /* public */
- HRESULT ProfilerCallback::JITCachedFunctionSearchFinished( FunctionID functionID,
- COR_PRF_JIT_CACHE result )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
-
- if(m_traceEvent) {
- LogToAny("JITCachedFunctionSearchFinished: FunctionID=0x%p\n", functionID);
- }
-
- return S_OK;
-
- } // ProfilerCallback::JITCachedFunctionSearchFinished
-
-
- /* public */
- HRESULT ProfilerCallback::ExceptionUnwindFunctionEnter( FunctionID functionID )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( g_pCallbackObject->m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
-
- if(m_traceEvent) {
- LogToAny("ExceptionUnwindFunctionEnter: FunctionID=0x%p\n", functionID);
- }
- return S_OK;
-
- } // ProfilerCallback::ExceptionUnwindFunctionEnter
-
-
- /* public */
- HRESULT ProfilerCallback::ExceptionUnwindFunctionLeave( )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
-
- if(m_traceEvent) {
- LogToAny("ExceptionUnwindFunctionLeave\n");
- }
-
- return S_OK;
-
- } // ProfilerCallback::ExceptionUnwindFunctionLeave
-
-
- /* public */
- HRESULT ProfilerCallback::ThreadCreated( ThreadID threadID )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( g_pCallbackObject->m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
-
- if(m_traceEvent) {
- HRESULT hr;
- ThreadID myThreadID;
-
- hr = m_pProfilerInfo->GetCurrentThreadID( &myThreadID );
- if ( SUCCEEDED( hr ) )
- {
- if ( threadID == myThreadID )
- {
- DWORD win32ThreadID;
- hr = m_pProfilerInfo->GetThreadInfo( threadID, &win32ThreadID );
- if ( SUCCEEDED( hr ) )
- {
- LogToAny("ThreadCreated: ThreadID=%0xp, Win32ThreadID=0x%p\n", threadID, win32ThreadID);
- }
- else
- {
- _THROW_EXCEPTION( "ICorProfilerInfo::GetThreadInfo() FAILED" )
- }
- }
- else
- _THROW_EXCEPTION( "Thread ID's do not match FAILED" )
- }
- else
- _THROW_EXCEPTION( "ICorProfilerInfo::GetCurrentThreadID() FAILED" )
- }
-
- return S_OK;
-
- } // ProfilerCallback::ThreadCreated
-
-
- /* public */
- HRESULT ProfilerCallback::ThreadDestroyed( ThreadID threadID )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( g_pCallbackObject->m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
- if(m_traceEvent)
- {
- LogToAny("ThreadDestroyed: ThreadID=%Id\n", threadID);
- }
- return S_OK;
-
- } // ProfilerCallback::ThreadDestroyed
-
- /* public */
- HRESULT ProfilerCallback::ThreadAssignedToOSThread( ThreadID managedThreadID,
- DWORD osThreadID )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( g_pCallbackObject->m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
- if(m_traceEvent) {
- LogToAny("ThreadAssignedToOSThread: ThreadID=0x%p, OSThreadID=0x%p\n", managedThreadID, osThreadID);
- }
- return S_OK;
-
- } // ProfilerCallback::ThreadAssignedToOSThread
-
- /* public */
- HRESULT ProfilerCallback::UnmanagedToManagedTransition( FunctionID functionID,
- COR_PRF_TRANSITION_REASON reason )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
-
- if ( m_traceEvent && reason == COR_PRF_TRANSITION_RETURN )
- {
- LogToAny("UnmanagedToManagedTransition: FunctionID=0x%p\n", functionID);
- }
-
- return S_OK;
-
- } // ProfilerCallback::UnmanagedToManagedTransition
-
-
-
- /* public */
- HRESULT ProfilerCallback::ManagedToUnmanagedTransition( FunctionID functionID,
- COR_PRF_TRANSITION_REASON reason )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
-
- if ( m_traceEvent && reason == COR_PRF_TRANSITION_CALL )
- {
- LogToAny("ManagedToUnmanagedTransition: FunctiondID=0x%p\n", functionID);
- }
- return S_OK;
-
- } // ProfilerCallback::ManagedToUnmanagedTransition
-
- HRESULT ProfilerCallback::ObjectAllocated( ObjectID objectID,
- ClassID classID )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
- if(m_traceEvent) {
- LogToAny("ObjectAllocated: ObjectID=0x%p, ClassID=0x%p\n", objectID, classID);
- }
-
- return S_OK;
-
- } // ProfilerCallback::ObjectAllocated
-
-
-
- /* public */
- HRESULT ProfilerCallback::ObjectReferences( ObjectID objectID,
- ClassID classID,
- ULONG objectRefs,
- ObjectID objectRefIDs[] )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
-
- if(m_traceEvent) {
- LogToAny("ObjectReferences: ObjectID=0x%p, ClassID=0x%p", objectID, classID);
- }
- return S_OK;
-
- } // ProfilerCallback::ObjectReferences
-
-
-
- /* public */
- HRESULT ProfilerCallback::RootReferences( ULONG rootRefs,
- ObjectID rootRefIDs[] )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
-
- if(m_traceEvent) {
- LogToAny("RootReferences: 0x%p\n", rootRefs);
- }
- return S_OK;
-
- } // ProfilerCallback::RootReferences
-
-
-
- /* public */
- HRESULT ProfilerCallback::RuntimeSuspendStarted( COR_PRF_SUSPEND_REASON suspendReason )
- {
- ///////////////////////////////////////////////////////////////////////////
- Synchronize guard( g_pCallbackObject->m_criticalSection );
- ///////////////////////////////////////////////////////////////////////////
-
- //if we are shutting down , terminate all the threads
- if ( suspendReason == COR_PRF_SUSPEND_FOR_SHUTDOWN )
- {
- m_bShutdown = TRUE;
- }
-
- if(m_traceEvent) {
- LogToAny("RuntimeSuspendStarted: %d\n", suspendReason);
- }
- return S_OK;
-
- } // ProfilerCallback::RuntimeSuspendStarted
-
-
-
- /* public */
- HRESULT ProfilerCallback::RuntimeResumeFinished()
- {
- //////////////////////////////////////////////////////////…
Large files files are truncated, but you can click here to view the full file