public DataTarget LoadFullDumpWithDbgEng(GCMode gc = GCMode.Workstation) { Guid guid = new Guid("27fe5639-8407-4f47-8364-ee118fb08ac8"); int hr = DebugCreate(guid, out IntPtr pDebugClient); if (hr != 0) { throw new Exception($"Failed to create DebugClient, hr={hr:x}."); } IDebugClient client = (IDebugClient)Marshal.GetTypedObjectForIUnknown(pDebugClient, typeof(IDebugClient)); IDebugControl control = (IDebugControl)client; string dumpPath = BuildDumpName(gc, true); hr = client.OpenDumpFile(dumpPath); if (hr != 0) { throw new Exception($"Failed to OpenDumpFile, hr={hr:x}."); } hr = control.WaitForEvent(DEBUG_WAIT.DEFAULT, 10000); if (hr != 0) { throw new Exception($"Failed to attach to dump file, hr={hr:x}."); } Marshal.Release(pDebugClient); return(DataTarget.CreateFromDbgEng(pDebugClient)); }
private static bool InitApi(IntPtr ptrClient) { // On our first call to the API: // 1. Store a copy of IDebugClient in DebugClient. // 2. Replace Console's output stream to be the debugger window. // 3. Create an instance of DataTarget using the IDebugClient. if (DebugClient is null) { object client = Marshal.GetUniqueObjectForIUnknown(ptrClient); DebugClient = (IDebugClient)client; var stream = new StreamWriter(new DbgEngStream(DebugClient)); stream.AutoFlush = true; Console.SetOut(stream); DataTarget = DataTarget.CreateFromDbgEng(ptrClient); } // If our ClrRuntime instance is null, it means that this is our first call, or // that the dac wasn't loaded on any previous call. Find the dac loaded in the // process (the user must use .cordll), then construct our runtime from it. if (Runtime is null) { // Just find a module named mscordacwks and assume it's the one the user // loaded into windbg. Process p = Process.GetCurrentProcess(); foreach (ProcessModule module in p.Modules) { if (module.FileName.ToLower().Contains("mscordacwks")) { // TODO: This does not support side-by-side CLRs. Runtime = DataTarget.ClrVersions.Single().CreateRuntime(module.FileName); break; } } // Otherwise, the user didn't run .cordll. if (Runtime is null) { Console.WriteLine("Mscordacwks.dll not loaded into the debugger."); Console.WriteLine("Run .cordll to load the dac before running this command."); } } else { // If we already had a runtime, flush it for this use. This is ONLY required // for a live process or iDNA trace. If you use the IDebug* apis to detect // that we are debugging a crash dump you may skip this call for better perf. Runtime.FlushCachedData(); } return(Runtime != null); }
internal static void Initialize(IntPtr ptrClient, bool isWinDbg) { // On our first call to the API: // 1. Store a copy of IDebugClient in DebugClient. // 2. Replace Console's output stream to be the debugger window. // 3. Create an instance of DataTarget using the IDebugClient. if (DataTarget == null) { if (!isWinDbg) { DebugClient = NativeInvoker.GetInstance <ILLDBDebugClient>(ptrClient, vtable); var linuxFunctionsType = Type.GetType("Microsoft.Diagnostics.Runtime.LinuxFunctions, Microsoft.Diagnostics.Runtime"); var field = typeof(DataTarget).GetField("<PlatformFunctions>k__BackingField", BindingFlags.Static | BindingFlags.NonPublic); field.SetValue(null, Activator.CreateInstance(linuxFunctionsType)); Console.SetOut(new StripDmlWriter(Console.Out)); } else { DebugClient = (IDebugClient)Marshal.GetUniqueObjectForIUnknown(ptrClient); var stream = new StreamWriter(new DbgEngStream(DebugClient)) { AutoFlush = true }; Console.SetOut(stream); } DataTarget = DataTarget.CreateFromDbgEng(ptrClient); } // If our ClrRuntime instance is null, it means that this is our first call, or // that the dac wasn't loaded on any previous call. if (Runtime == null) { Runtime = DataTarget.ClrVersions.Single().CreateRuntime(); } }
public DataTarget LoadFullDumpWithDbgEng(GCMode gc = GCMode.Workstation) { Guid guid = DebugClient.IID_IDebugClient; int hr = DebugCreate(guid, out IntPtr pDebugClient); if (hr != 0) { throw new Exception($"Failed to create DebugClient, hr={hr:x}."); } RefCountedFreeLibrary library = new RefCountedFreeLibrary(IntPtr.Zero); Marshal.AddRef(pDebugClient); Marshal.AddRef(pDebugClient); DebugSystemObjects sys = new DebugSystemObjects(library, pDebugClient); DebugClient client = new DebugClient(library, pDebugClient, sys); DebugControl control = new DebugControl(library, pDebugClient, sys); string dumpPath = BuildDumpName(gc, true); hr = client.OpenDumpFile(dumpPath); if (hr != 0) { throw new Exception($"Failed to OpenDumpFile, hr={hr:x}."); } hr = control.WaitForEvent(10000); if (hr != 0) { throw new Exception($"Failed to attach to dump file, hr={hr:x}."); } Marshal.Release(pDebugClient); return(DataTarget.CreateFromDbgEng(pDebugClient)); }