Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono-tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Mono.Profiler/profiler-decoder-library/Decoder.cs')
-rw-r--r--Mono.Profiler/profiler-decoder-library/Decoder.cs153
1 files changed, 153 insertions, 0 deletions
diff --git a/Mono.Profiler/profiler-decoder-library/Decoder.cs b/Mono.Profiler/profiler-decoder-library/Decoder.cs
index e6111fa7..1f5a4b3c 100644
--- a/Mono.Profiler/profiler-decoder-library/Decoder.cs
+++ b/Mono.Profiler/profiler-decoder-library/Decoder.cs
@@ -249,6 +249,7 @@ namespace Mono.Profiler {
GC_STOP_WORLD = 6,
GC_START_WORLD = 7,
JIT_TIME_ALLOCATION = 8,
+ STACK_SECTION = 9,
MASK = 15
}
GenericEvent GenericEventFromEventCode (int eventCode) {
@@ -296,11 +297,14 @@ namespace Mono.Profiler {
public void Decode<LC,LM,UFR,UFI,MR,EH,HO,HS> (IProfilerEventHandler<LC,LM,UFR,UFI,MR,EH,HO,HS> handler) where LC : ILoadedClass where LM : ILoadedMethod<LC> where UFR : IUnmanagedFunctionFromRegion where UFI : IUnmanagedFunctionFromID<MR,UFR> where MR : IExecutableMemoryRegion<UFR> where EH : ILoadedElementHandler<LC,LM,UFR,UFI,MR,HO,HS> where HO: IHeapObject<HO,LC> where HS: IHeapSnapshot<HO,LC> {
uint offsetInBlock = 0;
+ StackSectionElement<LC,LM>[] stackSection = new StackSectionElement<LC,LM> [32];
if (data == null) {
throw new DecodingException (this, 0, "Decoding used block");
}
+ handler.InitializeData (data, 0);
+
try {
//LogLine (" *** DECODING at offset {0} (code {1})", fileOffset, code);
switch (code) {
@@ -319,6 +323,7 @@ namespace Mono.Profiler {
//LogLine ("BLOCK INTRO: version {0}, runtimeFile {1}, flags {2}, startCounter {3}, startTime {4}", version, runtimeFile, (ProfilerFlags) flags, startCounter, startTime);
handler.Start (version, runtimeFile, (ProfilerFlags) flags, startCounter, microsecondsFromEpochToDateTime (startTime));
+ handler.DataProcessed (offsetInBlock);
break;
}
case BlockCode.END : {
@@ -332,6 +337,7 @@ namespace Mono.Profiler {
//LogLine ("BLOCK END: version {0}, endCounter {1}, endTime {2}", version, endCounter, endTime);
handler.End (version, endCounter, microsecondsFromEpochToDateTime (endTime));
+ handler.DataProcessed (offsetInBlock);
break;
}
case BlockCode.LOADED : {
@@ -348,14 +354,17 @@ namespace Mono.Profiler {
switch ((LoadedItemInfo) kind) {
case LoadedItemInfo.APPDOMAIN: {
handler.ApplicationDomainLoaded (threadId, startCounter, endCounter, itemName, success);
+ handler.DataProcessed (offsetInBlock);
break;
}
case LoadedItemInfo.ASSEMBLY: {
handler.AssemblyLoaded (threadId, startCounter, endCounter, itemName, success);
+ handler.DataProcessed (offsetInBlock);
break;
}
case LoadedItemInfo.MODULE: {
handler.ModuleLoaded (threadId, startCounter, endCounter, itemName, success);
+ handler.DataProcessed (offsetInBlock);
break;
}
default: {
@@ -376,14 +385,17 @@ namespace Mono.Profiler {
switch ((LoadedItemInfo) kind) {
case LoadedItemInfo.APPDOMAIN: {
handler.ApplicationDomainUnloaded (threadId, startCounter, endCounter, itemName);
+ handler.DataProcessed (offsetInBlock);
break;
}
case LoadedItemInfo.ASSEMBLY: {
handler.AssemblyUnloaded (threadId, startCounter, endCounter, itemName);
+ handler.DataProcessed (offsetInBlock);
break;
}
case LoadedItemInfo.MODULE: {
handler.ModuleUnloaded (threadId, startCounter, endCounter, itemName);
+ handler.DataProcessed (offsetInBlock);
break;
}
default: {
@@ -400,6 +412,7 @@ namespace Mono.Profiler {
//LogLine ("BLOCK MAPPING (START): startCounter {0}, startTime {1}, threadId {2}", startCounter, startTime, threadId);
handler.StartBlock (startCounter, microsecondsFromEpochToDateTime (startTime), threadId);
handler.SetCurrentThread (threadId);
+ handler.DataProcessed (offsetInBlock);
uint itemId;
for (itemId = ReadUint (ref offsetInBlock); itemId != 0; itemId = ReadUint (ref offsetInBlock)) {
@@ -420,6 +433,7 @@ namespace Mono.Profiler {
//LogLine ("BLOCK MAPPING (END): endCounter {0}, endTime {1}", endCounter, endTime);
handler.EndBlock (endCounter, microsecondsFromEpochToDateTime (endTime), threadId);
+ handler.DataProcessed (offsetInBlock);
break;
}
case BlockCode.EVENTS : {
@@ -430,6 +444,7 @@ namespace Mono.Profiler {
//LogLine ("BLOCK EVENTS (START): startCounter {0}, startTime {1}, threadId {2}", startCounter, startTime, threadId);
handler.StartBlock (startCounter, microsecondsFromEpochToDateTime (startTime), threadId);
handler.SetCurrentThread (threadId);
+ handler.DataProcessed (offsetInBlock);
ulong baseCounter = ReadUlong (ref offsetInBlock);
@@ -450,6 +465,7 @@ namespace Mono.Profiler {
}
//LogLine ("BLOCK EVENTS (PACKED:CLASS_ALLOCATION): classId {0}, classSize {1}, callerId {2}", classId, classSize, callerId);
handler.Allocation (handler.LoadedElements.GetClass (classId), classSize, (callerId != 0) ? handler.LoadedElements.GetMethod (callerId) : default (LM), false, 0);
+ handler.DataProcessed (offsetInBlock);
break;
}
case PackedEventCode.CLASS_EVENT: {
@@ -461,6 +477,7 @@ namespace Mono.Profiler {
baseCounter += counterDelta;
//LogLine ("BLOCK EVENTS (CLASS:EXCEPTION): classId {0}, counterDelta {1}", classId, counterDelta);
handler.Exception (handler.LoadedElements.GetClass (classId), baseCounter);
+ handler.DataProcessed (offsetInBlock);
break;
}
case ClassEvent.LOAD: {
@@ -471,8 +488,10 @@ namespace Mono.Profiler {
//LogLine ("BLOCK EVENTS (CLASS:LOAD): classId {0}, classSize {1}, kind {2}", classId, counterDelta, kind);
if (kind == EventKind.START) {
handler.ClassStartLoad (handler.LoadedElements.GetClass (classId), baseCounter);
+ handler.DataProcessed (offsetInBlock);
} else {
handler.ClassEndLoad (handler.LoadedElements.GetClass (classId), baseCounter, EventSuccessFromEventCode (packedData));
+ handler.DataProcessed (offsetInBlock);
}
break;
}
@@ -484,8 +503,10 @@ namespace Mono.Profiler {
//LogLine ("BLOCK EVENTS (CLASS:UNLOAD): classId {0}, counterDelta {1}, kind {2}", classId, counterDelta, kind);
if (kind == EventKind.START) {
handler.ClassStartUnload (handler.LoadedElements.GetClass (classId), baseCounter);
+ handler.DataProcessed (offsetInBlock);
} else {
handler.ClassEndUnload (handler.LoadedElements.GetClass (classId), baseCounter);
+ handler.DataProcessed (offsetInBlock);
}
break;
}
@@ -504,6 +525,7 @@ namespace Mono.Profiler {
//LogLine ("BLOCK EVENTS (PACKED:METHOD_ENTER): methodId {0}, counterDelta {1}", methodId, counterDelta);
handler.MethodEnter (handler.LoadedElements.GetMethod (methodId), baseCounter);
+ handler.DataProcessed (offsetInBlock);
break;
}
case PackedEventCode.METHOD_EXIT_EXPLICIT: {
@@ -515,6 +537,7 @@ namespace Mono.Profiler {
//LogLine ("BLOCK EVENTS (PACKED:METHOD_EXIT_EXPLICIT): methodId {0}, counterDelta {1}", methodId, counterDelta);
handler.MethodExit (handler.LoadedElements.GetMethod (methodId), baseCounter);
+ handler.DataProcessed (offsetInBlock);
break;
}
case PackedEventCode.METHOD_EXIT_IMPLICIT: {
@@ -530,6 +553,7 @@ namespace Mono.Profiler {
baseCounter += counterDelta;
//LogLine ("BLOCK EVENTS (METHOD:FREED): methodId {0}, counterDelta {1}", methodId, counterDelta);
handler.MethodFreed (handler.LoadedElements.GetMethod (methodId), baseCounter);
+ handler.DataProcessed (offsetInBlock);
break;
}
case MethodEvent.JIT: {
@@ -540,8 +564,10 @@ namespace Mono.Profiler {
//LogLine ("BLOCK EVENTS (METHOD:JIT): methodId {0}, counterDelta {1}, kind {2}", methodId, counterDelta, kind);
if (kind == EventKind.START) {
handler.MethodJitStart (handler.LoadedElements.GetMethod (methodId), baseCounter);
+ handler.DataProcessed (offsetInBlock);
} else {
handler.MethodJitEnd (handler.LoadedElements.GetMethod (methodId), baseCounter, EventSuccessFromEventCode (packedData));
+ handler.DataProcessed (offsetInBlock);
}
break;
}
@@ -564,8 +590,10 @@ namespace Mono.Profiler {
//LogLine ("BLOCK EVENTS (OTHER:GC_COLLECTION): generation {0}, counterDelta {1}, kind {2}", generation, counterDelta, kind);
if (kind == EventKind.START) {
handler.GarbageCollectionStart (collection, generation, baseCounter);
+ handler.DataProcessed (offsetInBlock);
} else {
handler.GarbageCollectionEnd (collection, generation, baseCounter);
+ handler.DataProcessed (offsetInBlock);
}
break;
}
@@ -579,8 +607,10 @@ namespace Mono.Profiler {
//LogLine ("BLOCK EVENTS (OTHER:GC_MARK): generation {0}, counterDelta {1}, kind {2}", generation, counterDelta, kind);
if (kind == EventKind.START) {
handler.GarbageCollectionMarkStart (collection, generation, baseCounter);
+ handler.DataProcessed (offsetInBlock);
} else {
handler.GarbageCollectionMarkEnd (collection, generation, baseCounter);
+ handler.DataProcessed (offsetInBlock);
}
break;
}
@@ -594,8 +624,10 @@ namespace Mono.Profiler {
//LogLine ("BLOCK EVENTS (OTHER:GC_SWEEP): generation {0}, counterDelta {1}, kind {2}", generation, counterDelta, kind);
if (kind == EventKind.START) {
handler.GarbageCollectionSweepStart (collection, generation, baseCounter);
+ handler.DataProcessed (offsetInBlock);
} else {
handler.GarbageCollectionSweepEnd (collection, generation, baseCounter);
+ handler.DataProcessed (offsetInBlock);
}
break;
}
@@ -604,6 +636,7 @@ namespace Mono.Profiler {
uint collection = ReadUint (ref offsetInBlock);
//LogLine ("BLOCK EVENTS (OTHER:GC_RESIZE): newSize {0}, collection {1}", newSize, collection);
handler.GarbageCollectionResize (collection, newSize);
+ handler.DataProcessed (offsetInBlock);
break;
}
case GenericEvent.GC_STOP_WORLD: {
@@ -616,8 +649,10 @@ namespace Mono.Profiler {
//LogLine ("BLOCK EVENTS (OTHER:GC_STOP_WORLD): generation {0}, counterDelta {1}, kind {2}", generation, counterDelta, kind);
if (kind == EventKind.START) {
handler.GarbageCollectionStopWorldStart (collection, generation, baseCounter);
+ handler.DataProcessed (offsetInBlock);
} else {
handler.GarbageCollectionStopWorldEnd (collection, generation, baseCounter);
+ handler.DataProcessed (offsetInBlock);
}
break;
}
@@ -631,8 +666,10 @@ namespace Mono.Profiler {
//LogLine ("BLOCK EVENTS (OTHER:GC_START_WORLD): generation {0}, counterDelta {1}, kind {2}", generation, counterDelta, kind);
if (kind == EventKind.START) {
handler.GarbageCollectionStartWorldStart (collection, generation, baseCounter);
+ handler.DataProcessed (offsetInBlock);
} else {
handler.GarbageCollectionStartWorldEnd (collection, generation, baseCounter);
+ handler.DataProcessed (offsetInBlock);
}
break;
}
@@ -644,8 +681,10 @@ namespace Mono.Profiler {
//LogLine ("BLOCK EVENTS (OTHER:THREAD): eventThreadId {0}, counterDelta {1}, kind {2}", eventThreadId, counterDelta, kind);
if (kind == EventKind.START) {
handler.ThreadStart (eventThreadId, baseCounter);
+ handler.DataProcessed (offsetInBlock);
} else {
handler.ThreadEnd (eventThreadId, baseCounter);
+ handler.DataProcessed (offsetInBlock);
}
break;
}
@@ -658,6 +697,26 @@ namespace Mono.Profiler {
}
//LogLine ("BLOCK EVENTS (OTHER:JIT_TIME_ALLOCATION): classId {0}, classSize {1}, callerId {2}", classId, classSize, callerId);
handler.Allocation (handler.LoadedElements.GetClass (classId), classSize, (callerId != 0) ? handler.LoadedElements.GetMethod (callerId) : default (LM), true, 0);
+ handler.DataProcessed (offsetInBlock);
+ break;
+ }
+ case GenericEvent.STACK_SECTION: {
+ uint lastValidFrame = ReadUint (ref offsetInBlock);
+ uint topSectionSize = ReadUint (ref offsetInBlock);
+
+ if (stackSection.Length < topSectionSize) {
+ stackSection = new StackSectionElement<LC,LM> [topSectionSize * 2];
+ }
+
+ for (int i = 0; i < topSectionSize; i++) {
+ uint methodId = ReadUint (ref offsetInBlock);
+ stackSection [i].IsBeingJitted = ((methodId & 1) != 0) ? true : false;
+ methodId >>= 1;
+ stackSection [i].Method = handler.LoadedElements.GetMethod (methodId);
+ }
+
+ handler.AdjustStack (lastValidFrame, topSectionSize, stackSection);
+ handler.DataProcessed (offsetInBlock);
break;
}
default: {
@@ -676,6 +735,7 @@ namespace Mono.Profiler {
ulong endTime = ReadUlong (ref offsetInBlock);
//LogLine ("BLOCK EVENTS (END): endCounter {0}, endTime {1}", endCounter, endTime);
handler.EndBlock (endCounter, microsecondsFromEpochToDateTime (endTime), threadId);
+ handler.DataProcessed (offsetInBlock);
break;
}
case BlockCode.STATISTICAL : {
@@ -684,6 +744,7 @@ namespace Mono.Profiler {
//LogLine ("BLOCK STATISTICAL (START): startCounter {0}, startTime {1}", startCounter, startTime);
handler.StartBlock (startCounter, microsecondsFromEpochToDateTime (startTime), 0);
+ handler.DataProcessed (offsetInBlock);
uint id;
for (id = ReadUint (ref offsetInBlock); id != (uint) StatisticalCode.END; id = ReadUint (ref offsetInBlock)) {
@@ -694,8 +755,10 @@ namespace Mono.Profiler {
//LogLine ("BLOCK STATISTICAL (METHOD): methodId {0}", methodId);
if (methodId != 0) {
handler.MethodStatisticalHit (handler.LoadedElements.GetMethod (methodId));
+ handler.DataProcessed (offsetInBlock);
} else {
handler.UnknownMethodStatisticalHit ();
+ handler.DataProcessed (offsetInBlock);
}
break;
}
@@ -703,6 +766,7 @@ namespace Mono.Profiler {
uint functionId = id >> 3;
UFI function = handler.LoadedElements.GetUnmanagedFunctionByID (functionId);
handler.UnmanagedFunctionStatisticalHit (function);
+ handler.DataProcessed (offsetInBlock);
break;
}
case StatisticalCode.UNMANAGED_FUNCTION_NEW_ID: {
@@ -712,6 +776,7 @@ namespace Mono.Profiler {
MR region = handler.LoadedElements.GetExecutableMemoryRegion (regionId);
UFI function = handler.LoadedElements.NewUnmanagedFunction (functionId, name, region);
handler.UnmanagedFunctionStatisticalHit (function);
+ handler.DataProcessed (offsetInBlock);
break;
}
case StatisticalCode.UNMANAGED_FUNCTION_OFFSET_IN_REGION: {
@@ -723,14 +788,17 @@ namespace Mono.Profiler {
if (function != null) {
//LogLine ("BLOCK STATISTICAL (FUNCTION): regionId {0}, offset {1}", regionId, offset);
handler.UnmanagedFunctionStatisticalHit (function);
+ handler.DataProcessed (offsetInBlock);
} else {
//LogLine ("BLOCK STATISTICAL (FUNCTION): regionId {0}, unknown offset {1}", regionId, offset);
handler.UnknownUnmanagedFunctionStatisticalHit (region, offset);
+ handler.DataProcessed (offsetInBlock);
}
} else {
ulong address = ReadUlong (ref offsetInBlock);
//LogLine ("BLOCK STATISTICAL (FUNCTION): unknown address {0}", address);
handler.UnknownUnmanagedFunctionStatisticalHit (address);
+ handler.DataProcessed (offsetInBlock);
}
break;
}
@@ -738,6 +806,7 @@ namespace Mono.Profiler {
uint chainDepth = id >> 3;
//LogLine ("BLOCK STATISTICAL (CHAIN): starting chain of depth {0}", chainDepth);
handler.StatisticalCallChainStart (chainDepth);
+ handler.DataProcessed (offsetInBlock);
break;
}
case StatisticalCode.REGIONS: {
@@ -762,6 +831,7 @@ namespace Mono.Profiler {
//}
}
handler.LoadedElements.SortExecutableMemoryRegions ();
+ handler.DataProcessed (offsetInBlock);
break;
}
}
@@ -782,11 +852,13 @@ namespace Mono.Profiler {
HS snapshot = handler.LoadedElements.NewHeapSnapshot (collection, jobStartCounter, microsecondsFromEpochToDateTime (jobStartTime), jobEndCounter, microsecondsFromEpochToDateTime (jobEndTime), handler.LoadedElements.Classes, handler.LoadedElements.RecordHeapSnapshots);
handler.HeapReportStart (snapshot);
+ handler.DataProcessed (offsetInBlock);
ulong startCounter = ReadUlong (ref offsetInBlock);
ulong startTime = ReadUlong (ref offsetInBlock);
//LogLine ("BLOCK HEAP_DATA (START): ({0}:{1}-{2}:{3}) startCounter {4}, startTime {5}", jobStartCounter, jobStartTime, jobEndCounter, jobEndTime, startCounter, startTime);
handler.StartBlock (startCounter, microsecondsFromEpochToDateTime (startTime), 0);
+ handler.DataProcessed (offsetInBlock);
ulong item;
ulong[] references = new ulong [50];
@@ -800,6 +872,7 @@ namespace Mono.Profiler {
LC c = handler.LoadedElements.GetClass (classId);
//LogLine (" Class id {0}, size {1}", classId, size);
handler.HeapObjectUnreachable (c, size);
+ handler.DataProcessed (offsetInBlock);
break;
}
case HeapSnapshotCode.OBJECT: {
@@ -818,6 +891,7 @@ namespace Mono.Profiler {
LC c = handler.LoadedElements.GetClass (classId);
HO o = snapshot.NewHeapObject (objectId, c, size, references, referencesCount);
handler.HeapObjectReachable (o);
+ handler.DataProcessed (offsetInBlock);
break;
}
default: {
@@ -826,11 +900,13 @@ namespace Mono.Profiler {
}
}
handler.HeapReportEnd (snapshot);
+ handler.DataProcessed (offsetInBlock);
ulong endCounter = ReadUlong (ref offsetInBlock);
ulong endTime = ReadUlong (ref offsetInBlock);
//LogLine ("BLOCK HEAP_DATA (END): endCounter {0}, endTime {1}", endCounter, endTime);
handler.EndBlock (endCounter, microsecondsFromEpochToDateTime (endTime), 0);
+ handler.DataProcessed (offsetInBlock);
break;
}
case BlockCode.HEAP_SUMMARY : {
@@ -841,6 +917,7 @@ namespace Mono.Profiler {
//LogLine ("BLOCK HEAP_SUMMARY (START): ([]{0}:{1}) startCounter {4}, startTime {5}", collection, startCounter, startTime);
handler.StartBlock (startCounter, microsecondsFromEpochToDateTime (startTime), 0);
handler.AllocationSummaryStart (collection, startCounter, microsecondsFromEpochToDateTime (startTime));
+ handler.DataProcessed (offsetInBlock);
uint id;
for (id = ReadUint (ref offsetInBlock); id != 0; id = ReadUint (ref offsetInBlock)) {
@@ -851,19 +928,23 @@ namespace Mono.Profiler {
LC c = handler.LoadedElements.GetClass (id);
handler.ClassAllocationSummary (c, reachableInstances, reachableBytes, unreachableInstances, unreachableBytes);
+ handler.DataProcessed (offsetInBlock);
}
ulong endCounter = ReadUlong (ref offsetInBlock);
ulong endTime = ReadUlong (ref offsetInBlock);
handler.AllocationSummaryEnd (collection, endCounter, microsecondsFromEpochToDateTime (endTime));
+ handler.DataProcessed (offsetInBlock);
//LogLine ("BLOCK HEAP_SUMMARY (END): endCounter {0}, endTime {1}", endCounter, endTime);
handler.EndBlock (endCounter, microsecondsFromEpochToDateTime (endTime), 0);
+ handler.DataProcessed (offsetInBlock);
break;
}
case BlockCode.DIRECTIVES : {
ulong startCounter = ReadUlong (ref offsetInBlock);
ulong startTime = ReadUlong (ref offsetInBlock);
handler.StartBlock (startCounter, microsecondsFromEpochToDateTime (startTime), 0);
+ handler.DataProcessed (offsetInBlock);
//LogLine ("BLOCK DIRECTIVES (START): startCounter {0}, startTime {1}", startCounter, startTime);
DirectiveCodes directive = (DirectiveCodes) ReadUint (ref offsetInBlock);
@@ -873,6 +954,10 @@ namespace Mono.Profiler {
//LogLine ("BLOCK DIRECTIVES (START): ALLOCATIONS_CARRY_CALLER");
handler.Directives.AllocationsCarryCallerMethodReceived ();
break;
+ case DirectiveCodes.ALLOCATIONS_HAVE_STACK:
+ //LogLine ("BLOCK DIRECTIVES (START): ALLOCATIONS_HAVE_STACK");
+ handler.Directives.AllocationsHaveStackTraceReceived ();
+ break;
default:
throw new DecodingException (this, offsetInBlock, String.Format ("unknown directive {0}", directive));
}
@@ -883,6 +968,7 @@ namespace Mono.Profiler {
ulong endCounter = ReadUlong (ref offsetInBlock);
ulong endTime = ReadUlong (ref offsetInBlock);
handler.EndBlock (endCounter, microsecondsFromEpochToDateTime (endTime), 0);
+ handler.DataProcessed (offsetInBlock);
//LogLine ("BLOCK DIRECTIVES (END): endCounter {0}, endTime {1}", endCounter, endTime);
break;
}
@@ -895,12 +981,79 @@ namespace Mono.Profiler {
throw new DecodingException (this, offsetInBlock, String.Format ("Block ended at offset {0} but its declared length is {1}", offsetInBlock, length));
}
} catch (DecodingException e) {
+ if (handleExceptions) {
+ HandleDecodingException<LC,LM,UFR,UFI,MR,EH,HO,HS> (e, offsetInBlock, handler);
+ }
throw e;
} catch (Exception e) {
+ if (handleExceptions) {
+ HandleRegularException<LC,LM,UFR,UFI,MR,EH,HO,HS> (e, offsetInBlock, handler);
+ }
throw new DecodingException(this, offsetInBlock, e.Message, e);
}
}
+ bool handleExceptions = true;
+
+ void DumpDebugInformation<LC,LM,UFR,UFI,MR,EH,HO,HS> (uint offsetInBlock, IProfilerEventHandler<LC,LM,UFR,UFI,MR,EH,HO,HS> handler) where LC : ILoadedClass where LM : ILoadedMethod<LC> where UFR : IUnmanagedFunctionFromRegion where UFI : IUnmanagedFunctionFromID<MR,UFR> where MR : IExecutableMemoryRegion<UFR> where EH : ILoadedElementHandler<LC,LM,UFR,UFI,MR,HO,HS> where HO: IHeapObject<HO,LC> where HS: IHeapSnapshot<HO,LC> {
+ if (debugLog != null) {
+ debugLog.WriteLine ("Attempting to decode data printing block contents...");
+ handleExceptions = false;
+ try {
+ DebugProfilerEventHandler<LC,LM,UFR,UFI,MR,EH,HO,HS> debugHandler =
+ new DebugProfilerEventHandler<LC,LM,UFR,UFI,MR,EH,HO,HS> (handler.LoadedElements, debugLog);
+ debugLog.WriteLine ("Current block of type {0} (file offset {1}, length {2})", Code, FileOffset, Length);
+ Decode (debugHandler);
+
+ } catch (Exception e) {
+ debugLog.WriteLine ("While attempting decoding, got exception {0}", e.Message);
+ DumpData (data, debugLog, offsetInBlock - 8, offsetInBlock + 24);
+ } finally {
+ handleExceptions = true;
+ }
+ }
+ }
+ void HandleDecodingException<LC,LM,UFR,UFI,MR,EH,HO,HS> (DecodingException e, uint offsetInBlock, IProfilerEventHandler<LC,LM,UFR,UFI,MR,EH,HO,HS> handler) where LC : ILoadedClass where LM : ILoadedMethod<LC> where UFR : IUnmanagedFunctionFromRegion where UFI : IUnmanagedFunctionFromID<MR,UFR> where MR : IExecutableMemoryRegion<UFR> where EH : ILoadedElementHandler<LC,LM,UFR,UFI,MR,HO,HS> where HO: IHeapObject<HO,LC> where HS: IHeapSnapshot<HO,LC> {
+ if (debugLog != null) {
+ debugLog.WriteLine ("ERROR: DecodingException in block of code {0}, length {1}, file offset {2}, block offset {3}: {4}", e.FailingData.Code, e.FailingData.Length, e.FailingData.FileOffset, e.OffsetInBlock, e.Message);
+ debugLog.WriteLine (e.StackTrace);
+ if (e.InnerException != null) {
+ debugLog.WriteLine ("Original stack trace:");
+ debugLog.WriteLine (e.InnerException.StackTrace);
+ }
+ DumpDebugInformation<LC,LM,UFR,UFI,MR,EH,HO,HS> (offsetInBlock, handler);
+ }
+
+ throw e;
+ }
+ void HandleRegularException<LC,LM,UFR,UFI,MR,EH,HO,HS> (Exception e, uint offsetInBlock, IProfilerEventHandler<LC,LM,UFR,UFI,MR,EH,HO,HS> handler) where LC : ILoadedClass where LM : ILoadedMethod<LC> where UFR : IUnmanagedFunctionFromRegion where UFI : IUnmanagedFunctionFromID<MR,UFR> where MR : IExecutableMemoryRegion<UFR> where EH : ILoadedElementHandler<LC,LM,UFR,UFI,MR,HO,HS> where HO: IHeapObject<HO,LC> where HS: IHeapSnapshot<HO,LC> {
+ if (debugLog != null) {
+ debugLog.WriteLine ("ERROR: Exception in block of code {0}, length {1}, file offset {2}, block offset {3}: {4}", Code, Length, FileOffset, offsetInBlock, e.Message);
+ debugLog.WriteLine (e.StackTrace);
+ DumpDebugInformation<LC,LM,UFR,UFI,MR,EH,HO,HS> (offsetInBlock, handler);
+ }
+
+ throw e;
+ }
+
+ static public void DumpData (byte[] data, TextWriter output, uint startOffset, uint endOffset) {
+ uint currentIndex = 0;
+ while (startOffset < endOffset) {
+ if (currentIndex % 8 == 0) {
+ if ((currentIndex != 0)) {
+ output.WriteLine ();
+ }
+ output.Write (" [{0}-{1}]", startOffset, startOffset + 7);
+ }
+ output.Write (" ");
+ output.Write (data [startOffset]);
+
+ startOffset ++;
+ currentIndex ++;
+ }
+ output.WriteLine ();
+ }
+
public BlockData (uint fileOffset, BlockCode code, int length, byte[] data) {
this.fileOffset = fileOffset;
this.code = code;