From 7b48e5f8bbffc2328b525485c8820105e371a7d6 Mon Sep 17 00:00:00 2001
From: Siegfried Pammer <siegfriedpammer@gmail.com>
Date: Thu, 26 Aug 2010 20:26:24 +0000
Subject: [PATCH] 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
---
 .../Analysis/Profiler/Controller/Profiler.cs  |   1 +
 .../Profiler/Controller/ProfilerOptions.cs    |  14 ++-
 .../Analysis/Profiler/Controller/structs.cs   |   1 +
 .../AddIn/Src/OptionPanels/General.xaml       |   4 +
 .../AddIn/Src/OptionPanels/OptionWrapper.cs   |   6 +
 .../Frontend/AddIn/Src/ProfilerRunner.cs      |   1 +
 .../Analysis/Profiler/Hook/Profiler.cpp       | 119 +++++++-----------
 .../Analysis/Profiler/Hook/SharedMemory.h     |   1 +
 8 files changed, 74 insertions(+), 73 deletions(-)

diff --git a/src/AddIns/Analysis/Profiler/Controller/Profiler.cs b/src/AddIns/Analysis/Profiler/Controller/Profiler.cs
index b24f532749..a49cdc7801 100644
--- a/src/AddIns/Analysis/Profiler/Controller/Profiler.cs
+++ b/src/AddIns/Analysis/Profiler/Controller/Profiler.cs
@@ -302,6 +302,7 @@ namespace ICSharpCode.Profiler.Controller
 			memHeader32->ProcessorFrequency = GetProcessorFrequency();
 			memHeader32->DoNotProfileDotnetInternals = profilerOptions.DoNotProfileDotNetInternals;
 			memHeader32->CombineRecursiveFunction = profilerOptions.CombineRecursiveFunction;
+			memHeader32->TrackEvents = profilerOptions.TrackEvents;
 			
 			if ((Int32)(fullView.Pointer + memHeader32->HeapOffset) % 8 != 0) {
 				throw new DataMisalignedException("Heap is not aligned properly: " + ((Int32)(fullView.Pointer + memHeader32->HeapOffset)).ToString(CultureInfo.InvariantCulture) + "!");
diff --git a/src/AddIns/Analysis/Profiler/Controller/ProfilerOptions.cs b/src/AddIns/Analysis/Profiler/Controller/ProfilerOptions.cs
index 680b09a93e..532fd97171 100644
--- a/src/AddIns/Analysis/Profiler/Controller/ProfilerOptions.cs
+++ b/src/AddIns/Analysis/Profiler/Controller/ProfilerOptions.cs
@@ -36,6 +36,7 @@ namespace ICSharpCode.Profiler.Controller
 		bool enableDCAtStart;
 		bool dotNotProfileDotNetInternals;
 		bool combineRecursiveFunction;
+		bool trackEvents;
 		int sharedMemorySize;
 		
 		PerformanceCounterDescriptor[] counters;
@@ -82,17 +83,26 @@ namespace ICSharpCode.Profiler.Controller
 			get { return sharedMemorySize; }
 		}
 		
+		/// <summary>
+		/// Gets whether events should be tracked or not.
+		/// </summary>
+		public bool TrackEvents {
+			get { return trackEvents; }
+		}
+		
 		/// <summary>
 		/// Creates new ProfilerOptions using the selected settings.
 		/// </summary>
 		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.sharedMemorySize = sharedMemorySize;
 			this.dotNotProfileDotNetInternals = profileDotNetInternals;
 			this.combineRecursiveFunction = combineRecursiveFunction;
 			this.enableDCAtStart = enableDCAtStart;
+			this.trackEvents = trackEvents;
 			this.counters = counters.ToArray();
 		}
 		
@@ -100,7 +110,7 @@ namespace ICSharpCode.Profiler.Controller
 		/// Creates default ProfilerOptions.
 		/// </summary>
 		public ProfilerOptions()
-			: this(true, DefaultSharedMemorySize, false, false, true, DefaultCounters)
+			: this(true, DefaultSharedMemorySize, false, false, true, true, DefaultCounters)
 		{
 		}
 	}
