From 96155736e5767dc0c0fc2f13549ca0a40ad1e7a6 Mon Sep 17 00:00:00 2001 From: x1nixmzeng Date: Sun, 11 Oct 2020 12:14:42 +0100 Subject: [PATCH] Update debugger types and thread report handling --- src/CxbxDebugger/Debugger/Debugger.cs | 157 ++++++++---------- .../Debugger/DebuggerEventInterfaces.cs | 3 +- src/CxbxDebugger/Debugger/DebuggerMessages.cs | 149 +++++++++++------ 3 files changed, 166 insertions(+), 143 deletions(-) diff --git a/src/CxbxDebugger/Debugger/Debugger.cs b/src/CxbxDebugger/Debugger/Debugger.cs index 6f5ea590d..1a1e6eaa3 100644 --- a/src/CxbxDebugger/Debugger/Debugger.cs +++ b/src/CxbxDebugger/Debugger/Debugger.cs @@ -9,6 +9,7 @@ using WinDebug = VsChromium.Core.Win32.Debugging; using System.Runtime.InteropServices; using WinLowLevel = LowLevelDesign.Win32.Windows.NativeMethods; using System.Threading; +using System.Threading.Tasks; namespace CxbxDebugger { @@ -32,13 +33,18 @@ namespace CxbxDebugger string[] args = new string[] { }; string Target = ""; + public string ProcessName + { + get { return Target; } + } + RunState State = RunState.NotLaunched; DebuggerMessages.DebuggerInit InitParams = new DebuggerMessages.DebuggerInit(); DebuggerInstance DebugInstance; - List GeneralEvents = new List(); + List SessionEvents = new List(); List ProcessEvents = new List(); List ThreadEvents = new List(); List ModuleEvents = new List(); @@ -103,7 +109,7 @@ namespace CxbxDebugger bpStall.Set(); // Remove all events - GeneralEvents.Clear(); + SessionEvents.Clear(); ProcessEvents.Clear(); ThreadEvents.Clear(); ModuleEvents.Clear(); @@ -172,6 +178,9 @@ namespace CxbxDebugger if (CanLaunch() == false) throw new Exception("Unable to launch in this state"); + if (args.Length == 0) + return false; + var DebugCreationFlags = WinProcesses.ProcessCreationFlags.DEBUG_ONLY_THIS_PROCESS | WinProcesses.ProcessCreationFlags.CREATE_NEW_CONSOLE; @@ -197,7 +206,7 @@ namespace CxbxDebugger // Store so they can be marshalled and closed correctly hProcess = new WinProcesses.SafeProcessHandle(stProcessInfo.hProcess); hThread = new WinProcesses.SafeThreadHandle(stProcessInfo.hThread); - + bContinue = true; State = RunState.Running; @@ -313,10 +322,7 @@ namespace CxbxDebugger Thread.StartAddress = DebugInfo.lpStartAddress; Thread.ThreadBase = DebugInfo.lpThreadLocalBase; - foreach (IDebuggerThreadEvents Event in ThreadEvents ) - { - Event.OnThreadCreate(Thread); - } + Parallel.ForEach(ThreadEvents, Event => Event.OnThreadCreate(Thread)); } private void HandleExitThread(WinDebug.DEBUG_EVENT DebugEvent) @@ -333,10 +339,7 @@ namespace CxbxDebugger { uint ExitCode = DebugInfo.dwExitCode; - foreach (IDebuggerThreadEvents Event in ThreadEvents) - { - Event.OnThreadExit(TargetThread, ExitCode); - } + Parallel.ForEach(ThreadEvents, Event => Event.OnThreadExit(TargetThread, ExitCode)); } } @@ -369,26 +372,17 @@ namespace CxbxDebugger DebugInstance = new DebuggerInstance(Process); RegisterEventInterfaces(DebugInstance); - foreach (IDebuggerProcessEvents Event in ProcessEvents) - { - Event.OnProcessCreate(Process); - } + Parallel.ForEach(ProcessEvents, Event => Event.OnProcessCreate(Process)); - foreach (IDebuggerThreadEvents Event in ThreadEvents) - { - Event.OnThreadCreate(MainThread); - } - + Parallel.ForEach(ThreadEvents, Event => Event.OnThreadCreate(MainThread)); + var XboxModule = new DebuggerModule(); XboxModule.Path = Target; XboxModule.ImageBase = DebugInfo.lpBaseOfImage; XboxModule.Core = true; - foreach (IDebuggerModuleEvents Event in ModuleEvents) - { - Event.OnModuleLoaded(XboxModule); - } + Parallel.ForEach(ModuleEvents, Event => Event.OnModuleLoaded(XboxModule)); } private void HandleExitProcess(WinDebug.DEBUG_EVENT DebugEvent) @@ -405,10 +399,7 @@ namespace CxbxDebugger if (TargetProcess != null) { - foreach (IDebuggerProcessEvents Event in ProcessEvents) - { - Event.OnProcessExit(TargetProcess, ExitCode); - } + Parallel.ForEach(ProcessEvents, Event => Event.OnProcessExit(TargetProcess, ExitCode)); } } @@ -426,10 +417,7 @@ namespace CxbxDebugger Module.Path = ResolveProcessPath(DebugInfo.hFile); Module.ImageBase = DebugInfo.lpBaseOfDll; - foreach (IDebuggerModuleEvents Event in ModuleEvents) - { - Event.OnModuleLoaded(Module); - } + Parallel.ForEach(ModuleEvents, Event => Event.OnModuleLoaded(Module)); } private void HandleUnloadDll(WinDebug.DEBUG_EVENT DebugEvent) @@ -445,10 +433,7 @@ namespace CxbxDebugger if (TargetModule != null) { - foreach (IDebuggerModuleEvents Event in ModuleEvents) - { - Event.OnModuleUnloaded(TargetModule); - } + Parallel.ForEach(ModuleEvents, Event => Event.OnModuleUnloaded(TargetModule)); } } @@ -458,10 +443,7 @@ namespace CxbxDebugger string debugString = ReadProcessString(DebugInfo.lpDebugStringData, DebugInfo.nDebugStringLength, DebugInfo.fUnicode == 1); - foreach(IDebuggerOutputEvents Event in OutputEvents) - { - Event.OnDebugOutput(debugString); - } + Parallel.ForEach(OutputEvents, Event => Event.OnDebugOutput(debugString)); } private void HandleException(WinDebug.DEBUG_EVENT DebugEvent) @@ -482,12 +464,28 @@ namespace CxbxDebugger } break; + case ExceptionCode.PrivilegedInstruction: + { + // Seeing this frequently called in Win10 + + ContinueStatus = WinDebug.CONTINUE_STATUS.DBG_EXCEPTION_NOT_HANDLED; + } + break; + + case ExceptionCode.StatusHandleNotClosable: + { + // Seeing this frequently called in Win10 + + ContinueStatus = WinDebug.CONTINUE_STATUS.DBG_EXCEPTION_NOT_HANDLED; + } + break; + case (ExceptionCode)DebuggerMessages.ReportType.OVERRIDE_EXCEPTION: { var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId); if (Thread != null) { - var Query = DebuggerMessages.GetExceptionHandledQuery(Thread, DebugInfo.ExceptionRecord.ExceptionInformation); + var Query = DebuggerMessages.GetExceptionHandledQuery(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation)); bool Handled = false; foreach (IDebuggerExceptionEvents Event in ExceptionEvents) @@ -506,7 +504,7 @@ namespace CxbxDebugger var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId); if (Thread != null) { - var Report = DebuggerMessages.GetHLECacheReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation); + var Report = DebuggerMessages.GetHLECacheReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation)); SetupHLECacheProvider(Report.FileName); } } @@ -517,7 +515,7 @@ namespace CxbxDebugger var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId); if (Thread != null) { - var Report = DebuggerMessages.GetKernelPatchReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation); + var Report = DebuggerMessages.GetKernelPatchReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation)); KernelSymbolProvider.AddKernelSymbolFromMessage(Report); } @@ -529,12 +527,9 @@ namespace CxbxDebugger var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId); if (Thread != null) { - var Report = DebuggerMessages.GetFileOpenedReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation); + var Report = DebuggerMessages.GetFileOpenedReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation)); - foreach (IDebuggerFileEvents Event in FileEvents) - { - Event.OnFileOpened(Report); - } + Parallel.ForEach(FileEvents, Event => Event.OnFileOpened(Report)); } } break; @@ -544,12 +539,9 @@ namespace CxbxDebugger var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId); if (Thread != null) { - var Report = DebuggerMessages.GetFileReadReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation); + var Report = DebuggerMessages.GetFileReadReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation)); - foreach (IDebuggerFileEvents Event in FileEvents) - { - Event.OnFileRead(Report); - } + Parallel.ForEach(FileEvents, Event => Event.OnFileRead(Report)); } } break; @@ -559,12 +551,9 @@ namespace CxbxDebugger var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId); if (Thread != null) { - var Report = DebuggerMessages.GetFileWriteReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation); + var Report = DebuggerMessages.GetFileWriteReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation)); - foreach (IDebuggerFileEvents Event in FileEvents) - { - Event.OnFileWrite(Report); - } + Parallel.ForEach(FileEvents, Event => Event.OnFileWrite(Report)); } } break; @@ -574,13 +563,10 @@ namespace CxbxDebugger var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId); if (Thread != null) { - var Report = DebuggerMessages.GetFileClosedReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation); + var Report = DebuggerMessages.GetFileClosedReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation)); if (Report != null) { - foreach (IDebuggerFileEvents Event in FileEvents) - { - Event.OnFileClosed(Report); - } + Parallel.ForEach(FileEvents, Event => Event.OnFileClosed(Report)); } } } @@ -591,14 +577,23 @@ namespace CxbxDebugger var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId); if (Thread != null) { - var Report = DebuggerMessages.GetDebuggerInitReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation); + var Report = DebuggerMessages.GetDebuggerInitReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation)); InitParams = Report; - foreach (IDebuggerGeneralEvents Event in GeneralEvents) - { - Event.OnDebugTitleLoaded(InitParams.Title); - } + Parallel.ForEach(SessionEvents, Event => Event.OnDebugTitleLoaded(InitParams.Title)); + } + } + break; + + case (ExceptionCode)DebuggerMessages.ReportType.DEBUGGER_NEW_TARGET: + { + var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId); + if (Thread != null) + { + var Report = DebuggerMessages.GetDebuggerNewTargetReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation)); + + Parallel.ForEach(SessionEvents, Event => Event.OnDebugTargetChanged(Report.CommandLine)); } } break; @@ -608,7 +603,7 @@ namespace CxbxDebugger var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId); if (Thread != null) { - var Report = DebuggerMessages.GetMSVCThreadName(Thread, DebugInfo.ExceptionRecord.ExceptionInformation); + var Report = DebuggerMessages.GetMSVCThreadName(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation)); if(Report != null) { // Resolve the ThreadId of an invalid ID to the current thread name @@ -623,10 +618,7 @@ namespace CxbxDebugger // Update the resolved thread name ResolvedThread.DebugName = Report.Name; - foreach (IDebuggerThreadEvents Event in ThreadEvents) - { - Event.OnThreadNamed(Thread); - } + Parallel.ForEach(ThreadEvents, Event => Event.OnThreadNamed(Thread)); } } } @@ -644,10 +636,7 @@ namespace CxbxDebugger bpStall.Reset(); - foreach (IDebuggerExceptionEvents Event in ExceptionEvents) - { - Event.OnBreakpoint(Thread, BpAddr, BpCode, FirstChance); - } + Parallel.ForEach(ExceptionEvents, Event => Event.OnBreakpoint(Thread, BpAddr, BpCode, FirstChance)); bpStall.WaitOne(); } @@ -674,10 +663,7 @@ namespace CxbxDebugger WinDebug.DEBUG_EVENT DbgEvt = new WinDebug.DEBUG_EVENT(); ContinueStatus = WinDebug.CONTINUE_STATUS.DBG_CONTINUE; - foreach (IDebuggerGeneralEvents Event in GeneralEvents) - { - Event.OnDebugStart(); - } + Parallel.ForEach(SessionEvents, Event => Event.OnDebugStart()); // Loop until told to stop while (bContinue == true) @@ -734,10 +720,7 @@ namespace CxbxDebugger State = RunState.Ended; - foreach (IDebuggerGeneralEvents Event in GeneralEvents) - { - Event.OnDebugEnd(); - } + Parallel.ForEach(SessionEvents, Event => Event.OnDebugEnd()); } public DebuggerSymbol ResolveSymbol(uint Address) @@ -757,8 +740,8 @@ namespace CxbxDebugger public void RegisterEventInterfaces(object EventClass) { - IDebuggerGeneralEvents GeneralListener = EventClass as IDebuggerGeneralEvents; - if(GeneralListener != null ) GeneralEvents.Add(GeneralListener); + IDebuggerSessionEvents SessionListener = EventClass as IDebuggerSessionEvents; + if(SessionListener != null ) SessionEvents.Add(SessionListener); IDebuggerProcessEvents ProcessListener = EventClass as IDebuggerProcessEvents; if (ProcessListener != null) ProcessEvents.Add(ProcessListener); diff --git a/src/CxbxDebugger/Debugger/DebuggerEventInterfaces.cs b/src/CxbxDebugger/Debugger/DebuggerEventInterfaces.cs index 70db79800..d76995c64 100644 --- a/src/CxbxDebugger/Debugger/DebuggerEventInterfaces.cs +++ b/src/CxbxDebugger/Debugger/DebuggerEventInterfaces.cs @@ -5,11 +5,12 @@ using System; namespace CxbxDebugger { - public interface IDebuggerGeneralEvents + public interface IDebuggerSessionEvents { void OnDebugStart(); void OnDebugEnd(); void OnDebugTitleLoaded(string Title); + void OnDebugTargetChanged(string CommandLine); } public interface IDebuggerProcessEvents diff --git a/src/CxbxDebugger/Debugger/DebuggerMessages.cs b/src/CxbxDebugger/Debugger/DebuggerMessages.cs index 00c266fa9..9c6029a9a 100644 --- a/src/CxbxDebugger/Debugger/DebuggerMessages.cs +++ b/src/CxbxDebugger/Debugger/DebuggerMessages.cs @@ -9,15 +9,20 @@ namespace CxbxDebugger { public enum ReportType : uint { - HLECACHE_FILE = 0x00deed00, - KERNEL_PATCH = 0x00deed01, - FILE_OPENED = 0x00deed02, - FILE_READ = 0x00deed03, - FILE_CLOSED = 0x00deed04, - DEBUGGER_INIT = 0x00deed05, - FILE_WRITE = 0x00deed06, + HLECACHE_FILE = 0x1000, - OVERRIDE_EXCEPTION = 0x00ceed01, + KERNEL_PATCH = 0x2000, + + FILE_OPENED = 0x3000, + + FILE_READ = 0x3001, + FILE_WRITE = 0x3002, + FILE_CLOSED = 0x3003, + + DEBUGGER_INIT = 0x400, + DEBUGGER_NEW_TARGET = 0x401, + + OVERRIDE_EXCEPTION = 0x500, // Exception code from https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx MS_VC_EXCEPTION = 0x406D1388, @@ -29,22 +34,38 @@ namespace CxbxDebugger WCHAR, }; + public class DataProcessor + { + uint[] SourceData; + uint SourceIndex; + + public DataProcessor(uint[] Data) + { + SourceData = Data; + SourceIndex = 0; + } + + public uint Pop() + { + return SourceData[SourceIndex++]; + } + } + public class HLECache { public string FileName { get; set; } } - public static HLECache GetHLECacheReport(DebuggerThread Context, uint[] Data) + public static HLECache GetHLECacheReport(DebuggerThread Context, DataProcessor Data) { HLECache Report = new HLECache(); - StringType Type = (StringType)Data[0]; - + var Type = (StringType)Data.Pop(); if (Type != StringType.CHAR) throw new Exception("GetHLECacheReport expects a string message"); - uint Length = Data[1]; - IntPtr MessagePtr = new IntPtr(Data[2]); + var Length = Data.Pop(); ; + var MessagePtr = new IntPtr(Data.Pop()); Report.FileName = Context.OwningProcess.ReadString(MessagePtr, Length); @@ -57,20 +78,19 @@ namespace CxbxDebugger public IntPtr Address { get; set; } } - public static KernelPatch GetKernelPatchReport(DebuggerThread Context, uint[] Data) + public static KernelPatch GetKernelPatchReport(DebuggerThread Context, DataProcessor Data) { KernelPatch Report = new KernelPatch(); - StringType Type = (StringType)Data[0]; - + var Type = (StringType)Data.Pop(); if (Type != StringType.CHAR) throw new Exception("GetKernelPatchReport expects a string message"); - uint Length = Data[1]; - IntPtr MessagePtr = new IntPtr(Data[2]); + var Length = Data.Pop(); + var MessagePtr = new IntPtr(Data.Pop()); Report.Name = Context.OwningProcess.ReadString(MessagePtr, Length); - Report.Address = new IntPtr(Data[3]); + Report.Address = new IntPtr(Data.Pop()); return Report; } @@ -82,23 +102,21 @@ namespace CxbxDebugger public bool Succeeded { get; set; } } - public static FileOpened GetFileOpenedReport(DebuggerThread Context, uint[] Data) + public static FileOpened GetFileOpenedReport(DebuggerThread Context, DataProcessor Data) { FileOpened Report = new FileOpened(); - Report.Handle = new IntPtr(Data[0]); - - StringType Type = (StringType)Data[1]; + Report.Handle = new IntPtr(Data.Pop()); + var Type = (StringType)Data.Pop(); if (Type != StringType.WCHAR) throw new Exception("GetFileOpenedReport expects a widestring message"); - uint Length = Data[2]; - IntPtr MessagePtr = new IntPtr(Data[3]); + var Length = Data.Pop(); + var MessagePtr = new IntPtr(Data.Pop()); Report.FileName = Context.OwningProcess.ReadWString(MessagePtr, Length); - - Report.Succeeded = Data[4] != 0; + Report.Succeeded = Data.Pop() != 0; return Report; } @@ -110,13 +128,13 @@ namespace CxbxDebugger public uint Offset { get; set; } } - public static FileRead GetFileReadReport(DebuggerThread Context, uint[] Data) + public static FileRead GetFileReadReport(DebuggerThread Context, DataProcessor Data) { FileRead Report = new FileRead(); - Report.Handle = new IntPtr(Data[0]); - Report.Length = Data[1]; - Report.Offset = Data[2]; + Report.Handle = new IntPtr(Data.Pop()); + Report.Length = Data.Pop(); + Report.Offset = Data.Pop(); return Report; } @@ -128,13 +146,13 @@ namespace CxbxDebugger public uint Offset { get; set; } } - public static FileWrite GetFileWriteReport(DebuggerThread Context, uint[] Data) + public static FileWrite GetFileWriteReport(DebuggerThread Context, DataProcessor Data) { FileWrite Report = new FileWrite(); - Report.Handle = new IntPtr(Data[0]); - Report.Length = Data[1]; - Report.Offset = Data[2]; + Report.Handle = new IntPtr(Data.Pop()); + Report.Length = Data.Pop(); + Report.Offset = Data.Pop(); return Report; } @@ -144,18 +162,20 @@ namespace CxbxDebugger public IntPtr Handle { get; set; } } - public static FileClosed GetFileClosedReport(DebuggerThread Context, uint[] Data) + public static FileClosed GetFileClosedReport(DebuggerThread Context, DataProcessor Data) { // TODO: Restructure this library uint InvalidHandle = (uint)VsChromium.Core.Win32.Handles.NativeMethods.INVALID_HANDLE_VALUE; + var Handle = Data.Pop(); + // Skip invalid file handles - if (Data[0] == InvalidHandle) + if (Handle == InvalidHandle) return null; FileClosed Report = new FileClosed(); - Report.Handle = new IntPtr(Data[0]); + Report.Handle = new IntPtr(Handle); return Report; } @@ -169,59 +189,78 @@ namespace CxbxDebugger public IntPtr ParameterBase { get; set; } } - public static ExceptionHandledQuery GetExceptionHandledQuery(DebuggerThread Context, uint[] Data) + public static ExceptionHandledQuery GetExceptionHandledQuery(DebuggerThread Context, DataProcessor Data) { ExceptionHandledQuery Query = new ExceptionHandledQuery(); - Query.ReponseAddr = new IntPtr(Data[0]); - Query.ExceptionAddress = Data[1]; - Query.ExceptionCode = Data[2]; - Query.ParameterCount = Data[3]; - Query.ParameterBase = new IntPtr(Data[4]); + Query.ReponseAddr = new IntPtr(Data.Pop()); + Query.ExceptionAddress = Data.Pop(); + Query.ExceptionCode = Data.Pop(); + Query.ParameterCount = Data.Pop(); + Query.ParameterBase = new IntPtr(Data.Pop()); return Query; } public class DebuggerInit { - public uint TitleID { get; set; } public string Title { get; set; } } - public static DebuggerInit GetDebuggerInitReport(DebuggerThread Context, uint[] Data) + public static DebuggerInit GetDebuggerInitReport(DebuggerThread Context, DataProcessor Data) { DebuggerInit Report = new DebuggerInit(); - Report.TitleID = Data[0]; - - StringType Type = (StringType)Data[1]; + StringType Type = (StringType)Data.Pop(); if (Type != StringType.CHAR) throw new Exception("GetDebuggerInitReport expects a string message"); - uint Length = Data[2]; - IntPtr MessagePtr = new IntPtr(Data[3]); + uint Length = Data.Pop(); + IntPtr MessagePtr = new IntPtr(Data.Pop()); Report.Title = Context.OwningProcess.ReadString(MessagePtr, Length); return Report; } + public class DebuggerNewTarget + { + public string CommandLine { get; set; } + } + + public static DebuggerNewTarget GetDebuggerNewTargetReport(DebuggerThread Context, DataProcessor Data) + { + var Report = new DebuggerNewTarget(); + + StringType Type = (StringType)Data.Pop(); + + if (Type != StringType.CHAR) + throw new Exception("GetDebuggerInitReport expects a string message"); + + uint Length = Data.Pop(); + IntPtr MessagePtr = new IntPtr(Data.Pop()); + + Report.CommandLine = Context.OwningProcess.ReadString(MessagePtr, Length); + + return Report; + } + public class MSVCThreadName { public string Name { get; set; } public uint ThreadId { get; set; } } - public static MSVCThreadName GetMSVCThreadName(DebuggerThread Context, uint[] Data) + public static MSVCThreadName GetMSVCThreadName(DebuggerThread Context, DataProcessor Data) { - uint Type = Data[0]; + var Type = Data.Pop(); if (Type != 0x1000) return null; string ReportName = ""; - IntPtr MessagePtr = new IntPtr(Data[1]); + IntPtr MessagePtr = new IntPtr(Data.Pop()); if (MessagePtr != IntPtr.Zero) { ReportName = Context.OwningProcess.ReadString(MessagePtr); @@ -230,7 +269,7 @@ namespace CxbxDebugger MSVCThreadName Report = new MSVCThreadName(); Report.Name = ReportName; - Report.ThreadId = Data[2]; + Report.ThreadId = Data.Pop(); return Report; }