Browse Source

Added option to disable event tracking (IL rewriting) in profiler; workaround for cases like http://community.sharpdevelop.net/forums/t/11725.aspx

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6446 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Siegfried Pammer 16 years ago
parent
commit
7b48e5f8bb
  1. 1
      src/AddIns/Analysis/Profiler/Controller/Profiler.cs
  2. 14
      src/AddIns/Analysis/Profiler/Controller/ProfilerOptions.cs
  3. 1
      src/AddIns/Analysis/Profiler/Controller/structs.cs
  4. 4
      src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/OptionPanels/General.xaml
  5. 6
      src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/OptionPanels/OptionWrapper.cs
  6. 1
      src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/ProfilerRunner.cs
  7. 119
      src/AddIns/Analysis/Profiler/Hook/Profiler.cpp
  8. 1
      src/AddIns/Analysis/Profiler/Hook/SharedMemory.h

1
src/AddIns/Analysis/Profiler/Controller/Profiler.cs

@ -302,6 +302,7 @@ namespace ICSharpCode.Profiler.Controller
memHeader32->ProcessorFrequency = GetProcessorFrequency(); memHeader32->ProcessorFrequency = GetProcessorFrequency();
memHeader32->DoNotProfileDotnetInternals = profilerOptions.DoNotProfileDotNetInternals; memHeader32->DoNotProfileDotnetInternals = profilerOptions.DoNotProfileDotNetInternals;
memHeader32->CombineRecursiveFunction = profilerOptions.CombineRecursiveFunction; memHeader32->CombineRecursiveFunction = profilerOptions.CombineRecursiveFunction;
memHeader32->TrackEvents = profilerOptions.TrackEvents;
if ((Int32)(fullView.Pointer + memHeader32->HeapOffset) % 8 != 0) { if ((Int32)(fullView.Pointer + memHeader32->HeapOffset) % 8 != 0) {
throw new DataMisalignedException("Heap is not aligned properly: " + ((Int32)(fullView.Pointer + memHeader32->HeapOffset)).ToString(CultureInfo.InvariantCulture) + "!"); throw new DataMisalignedException("Heap is not aligned properly: " + ((Int32)(fullView.Pointer + memHeader32->HeapOffset)).ToString(CultureInfo.InvariantCulture) + "!");

14
src/AddIns/Analysis/Profiler/Controller/ProfilerOptions.cs

@ -36,6 +36,7 @@ namespace ICSharpCode.Profiler.Controller
bool enableDCAtStart; bool enableDCAtStart;
bool dotNotProfileDotNetInternals; bool dotNotProfileDotNetInternals;
bool combineRecursiveFunction; bool combineRecursiveFunction;
bool trackEvents;
int sharedMemorySize; int sharedMemorySize;
PerformanceCounterDescriptor[] counters; PerformanceCounterDescriptor[] counters;
@ -82,17 +83,26 @@ namespace ICSharpCode.Profiler.Controller
get { return sharedMemorySize; } get { return sharedMemorySize; }
} }
/// <summary>
/// Gets whether events should be tracked or not.
/// </summary>
public bool TrackEvents {
get { return trackEvents; }
}
/// <summary> /// <summary>
/// Creates new ProfilerOptions using the selected settings. /// Creates new ProfilerOptions using the selected settings.
/// </summary> /// </summary>
public ProfilerOptions(bool enableDC, int sharedMemorySize, bool profileDotNetInternals, public ProfilerOptions(bool enableDC, int sharedMemorySize, bool profileDotNetInternals,
bool combineRecursiveFunction, bool enableDCAtStart, IEnumerable<PerformanceCounterDescriptor> counters) bool combineRecursiveFunction, bool enableDCAtStart, bool trackEvents,
IEnumerable<PerformanceCounterDescriptor> counters)
{ {
this.enableDC = enableDC; this.enableDC = enableDC;
this.sharedMemorySize = sharedMemorySize; this.sharedMemorySize = sharedMemorySize;
this.dotNotProfileDotNetInternals = profileDotNetInternals; this.dotNotProfileDotNetInternals = profileDotNetInternals;
this.combineRecursiveFunction = combineRecursiveFunction; this.combineRecursiveFunction = combineRecursiveFunction;
this.enableDCAtStart = enableDCAtStart; this.enableDCAtStart = enableDCAtStart;
this.trackEvents = trackEvents;
this.counters = counters.ToArray(); this.counters = counters.ToArray();
} }
@ -100,7 +110,7 @@ namespace ICSharpCode.Profiler.Controller
/// Creates default ProfilerOptions. /// Creates default ProfilerOptions.
/// </summary> /// </summary>
public ProfilerOptions() public ProfilerOptions()
: this(true, DefaultSharedMemorySize, false, false, true, DefaultCounters) : this(true, DefaultSharedMemorySize, false, false, true, true, DefaultCounters)
{ {
} }
} }