diff --git a/src/AddIns/Analysis/Profiler/Controller/structs.cs b/src/AddIns/Analysis/Profiler/Controller/structs.cs
index b8e2805656..8b676398a8 100644
--- a/src/AddIns/Analysis/Profiler/Controller/structs.cs
+++ b/src/AddIns/Analysis/Profiler/Controller/structs.cs
@@ -32,6 +32,7 @@ namespace ICSharpCode.Profiler.Controller
 		public int ProcessorFrequency;
 		public bool DoNotProfileDotnetInternals;
 		public bool CombineRecursiveFunction;
+		public bool TrackEvents;
 		public Allocator32 Allocator;
 	}
 	
diff --git a/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/OptionPanels/General.xaml b/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/OptionPanels/General.xaml
index 54e442b2a8..afbfda50b0 100644
--- a/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/OptionPanels/General.xaml
+++ b/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/OptionPanels/General.xaml
@@ -23,6 +23,10 @@
 					IsChecked="{sd:OptionBinding addin:OptionWrapper.EnableDCAtStart}"
 					VerticalAlignment="Top"
 					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
 					HorizontalAlignment="Left"
 					VerticalAlignment="Top"
diff --git a/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/OptionPanels/OptionWrapper.cs b/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/OptionPanels/OptionWrapper.cs
index 461b0bbcdd..504071f3eb 100644
--- a/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/OptionPanels/OptionWrapper.cs
+++ b/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/OptionPanels/OptionWrapper.cs
@@ -41,6 +41,11 @@ namespace ICSharpCode.Profiler.AddIn.OptionPanels
 			set { properties.Set("EnableDCAtStart", value); }
 		}
 		
+		public static bool TrackEvents {
+			get { return properties.Get("TrackEvents", true); }
+			set { properties.Set("TrackEvents", value); }
+		}
+		
 		public static ProfilerOptions CreateProfilerOptions()
 		{
 			return new ProfilerOptions(
@@ -49,6 +54,7 @@ namespace ICSharpCode.Profiler.AddIn.OptionPanels
 				properties.Get("DoNotProfileNetInternals", false),
 				properties.Get("CombineRecursiveFunction", false),
 				properties.Get("EnableDCAtStart", true),
+				properties.Get("TrackEvents", true),
 				ProfilerOptions.DefaultCounters
 			);
 		}
diff --git a/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/ProfilerRunner.cs b/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/ProfilerRunner.cs
index 2aef446906..cb56792685 100644
--- a/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/ProfilerRunner.cs
+++ b/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("Enable DC: " + options.EnableDC);
 			LoggingService.Info("Profile .NET internals: " + (!options.DoNotProfileDotNetInternals));
+			LoggingService.Info("Track events: " + options.TrackEvents);
 		}
 		
 		void FinishSession()
diff --git a/src/AddIns/Analysis/Profiler/Hook/Profiler.cpp b/src/AddIns/Analysis/Profiler/Hook/Profiler.cpp
index 7ed0d5b61a..966d407073 100644
--- a/src/AddIns/Analysis/Profiler/Hook/Profiler.cpp
+++ b/src/AddIns/Analysis/Profiler/Hook/Profiler.cpp
@@ -18,18 +18,15 @@
 #include <intrin.h>
 #include "ProfilerMetaData.h"
 
