This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class TimerInfo | |
{ | |
public ulong TimerQueueTimerAddress { get; set; } | |
public uint DueTime { get; set; } | |
public uint Period { get; set; } | |
public bool Cancelled { get; set; } | |
public ulong StateAddress { get; set; } | |
public string StateTypeName { get; set; } | |
public ulong ThisAddress { get; set; } | |
public string MethodName { get; set; } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public IEnumerable<TimerInfo> EnumerateTimers(ClrRuntime runtime) | |
{ | |
ClrHeap heap = runtime.GetHeap(); | |
if (!heap.CanWalkHeap) | |
yield break; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private ClrModule GetMscorlib(ClrRuntime runtime) | |
{ | |
foreach (ClrModule module in runtime.Modules) | |
if (module.AssemblyName.Contains("mscorlib.dll")) | |
return module; | |
// Uh oh, this shouldn't have happened. Let's look more carefully (slowly). | |
foreach (ClrModule module in runtime.Modules) | |
if (module.AssemblyName.ToLower().Contains("mscorlib")) | |
return module; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var timerQueueType = GetMscorlib(runtime).GetTypeByName("System.Threading.TimerQueue"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ClrStaticField staticField = timerQueueType.GetStaticFieldByName("s_queue"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
foreach (ClrAppDomain domain in runtime.AppDomains) | |
{ | |
ulong? timerQueue = (ulong?)staticField.GetValue(domain); | |
if (!timerQueue.HasValue || timerQueue.Value == 0) | |
continue; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private object GetFieldValue(ClrHeap heap, ulong address, string fieldName) | |
{ | |
var type = heap.GetObjectType(address); | |
ClrInstanceField field = type.GetFieldByName(fieldName); | |
if (field == null) | |
return null; | |
return field.GetValue(address); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// m_timers is the start of the list of TimerQueueTimer | |
var currentPointer = GetFieldValue(heap, timerQueue.Value, "m_timers"); | |
while ((currentPointer != null) && (((ulong)currentPointer) != 0)) | |
{ | |
// currentPointer points to a TimerQueueTimer instance | |
ulong currentTimerQueueTimerRef = (ulong)currentPointer; | |
TimerInfo ti = new TimerInfo() | |
{ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var val = GetFieldValue(heap, currentTimerQueueTimerRef, "m_dueTime"); | |
ti.DueTime = (uint)val; | |
val = GetFieldValue(heap, currentTimerQueueTimerRef, "m_period"); | |
ti.Period = (uint)val; | |
val = GetFieldValue(heap, currentTimerQueueTimerRef, "m_canceled"); | |
ti.Cancelled = (bool)val; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val = GetFieldValue(heap, currentTimerQueueTimerRef, "m_state"); | |
ti.StateTypeName = ""; | |
if (val == null) | |
{ | |
ti.StateAddress = 0; | |
} | |
else | |
{ | |
ti.StateAddress = (ulong)val; | |
var stateType = heap.GetObjectType(ti.StateAddress); |
OlderNewer