1
src/AddIns/Analysis/Profiler/Controller/structs.cs

@ -32,6 +32,7 @@ namespace ICSharpCode.Profiler.Controller
public int ProcessorFrequency; public int ProcessorFrequency;
public bool DoNotProfileDotnetInternals; public bool DoNotProfileDotnetInternals;
public bool CombineRecursiveFunction; public bool CombineRecursiveFunction;
public bool TrackEvents;
public Allocator32 Allocator; public Allocator32 Allocator;
} }

4
src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/OptionPanels/General.xaml

@ -23,6 +23,10 @@
IsChecked="{sd:OptionBinding addin:OptionWrapper.EnableDCAtStart}" IsChecked="{sd:OptionBinding addin:OptionWrapper.EnableDCAtStart}"
VerticalAlignment="Top" VerticalAlignment="Top"
Content="{sd:Localize AddIns.Profiler.Options.General.DataCollection.EnableDCAtStartup}" /> Content="{sd:Localize AddIns.Profiler.Options.General.DataCollection.EnableDCAtStartup}" />
<CheckBox
IsChecked="{sd:OptionBinding addin:OptionWrapper.TrackEvents}"
VerticalAlignment="Top"
Content="{sd:Localize AddIns.Profiler.Options.General.DataCollection.TrackEvents}" />
<Label <Label
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Top" VerticalAlignment="Top"

6
src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/OptionPanels/OptionWrapper.cs

@ -41,6 +41,11 @@ namespace ICSharpCode.Profiler.AddIn.OptionPanels
set { properties.Set("EnableDCAtStart", value); } set { properties.Set("EnableDCAtStart", value); }
} }
public static bool TrackEvents {
get { return properties.Get("TrackEvents", true); }
set { properties.Set("TrackEvents", value); }
}
public static ProfilerOptions CreateProfilerOptions() public static ProfilerOptions CreateProfilerOptions()
{ {
return new ProfilerOptions( return new ProfilerOptions(
@ -49,6 +54,7 @@ namespace ICSharpCode.Profiler.AddIn.OptionPanels
properties.Get("DoNotProfileNetInternals", false), properties.Get("DoNotProfileNetInternals", false),
properties.Get("CombineRecursiveFunction", false), properties.Get("CombineRecursiveFunction", false),
properties.Get("EnableDCAtStart", true), properties.Get("EnableDCAtStart", true),
properties.Get("TrackEvents", true),
ProfilerOptions.DefaultCounters ProfilerOptions.DefaultCounters
); );
} }

1
src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/ProfilerRunner.cs

@ -76,6 +76,7 @@ namespace ICSharpCode.Profiler.AddIn
LoggingService.Info("Combine recursive calls: " + options.CombineRecursiveFunction); LoggingService.Info("Combine recursive calls: " + options.CombineRecursiveFunction);
LoggingService.Info("Enable DC: " + options.EnableDC); LoggingService.Info("Enable DC: " + options.EnableDC);
LoggingService.Info("Profile .NET internals: " + (!options.DoNotProfileDotNetInternals)); LoggingService.Info("Profile .NET internals: " + (!options.DoNotProfileDotNetInternals));
LoggingService.Info("Track events: " + options.TrackEvents);
} }
void FinishSession() void FinishSession()

119
src/AddIns/Analysis/Profiler/Hook/Profiler.cpp

