public override bool Generate(CommandExecutionContext context) { _title = Path.GetFileName(context.DumpFile); switch (context.TargetType) { case TargetType.DumpFile: DumpType = "Full memory dump with heap"; break; case TargetType.DumpFileNoHeap: DumpType = "Mini dump with no heap"; break; default: DumpType = "Unsupported dump file type"; break; } var target = context.NativeDbgEngTarget; IDebugSystemObjects2 sysObjects = (IDebugSystemObjects2)target.DebuggerInterface; IDebugControl2 control = (IDebugControl2)target.DebuggerInterface; uint dummy; StringBuilder exeName = new StringBuilder(2048); if (HR.Succeeded(sysObjects.GetCurrentProcessExecutableName(exeName, exeName.Capacity, out dummy))) { ExecutableName = exeName.ToString(); } uint uptime; if (HR.Succeeded(sysObjects.GetCurrentProcessUpTime(out uptime))) { ProcessUpTimeInSeconds = uptime; } if (HR.Succeeded(control.GetCurrentSystemUpTime(out uptime))) { SystemUpTimeInSeconds = uptime; } uint time; if (HR.Succeeded(control.GetCurrentTimeDate(out time))) { SessionTime = DateTimeOffset.FromUnixTimeSeconds(time); } uint num; if (HR.Succeeded(control.GetNumberProcessors(out num))) { NumberOfProcessors = num; } uint platformId, major, minor, servicePackNumber; StringBuilder servicePack = new StringBuilder(1048); StringBuilder build = new StringBuilder(1048); if (HR.Succeeded(control.GetSystemVersion(out platformId, out major, out minor, servicePack, servicePack.Capacity, out dummy, out servicePackNumber, build, build.Capacity, out dummy))) { WindowsBuildNumber = minor; WindowsServicePack = servicePack.ToString(); WindowsServicePackNumber = servicePackNumber; WindowsBuild = build.ToString(); } ClrVersions.AddRange(context.Runtime.DataTarget.ClrVersions.Select(v => v.Version.ToString())); if (context.Runtime.DataTarget.ClrVersions.Any(v => v.Version.Minor == 2)) { Recommendations.Add(new CLRV2Detected()); } return(true); }
public static LastEventInformation GetLastEventInformation(this DataTarget target) { var control = (IDebugControl)target.DebuggerInterface; DEBUG_EVENT eventType; uint procId, threadId; StringBuilder description = new StringBuilder(2048); uint unused; uint descriptionSize; if (HR.Failed(control.GetLastEventInformation( out eventType, out procId, out threadId, IntPtr.Zero, 0, out unused, description, description.Capacity, out descriptionSize))) { return(null); } var osThreadIds = target.GetOSThreadIds(); var eventInformation = new LastEventInformation { OSThreadId = (int)osThreadIds[threadId], EventType = eventType, EventDescription = description.ToString() }; IDebugAdvanced2 debugAdvanced = (IDebugAdvanced2)target.DebuggerInterface; int outSize; byte[] buffer = new byte[Marshal.SizeOf(typeof(EXCEPTION_RECORD64))]; int hr = debugAdvanced.Request(DEBUG_REQUEST.TARGET_EXCEPTION_RECORD, null, 0, buffer, buffer.Length, out outSize); if (HR.Succeeded(hr)) { GCHandle gch = GCHandle.Alloc(buffer, GCHandleType.Pinned); try { eventInformation.ExceptionRecord = (EXCEPTION_RECORD64)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(EXCEPTION_RECORD64)); } finally { gch.Free(); } } buffer = new byte[Marshal.SizeOf(typeof(uint))]; hr = debugAdvanced.Request(DEBUG_REQUEST.TARGET_EXCEPTION_THREAD, null, 0, buffer, buffer.Length, out outSize); if (HR.Succeeded(hr)) { // If there is a stored exception event with a thread id, use that instead // of what GetLastEventInformation returns, because it might be different. eventInformation.OSThreadId = (int)BitConverter.ToUInt32(buffer, 0); } buffer = new byte[Marshal.SizeOf(typeof(CONTEXT))]; hr = debugAdvanced.Request(DEBUG_REQUEST.TARGET_EXCEPTION_CONTEXT, null, 0, buffer, buffer.Length, out outSize); if (HR.Succeeded(hr)) { var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned); try { eventInformation.ExceptionContext = (CONTEXT)Marshal.PtrToStructure( gch.AddrOfPinnedObject(), typeof(CONTEXT)); } finally { gch.Free(); } } return(eventInformation); }