-STDMETHODIMP_(ULONG) CProfiler::AddRef() 
-{
+STDMETHODIMP_(ULONG) CProfiler::AddRef() {
 	return 1;
 }
 
-STDMETHODIMP_(ULONG) CProfiler::Release() 
-{
+STDMETHODIMP_(ULONG) CProfiler::Release() {
 	return 1;
 }
 
-HRESULT CProfiler::QueryInterface(const IID &riid, LPVOID *ppv)
-{
+HRESULT CProfiler::QueryInterface(const IID &riid, LPVOID *ppv) {
   *ppv = nullptr;
   if(IsEqualIID(riid, IID_IUnknown) ||
 	 IsEqualIID(riid, IID_ICorProfilerCallback) ||
@@ -44,8 +41,7 @@ HRESULT CProfiler::QueryInterface(const IID &riid, LPVOID *ppv)
 
 // ----  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");
 	// first function call on 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");
 }
 
-void CProfiler::EnterLock(ThreadLocalData *data)
-{
+void CProfiler::EnterLock(ThreadLocalData *data) {
 	data->inLock = 1;
 	_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();
 	
 	if (data == nullptr) {
@@ -116,8 +110,7 @@ EXIT:
 	data->inLock = 0;
 }
 
-void DetachFromThread(ThreadLocalData *data)
-{
+void DetachFromThread(ThreadLocalData *data) {
 	if (data != nullptr) {
 		DebugWriteLine(L"DetachFromThread %d", data->threadID);
 		ULONGLONG tsc = __rdtsc();
@@ -129,8 +122,7 @@ void DetachFromThread(ThreadLocalData *data)
 	}
 }
 
-ASSEMBLER_CALLBACK FunctionLeaveGlobal()
-{
+ASSEMBLER_CALLBACK FunctionLeaveGlobal() {
 	ThreadLocalData *data = getThreadLocalData();
 
 	profiler.EnterLock(data);
@@ -154,8 +146,7 @@ EXIT:
 	data->inLock = 0;
 }
 
-ASSEMBLER_CALLBACK FunctionTailcallGlobal()
-{
+ASSEMBLER_CALLBACK FunctionTailcallGlobal() {
 	DebugWriteLine(L"FunctionTailcallGlobal");
 	// handle tail calls A->B as leave A, enter B, ...
 	FunctionLeaveGlobal();
@@ -180,13 +171,11 @@ int getNewPosFunctionID() {
 }
 
 // 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);
 }
 
-UINT_PTR CProfiler::MapFunction(FunctionID functionID, const WCHAR **sigOutput)
-{
+UINT_PTR CProfiler::MapFunction(FunctionID functionID, const WCHAR **sigOutput) {
 	mapFunctionCriticalSection.Enter();
 	int clientData = 0;
 	
@@ -233,15 +222,13 @@ FunctionInfo *CProfiler::CreateNewRoot() {
 	return newThreadRoot;
 }
 
-void CProfiler::MovedRootChild(FunctionInfo *newRootChild)
-{
+void CProfiler::MovedRootChild(FunctionInfo *newRootChild) {
 	rootElementCriticalSection.Enter();
 	sharedMemoryHeader->RootFuncInfo->AddOrUpdateChild(newRootChild);
 	rootElementCriticalSection.Leave();
 }
 
-CProfiler::CProfiler()
-{
+CProfiler::CProfiler() {
 	this->pICorProfilerInfo = nullptr;
 	this->pICorProfilerInfo2 = nullptr;
 	this->sigReader = nullptr;
@@ -250,8 +237,7 @@ CProfiler::CProfiler()
 // ----  ICorProfilerCallback IMPLEMENTATION ------------------
 
 // called when the profiling object is created by the CLR
-STDMETHODIMP CProfiler::Initialize(IUnknown *pICorProfilerInfoUnk)
-{
+STDMETHODIMP CProfiler::Initialize(IUnknown *pICorProfilerInfoUnk) {
 	#ifdef DEBUG
 	MessageBox(nullptr, TEXT("CProfiler::Initialize - Attach debugger now!"), TEXT("Attach debugger"), MB_OK);
 	//__debugbreak();
@@ -305,15 +291,13 @@ STDMETHODIMP CProfiler::Initialize(IUnknown *pICorProfilerInfoUnk)
 }
 
 // called when the profiler is being terminated by the CLR
-STDMETHODIMP CProfiler::Shutdown()
-{
+STDMETHODIMP CProfiler::Shutdown() {
 	LogString(L"Shutdown...");
 
     return S_OK;
 }
 
-int CProfiler::InitializeCommunication()
-{	
+int CProfiler::InitializeCommunication() {
 	DebugWriteLine(L"Looking for Shared Memory...");
 	TCHAR sharedMemName[68];
 	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.
-void CProfiler::LogString(WCHAR *pszFmtString, ...)
-{
+void CProfiler::LogString(WCHAR *pszFmtString, ...) {
 	WCHAR szBuffer[2 * 4096];
 
 	va_list args;
@@ -394,18 +377,17 @@ void CProfiler::LogString(WCHAR *pszFmtString, ...)
 	nativeToManagedCriticalSection.Leave();
 }
 
-HRESULT CProfiler::SetEventMask()
-{
+HRESULT CProfiler::SetEventMask() {
 	DWORD eventMask = COR_PRF_MONITOR_ENTERLEAVE | COR_PRF_MONITOR_THREADS | 
 		COR_PRF_MONITOR_FUNCTION_UNLOADS | COR_PRF_MONITOR_CLR_EXCEPTIONS |
-		COR_PRF_MONITOR_EXCEPTIONS | COR_PRF_MONITOR_JIT_COMPILATION |
-		COR_PRF_MONITOR_MODULE_LOADS;
+		COR_PRF_MONITOR_EXCEPTIONS;
+	if (sharedMemoryHeader->trackEvents)
+		eventMask = eventMask | COR_PRF_MONITOR_MODULE_LOADS/* | COR_PRF_MONITOR_JIT_COMPILATION*/;
 	return pICorProfilerInfo->SetEventMask(eventMask);
 }
 
 // THREAD CALLBACK FUNCTIONS
-STDMETHODIMP CProfiler::ThreadAssignedToOSThread(ThreadID managedThreadID, DWORD osThreadID)
-{
+STDMETHODIMP CProfiler::ThreadAssignedToOSThread(ThreadID managedThreadID, DWORD osThreadID) {
 	this->threadMapCriticalSection.Enter();
 	DebugWriteLine(L"ThreadAssignedToOSThread %d, %d", managedThreadID, osThreadID);
 	
@@ -429,8 +411,7 @@ STDMETHODIMP CProfiler::ThreadAssignedToOSThread(ThreadID managedThreadID, DWORD
 	return S_OK;
 }
 
-STDMETHODIMP CProfiler::ThreadNameChanged(ThreadID threadID, ULONG cchName, WCHAR name[])
-{
+STDMETHODIMP CProfiler::ThreadNameChanged(ThreadID threadID, ULONG cchName, WCHAR name[]) {
 	this->threadMapCriticalSection.Enter();
 	DebugWriteLine(L"ThreadNameChanged %d, %s", threadID, name);
 	
@@ -459,8 +440,7 @@ STDMETHODIMP CProfiler::ThreadNameChanged(ThreadID threadID, ULONG cchName, WCHA
 }
 
 // UNLOAD CALLBACK FUNCTIONS
-STDMETHODIMP CProfiler::FunctionUnloadStarted(FunctionID functionID)
-{
+STDMETHODIMP CProfiler::FunctionUnloadStarted(FunctionID functionID) {
 	mapFunctionCriticalSection.Enter();
 	DebugWriteLine(L"FunctionUnloadStarted %d", functionID);
 	
@@ -469,8 +449,7 @@ STDMETHODIMP CProfiler::FunctionUnloadStarted(FunctionID functionID)
     return S_OK;
 }
 
-STDMETHODIMP CProfiler::ThreadCreated(ThreadID threadID)
-{
+STDMETHODIMP CProfiler::ThreadCreated(ThreadID threadID) {
 	this->threadMapCriticalSection.Enter();
 	DebugWriteLine(L"ThreadCreated %d", threadID);
 	
@@ -490,8 +469,7 @@ STDMETHODIMP CProfiler::ThreadCreated(ThreadID threadID)
 	return S_OK;
 }
 
-STDMETHODIMP CProfiler::ThreadDestroyed(ThreadID threadID)
-{
+STDMETHODIMP CProfiler::ThreadDestroyed(ThreadID threadID) {
 	this->threadMapCriticalSection.Enter();
 	DebugWriteLine(L"ThreadDestroyed %d", threadID);
 	
@@ -510,24 +488,24 @@ STDMETHODIMP CProfiler::ThreadDestroyed(ThreadID threadID)
 	return S_OK;
 }
 
-STDMETHODIMP CProfiler::ExceptionThrown(ObjectID)
-{
+STDMETHODIMP CProfiler::ExceptionThrown(ObjectID) {
 	DebugWriteLine(L"ExceptionThrown");
     return S_OK;
 }
 
-STDMETHODIMP CProfiler::ExceptionUnwindFunctionLeave()
-{
+STDMETHODIMP CProfiler::ExceptionUnwindFunctionLeave() {
 	DebugWriteLine(L"ExceptionUnwindFunctionLeave");
 	FunctionLeaveGlobal();
     return S_OK;
 }
 
-STDMETHODIMP CProfiler::JITCompilationStarted(FunctionID functionID, BOOL /*fIsSafeToBlock*/)
-{
+STDMETHODIMP CProfiler::JITCompilationStarted(FunctionID functionID, BOOL /*fIsSafeToBlock*/) {
 	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++) {
 		if (wcsstr(consoleGroupList[i], name) != nullptr)
 			Rewrite(functionID, 0x1, nameId);
@@ -546,14 +524,12 @@ STDMETHODIMP CProfiler::JITCompilationStarted(FunctionID functionID, BOOL /*fIsS
 	return S_OK;
 }
 
-void CProfiler::Activate()
-{
+void CProfiler::Activate() {
 	ThreadLocalData *data = getThreadLocalData();
 	data->active = true;
 }
 
-void CProfiler::Deactivate()
-{
+void CProfiler::Deactivate() {
 	ThreadLocalData *data = getThreadLocalData();
 	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 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;
 	mdToken token;
 	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,
 									mdMethodDef activateCall, mdMethodDef loggerCall, mdMethodDef deactivateCall,
-									int type, int nameId)
-{
+									int type, int nameId) {
 	HRESULT hr = S_OK;
 	
 	int start = *size;
@@ -797,8 +771,7 @@ int CProfiler::SetInjectionCode(IMetaDataImport *metaData, byte *buffer, int *si
 	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;
     memset(targetTable, 0, FAT_HEADER_SIZE);
     targetTable->Flags = CorILMethod_FatFormat;
@@ -810,8 +783,7 @@ void CProfiler::ConvertToFat(byte *target, int *size)
 /// <summary>
 /// Moves all offsets in SEH section tables by the given count of bytes.
 /// </summary>
-void CProfiler::FixSEHSections(const COR_ILMETHOD_SECT *sections, int offset)
-{
+void CProfiler::FixSEHSections(const COR_ILMETHOD_SECT *sections, int offset) {
     while (sections) {
         if (sections->Kind() == CorILMethod_Sect_EHTable) {
             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);
 	
 	if (!SUCCEEDED(hr))
@@ -860,8 +831,7 @@ bool CProfiler::CreateMethod(IMetaDataEmit *emitter, const WCHAR *name, PCCOR_SI
 	return true;
 }
 
-STDMETHODIMP CProfiler::ModuleLoadFinished(ModuleID moduleID, HRESULT /*hrStatus*/)
-{
+STDMETHODIMP CProfiler::ModuleLoadFinished(ModuleID moduleID, HRESULT /*hrStatus*/) {
 	HRESULT hr = S_OK;
 	
 	IMetaDataEmit *pIMetaDataEmit = nullptr;
@@ -890,7 +860,7 @@ STDMETHODIMP CProfiler::ModuleLoadFinished(ModuleID moduleID, HRESULT /*hrStatus
 	mdMethodDef activator;
 	if (!CreateMethod(pIMetaDataEmit, L"ActivateProfiler", rgSig, &activator, moduleRef))
 		goto CLEANUP;
-		
+
 	mdMethodDef 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:
+	#ifdef DEBUG
+	if (!SUCCEEDED(hr)) {
+		MessageBox(nullptr, TEXT("Crashed in ModuleLoadFinished"), TEXT("Crash!"), MB_OK);
+		__debugbreak();
+	}
+	#endif
+	
 	if (pIMetaDataEmit != nullptr)
 		pIMetaDataEmit->Release();
 	
diff --git a/src/AddIns/Analysis/Profiler/Hook/SharedMemory.h b/src/AddIns/Analysis/Profiler/Hook/SharedMemory.h
index d0d30b882d..99b7eccf69 100644
--- a/src/AddIns/Analysis/Profiler/Hook/SharedMemory.h
+++ b/src/AddIns/Analysis/Profiler/Hook/SharedMemory.h
@@ -28,6 +28,7 @@ struct SharedMemoryHeader
 	int ProcFrequency;
 	bool doNotProfileDotnetInternals;
 	bool combineRecursiveFunction;
+	bool trackEvents;
 	freeListAllocator<FunctionInfoAllocationSize> mallocator;
 };