@ -18,18 +18,15 @@
#include <intrin.h> #include <intrin.h>
#include "ProfilerMetaData.h" #include "ProfilerMetaData.h"
STDMETHODIMP_(ULONG) CProfiler::AddRef() STDMETHODIMP_(ULONG) CProfiler::AddRef() {
{
return 1; return 1;
} }
STDMETHODIMP_(ULONG) CProfiler::Release() STDMETHODIMP_(ULONG) CProfiler::Release() {
{
return 1; return 1;
} }
HRESULT CProfiler::QueryInterface(const IID &riid, LPVOID *ppv) HRESULT CProfiler::QueryInterface(const IID &riid, LPVOID *ppv) {
{
*ppv = nullptr; *ppv = nullptr;
if(IsEqualIID(riid, IID_IUnknown) || if(IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_ICorProfilerCallback) || IsEqualIID(riid, IID_ICorProfilerCallback) ||
@ -44,8 +41,7 @@ HRESULT CProfiler::QueryInterface(const IID &riid, LPVOID *ppv)
// ---- CALLBACK FUNCTIONS ------------------ // ---- CALLBACK FUNCTIONS ------------------
__declspec(noinline) void FunctionEnterCreateNewRoot(ThreadLocalData *data, const ULONGLONG &tsc) __declspec(noinline) void FunctionEnterCreateNewRoot(ThreadLocalData *data, const ULONGLONG &tsc) {
{
DebugWriteLine(L"Creating new root"); DebugWriteLine(L"Creating new root");
// first function call on this thread // first function call on this thread
// create a new root node for this thread // create a new root node for this thread
@ -53,8 +49,7 @@ __declspec(noinline) void FunctionEnterCreateNewRoot(ThreadLocalData *data, cons
DebugWriteLine(L"Created new root"); DebugWriteLine(L"Created new root");
} }
void CProfiler::EnterLock(ThreadLocalData *data) void CProfiler::EnterLock(ThreadLocalData *data) {
{
data->inLock = 1; data->inLock = 1;
_ReadWriteBarrier(); _mm_mfence(); _ReadWriteBarrier(); _mm_mfence();
@ -67,8 +62,7 @@ void CProfiler::EnterLock(ThreadLocalData *data)
} }
} }
ASSEMBLER_CALLBACK FunctionEnterGlobal(int functionID) ASSEMBLER_CALLBACK FunctionEnterGlobal(int functionID) {
{
ThreadLocalData *data = getThreadLocalData(); ThreadLocalData *data = getThreadLocalData();
if (data == nullptr) { if (data == nullptr) {
@ -116,8 +110,7 @@ EXIT:
data->inLock = 0; data->inLock = 0;
} }
void DetachFromThread(ThreadLocalData *data) void DetachFromThread(ThreadLocalData *data) {
{
if (data != nullptr) { if (data != nullptr) {
DebugWriteLine(L"DetachFromThread %d", data->threadID); DebugWriteLine(L"DetachFromThread %d", data->threadID);
ULONGLONG tsc = __rdtsc(); ULONGLONG tsc = __rdtsc();
@ -129,8 +122,7 @@ void DetachFromThread(ThreadLocalData *data)
} }
} }
ASSEMBLER_CALLBACK FunctionLeaveGlobal() ASSEMBLER_CALLBACK FunctionLeaveGlobal() {
{
ThreadLocalData *data = getThreadLocalData(); ThreadLocalData *data = getThreadLocalData();
profiler.EnterLock(data); profiler.EnterLock(data);
@ -154,8 +146,7 @@ EXIT:
data->inLock = 0; data->inLock = 0;
} }
ASSEMBLER_CALLBACK FunctionTailcallGlobal() ASSEMBLER_CALLBACK FunctionTailcallGlobal() {
{
DebugWriteLine(L"FunctionTailcallGlobal"); DebugWriteLine(L"FunctionTailcallGlobal");
// handle tail calls A->B as leave A, enter B, ... // handle tail calls A->B as leave A, enter B, ...
FunctionLeaveGlobal(); FunctionLeaveGlobal();
@ -180,13 +171,11 @@ int getNewPosFunctionID() {
} }
// this function is called by the CLR when a function has been mapped to an ID // this function is called by the CLR when a function has been mapped to an ID
UINT_PTR CProfiler::FunctionMapper(FunctionID functionID, BOOL *) UINT_PTR CProfiler::FunctionMapper(FunctionID functionID, BOOL *) {
{
return profiler.MapFunction(functionID, nullptr); return profiler.MapFunction(functionID, nullptr);
} }
UINT_PTR CProfiler::MapFunction(FunctionID functionID, const WCHAR **sigOutput) UINT_PTR CProfiler::MapFunction(FunctionID functionID, const WCHAR **sigOutput) {
{
mapFunctionCriticalSection.Enter(); mapFunctionCriticalSection.Enter();
int clientData = 0; int clientData = 0;
@ -233,15 +222,13 @@ FunctionInfo *CProfiler::CreateNewRoot() {
return newThreadRoot; return newThreadRoot;
} }
void CProfiler::MovedRootChild(FunctionInfo *newRootChild) void CProfiler::MovedRootChild(FunctionInfo *newRootChild) {
{
rootElementCriticalSection.Enter(); rootElementCriticalSection.Enter();
sharedMemoryHeader->RootFuncInfo->AddOrUpdateChild(newRootChild); sharedMemoryHeader->RootFuncInfo->AddOrUpdateChild(newRootChild);
rootElementCriticalSection.Leave(); rootElementCriticalSection.Leave();
} }
CProfiler::CProfiler() CProfiler::CProfiler() {
{
this->pICorProfilerInfo = nullptr; this->pICorProfilerInfo = nullptr;
this->pICorProfilerInfo2 = nullptr; this->pICorProfilerInfo2 = nullptr;
this->sigReader = nullptr; this->sigReader = nullptr;
@ -250,8 +237,7 @@ CProfiler::CProfiler()
// ---- ICorProfilerCallback IMPLEMENTATION ------------------ // ---- ICorProfilerCallback IMPLEMENTATION ------------------
// called when the profiling object is created by the CLR // called when the profiling object is created by the CLR
STDMETHODIMP CProfiler::Initialize(IUnknown *pICorProfilerInfoUnk) STDMETHODIMP CProfiler::Initialize(IUnknown *pICorProfilerInfoUnk) {
{
#ifdef DEBUG #ifdef DEBUG
MessageBox(nullptr, TEXT("CProfiler::Initialize - Attach debugger now!"), TEXT("Attach debugger"), MB_OK); MessageBox(nullptr, TEXT("CProfiler::Initialize - Attach debugger now!"), TEXT("Attach debugger"), MB_OK);
//__debugbreak(); //__debugbreak();
@ -305,15 +291,13 @@ STDMETHODIMP CProfiler::Initialize(IUnknown *pICorProfilerInfoUnk)
} }
// called when the profiler is being terminated by the CLR // called when the profiler is being terminated by the CLR
STDMETHODIMP CProfiler::Shutdown() STDMETHODIMP CProfiler::Shutdown() {
{
LogString(L"Shutdown..."); LogString(L"Shutdown...");
return S_OK; return S_OK;
} }
int CProfiler::InitializeCommunication() int CProfiler::InitializeCommunication() {
{
DebugWriteLine(L"Looking for Shared Memory..."); DebugWriteLine(L"Looking for Shared Memory...");
TCHAR sharedMemName[68]; TCHAR sharedMemName[68];
memset(sharedMemName, 0, sizeof(sharedMemName)); memset(sharedMemName, 0, sizeof(sharedMemName));
@ -379,8 +363,7 @@ int CProfiler::InitializeCommunication()
} }
// Writes a string to the log file. Uses the same calling convention as printf. // Writes a string to the log file. Uses the same calling convention as printf.
void CProfiler::LogString(WCHAR *pszFmtString, ...) void CProfiler::LogString(WCHAR *pszFmtString, ...) {
{
WCHAR szBuffer[2 * 4096]; WCHAR szBuffer[2 * 4096];
va_list args; va_list args;
@ -394,18 +377,17 @@ void CProfiler::LogString(WCHAR *pszFmtString, ...)
nativeToManagedCriticalSection.Leave(); nativeToManagedCriticalSection.Leave();
} }
HRESULT CProfiler::SetEventMask() HRESULT CProfiler::SetEventMask() {
{
DWORD eventMask = COR_PRF_MONITOR_ENTERLEAVE | COR_PRF_MONITOR_THREADS | DWORD eventMask = COR_PRF_MONITOR_ENTERLEAVE | COR_PRF_MONITOR_THREADS |
COR_PRF_MONITOR_FUNCTION_UNLOADS | COR_PRF_MONITOR_CLR_EXCEPTIONS | COR_PRF_MONITOR_FUNCTION_UNLOADS | COR_PRF_MONITOR_CLR_EXCEPTIONS |
COR_PRF_MONITOR_EXCEPTIONS | COR_PRF_MONITOR_JIT_COMPILATION | COR_PRF_MONITOR_EXCEPTIONS;
COR_PRF_MONITOR_MODULE_LOADS; if (sharedMemoryHeader->trackEvents)
eventMask = eventMask | COR_PRF_MONITOR_MODULE_LOADS/* | COR_PRF_MONITOR_JIT_COMPILATION*/;
return pICorProfilerInfo->SetEventMask(eventMask); return pICorProfilerInfo->SetEventMask(eventMask);
} }
// THREAD CALLBACK FUNCTIONS // THREAD CALLBACK FUNCTIONS
STDMETHODIMP CProfiler::ThreadAssignedToOSThread(ThreadID managedThreadID, DWORD osThreadID) STDMETHODIMP CProfiler::ThreadAssignedToOSThread(ThreadID managedThreadID, DWORD osThreadID) {
{
this->threadMapCriticalSection.Enter(); this->threadMapCriticalSection.Enter();
DebugWriteLine(L"ThreadAssignedToOSThread %d, %d", managedThreadID, osThreadID); DebugWriteLine(L"ThreadAssignedToOSThread %d, %d", managedThreadID, osThreadID);
@ -429,8 +411,7 @@ STDMETHODIMP CProfiler::ThreadAssignedToOSThread(ThreadID managedThreadID, DWORD
return S_OK; return S_OK;
} }
STDMETHODIMP CProfiler::ThreadNameChanged(ThreadID threadID, ULONG cchName, WCHAR name[]) STDMETHODIMP CProfiler::ThreadNameChanged(ThreadID threadID, ULONG cchName, WCHAR name[]) {
{
this->threadMapCriticalSection.Enter(); this->threadMapCriticalSection.Enter();
DebugWriteLine(L"ThreadNameChanged %d, %s", threadID, name); DebugWriteLine(L"ThreadNameChanged %d, %s", threadID, name);
@ -459,8 +440,7 @@ STDMETHODIMP CProfiler::ThreadNameChanged(ThreadID threadID, ULONG cchName, WCHA
} }
// UNLOAD CALLBACK FUNCTIONS // UNLOAD CALLBACK FUNCTIONS
STDMETHODIMP CProfiler::FunctionUnloadStarted(FunctionID functionID) STDMETHODIMP CProfiler::FunctionUnloadStarted(FunctionID functionID) {
{
mapFunctionCriticalSection.Enter(); mapFunctionCriticalSection.Enter();
DebugWriteLine(L"FunctionUnloadStarted %d", functionID); DebugWriteLine(L"FunctionUnloadStarted %d", functionID);
@ -469,8 +449,7 @@ STDMETHODIMP CProfiler::FunctionUnloadStarted(FunctionID functionID)
return S_OK; return S_OK;
} }
STDMETHODIMP CProfiler::ThreadCreated(ThreadID threadID) STDMETHODIMP CProfiler::ThreadCreated(ThreadID threadID) {
{
this->threadMapCriticalSection.Enter(); this->threadMapCriticalSection.Enter();
DebugWriteLine(L"ThreadCreated %d", threadID); DebugWriteLine(L"ThreadCreated %d", threadID);
@ -490,8 +469,7 @@ STDMETHODIMP CProfiler::ThreadCreated(ThreadID threadID)
return S_OK; return S_OK;
} }
STDMETHODIMP CProfiler::ThreadDestroyed(ThreadID threadID) STDMETHODIMP CProfiler::ThreadDestroyed(ThreadID threadID) {
{
this->threadMapCriticalSection.Enter(); this->threadMapCriticalSection.Enter();
DebugWriteLine(L"ThreadDestroyed %d", threadID); DebugWriteLine(L"ThreadDestroyed %d", threadID);
@ -510,24 +488,24 @@ STDMETHODIMP CProfiler::ThreadDestroyed(ThreadID threadID)
return S_OK; return S_OK;
} }
STDMETHODIMP CProfiler::ExceptionThrown(ObjectID) STDMETHODIMP CProfiler::ExceptionThrown(ObjectID) {
{
DebugWriteLine(L"ExceptionThrown"); DebugWriteLine(L"ExceptionThrown");
return S_OK; return S_OK;
} }
STDMETHODIMP CProfiler::ExceptionUnwindFunctionLeave() STDMETHODIMP CProfiler::ExceptionUnwindFunctionLeave() {
{
DebugWriteLine(L"ExceptionUnwindFunctionLeave"); DebugWriteLine(L"ExceptionUnwindFunctionLeave");
FunctionLeaveGlobal(); FunctionLeaveGlobal();
return S_OK; return S_OK;
} }
STDMETHODIMP CProfiler::JITCompilationStarted(FunctionID functionID, BOOL /*fIsSafeToBlock*/) STDMETHODIMP CProfiler::JITCompilationStarted(FunctionID functionID, BOOL /*fIsSafeToBlock*/) {
{
WCHAR *name; WCHAR *name;
int nameId = (int)MapFunction(functionID, (const WCHAR **)(&name)); int nameId = (int)MapFunction(functionID, (const WCHAR **)(&name));
if (name == nullptr)
return S_OK;
for (int i = 0; i < CONSOLE_GROUP_LENGTH; i++) { for (int i = 0; i < CONSOLE_GROUP_LENGTH; i++) {
if (wcsstr(consoleGroupList[i], name) != nullptr) if (wcsstr(consoleGroupList[i], name) != nullptr)
Rewrite(functionID, 0x1, nameId); Rewrite(functionID, 0x1, nameId);
@ -546,14 +524,12 @@ STDMETHODIMP CProfiler::JITCompilationStarted(FunctionID functionID, BOOL /*fIsS
return S_OK; return S_OK;
} }
void CProfiler::Activate() void CProfiler::Activate() {
{
ThreadLocalData *data = getThreadLocalData(); ThreadLocalData *data = getThreadLocalData();
data->active = true; data->active = true;
} }
void CProfiler::Deactivate() void CProfiler::Deactivate() {
{
ThreadLocalData *data = getThreadLocalData(); ThreadLocalData *data = getThreadLocalData();
data->active = false; data->active = false;
} }
@ -563,8 +539,7 @@ const ULONG TINY_HEADER_SIZE = 0x1; /* 1 byte */
const ULONG MAX_CODE_SIZE_TINY = 0x40; /* 64 bytes */ const ULONG MAX_CODE_SIZE_TINY = 0x40; /* 64 bytes */
const WORD DEFAULT_MAX_STACK = 0x8; /* default stack depth in slots */ const WORD DEFAULT_MAX_STACK = 0x8; /* default stack depth in slots */
void CProfiler::Rewrite(FunctionID functionID, int type, int nameId) void CProfiler::Rewrite(FunctionID functionID, int type, int nameId) {
{
ModuleID moduleID; ModuleID moduleID;
mdToken token; mdToken token;
HRESULT hr = S_OK; HRESULT hr = S_OK;
@ -715,8 +690,7 @@ void CProfiler::Rewrite(FunctionID functionID, int type, int nameId)
int CProfiler::SetInjectionCode(IMetaDataImport *metaData, byte *buffer, int *size, int CProfiler::SetInjectionCode(IMetaDataImport *metaData, byte *buffer, int *size,
mdMethodDef activateCall, mdMethodDef loggerCall, mdMethodDef deactivateCall, mdMethodDef activateCall, mdMethodDef loggerCall, mdMethodDef deactivateCall,
int type, int nameId) int type, int nameId) {
{
HRESULT hr = S_OK; HRESULT hr = S_OK;
int start = *size; int start = *size;
@ -797,8 +771,7 @@ int CProfiler::SetInjectionCode(IMetaDataImport *metaData, byte *buffer, int *si
return *size - start; return *size - start;
} }
void CProfiler::ConvertToFat(byte *target, int *size) void CProfiler::ConvertToFat(byte *target, int *size) {
{
COR_ILMETHOD_FAT *targetTable = (COR_ILMETHOD_FAT *)target; COR_ILMETHOD_FAT *targetTable = (COR_ILMETHOD_FAT *)target;
memset(targetTable, 0, FAT_HEADER_SIZE); memset(targetTable, 0, FAT_HEADER_SIZE);
targetTable->Flags = CorILMethod_FatFormat; targetTable->Flags = CorILMethod_FatFormat;
@ -810,8 +783,7 @@ void CProfiler::ConvertToFat(byte *target, int *size)
/// <summary> /// <summary>
/// Moves all offsets in SEH section tables by the given count of bytes. /// Moves all offsets in SEH section tables by the given count of bytes.
/// </summary> /// </summary>
void CProfiler::FixSEHSections(const COR_ILMETHOD_SECT *sections, int offset) void CProfiler::FixSEHSections(const COR_ILMETHOD_SECT *sections, int offset) {
{
while (sections) { while (sections) {
if (sections->Kind() == CorILMethod_Sect_EHTable) { if (sections->Kind() == CorILMethod_Sect_EHTable) {
COR_ILMETHOD_SECT_EH *peh = (COR_ILMETHOD_SECT_EH *) sections; COR_ILMETHOD_SECT_EH *peh = (COR_ILMETHOD_SECT_EH *) sections;
@ -845,8 +817,7 @@ void CProfiler::FixSEHSections(const COR_ILMETHOD_SECT *sections, int offset)
} }
} }
bool CProfiler::CreateMethod(IMetaDataEmit *emitter, const WCHAR *name, PCCOR_SIGNATURE sig, mdMethodDef *methodDefinition, mdToken moduleRef) bool CProfiler::CreateMethod(IMetaDataEmit *emitter, const WCHAR *name, PCCOR_SIGNATURE sig, mdMethodDef *methodDefinition, mdToken moduleRef) {
{
HRESULT hr = emitter->DefineMethod(mdTokenNil, name, mdPublic | mdStatic | mdPinvokeImpl, sig, sizeof(sig), 0, miIL | miManaged, methodDefinition); HRESULT hr = emitter->DefineMethod(mdTokenNil, name, mdPublic | mdStatic | mdPinvokeImpl, sig, sizeof(sig), 0, miIL | miManaged, methodDefinition);
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
@ -860,8 +831,7 @@ bool CProfiler::CreateMethod(IMetaDataEmit *emitter, const WCHAR *name, PCCOR_SI
return true; return true;
} }
STDMETHODIMP CProfiler::ModuleLoadFinished(ModuleID moduleID, HRESULT /*hrStatus*/) STDMETHODIMP CProfiler::ModuleLoadFinished(ModuleID moduleID, HRESULT /*hrStatus*/) {
{
HRESULT hr = S_OK; HRESULT hr = S_OK;
IMetaDataEmit *pIMetaDataEmit = nullptr; IMetaDataEmit *pIMetaDataEmit = nullptr;
@ -890,7 +860,7 @@ STDMETHODIMP CProfiler::ModuleLoadFinished(ModuleID moduleID, HRESULT /*hrStatus
mdMethodDef activator; mdMethodDef activator;
if (!CreateMethod(pIMetaDataEmit, L"ActivateProfiler", rgSig, &activator, moduleRef)) if (!CreateMethod(pIMetaDataEmit, L"ActivateProfiler", rgSig, &activator, moduleRef))
goto CLEANUP; goto CLEANUP;
mdMethodDef logger; mdMethodDef logger;
hr = pIMetaDataEmit->DefineMethod(mdTokenNil, L"LogEvent", mdPublic | mdStatic | mdPinvokeImpl, loggerSig, sizeof(loggerSig), 0, miIL | miManaged, &logger); hr = pIMetaDataEmit->DefineMethod(mdTokenNil, L"LogEvent", mdPublic | mdStatic | mdPinvokeImpl, loggerSig, sizeof(loggerSig), 0, miIL | miManaged, &logger);
@ -912,6 +882,13 @@ STDMETHODIMP CProfiler::ModuleLoadFinished(ModuleID moduleID, HRESULT /*hrStatus
} }
CLEANUP: CLEANUP:
#ifdef DEBUG
if (!SUCCEEDED(hr)) {
MessageBox(nullptr, TEXT("Crashed in ModuleLoadFinished"), TEXT("Crash!"), MB_OK);
__debugbreak();
}
#endif
if (pIMetaDataEmit != nullptr) if (pIMetaDataEmit != nullptr)
pIMetaDataEmit->Release(); pIMetaDataEmit->Release();

1
src/AddIns/Analysis/Profiler/Hook/SharedMemory.h

@ -28,6 +28,7 @@ struct SharedMemoryHeader
int ProcFrequency; int ProcFrequency;
bool doNotProfileDotnetInternals; bool doNotProfileDotnetInternals;
bool combineRecursiveFunction; bool combineRecursiveFunction;
bool trackEvents;
freeListAllocator<FunctionInfoAllocationSize> mallocator; freeListAllocator<FunctionInfoAllocationSize> mallocator;
}; };

Loading…
Cancel
Save