diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallback.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallback.cs index 5ba869e747..99d9b833dc 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallback.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallback.cs @@ -212,7 +212,8 @@ namespace DebuggerLibrary { EnterCallback("DebuggerError", pProcess); - System.Windows.Forms.MessageBox.Show("Debugger error: \nHR = " + errorHR.ToString() + "\nCode = " + errorCode.ToString()); + string errorText = String.Format("Debugger error: \nHR = 0x{0:X} \nCode = 0x{1:X}", errorHR, errorCode); + System.Windows.Forms.MessageBox.Show(errorText); ExitCallback_Paused(PausedReason.DebuggerError); } @@ -359,7 +360,7 @@ namespace DebuggerLibrary debugger.RemoveProcess(process); if (debugger.Processes.Count == 0) { - debugger.ResetEnvironment(); + debugger.TerminateDebugger(); } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/NativeMethods.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/NativeMethods.cs index 0caf4974d9..6707d47152 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/NativeMethods.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/NativeMethods.cs @@ -26,5 +26,8 @@ namespace DebuggerLibrary [DllImport("mscoree.dll", CharSet=CharSet.Unicode)] public static extern int GetCORVersion([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName, Int32 cchBuffer, out Int32 dwLength); + + [DllImport("mscoree.dll", CharSet=CharSet.Unicode)] + public static extern int GetRequestedRuntimeVersion(string exeFilename, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pVersion, Int32 cchBuffer, out Int32 dwLength); } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs index a302d811a8..e0400e8bbc 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs @@ -54,35 +54,58 @@ namespace DebuggerLibrary public NDebugger() { requiredApartmentState = System.Threading.Thread.CurrentThread.GetApartmentState(); - - InitDebugger(); - ResetEnvironment(); - + this.ModuleLoaded += new EventHandler(SetBreakpointsInModule); } - ~NDebugger() //TODO + /// + /// Get the .NET version of the process that called this function + /// + public string GetDebuggerVersion() { - //corDebug.Terminate(); + int size; + NativeMethods.GetCORVersion(null, 0, out size); + StringBuilder sb = new StringBuilder(size); + int hr = NativeMethods.GetCORVersion(sb, sb.Capacity, out size); + return sb.ToString(); } - - internal void InitDebugger() + + /// + /// Get the .NET version of a given program - eg. "v1.1.4322" + /// + public string GetProgramVersion(string exeFilename) { - int size; - NativeMethods.GetCORVersion(null, 0, out size); - StringBuilder sb = new StringBuilder(size); - int hr = NativeMethods.GetCORVersion(sb, sb.Capacity, out size); - - NativeMethods.CreateDebuggingInterfaceFromVersion(3, sb.ToString(), out corDebug); - - managedCallback = new ManagedCallback(this); - managedCallbackProxy = new ManagedCallbackProxy(this, managedCallback); - + int size; + NativeMethods.GetRequestedRuntimeVersion(exeFilename, null, 0, out size); + StringBuilder sb = new StringBuilder(size); + int hr = NativeMethods.GetRequestedRuntimeVersion(exeFilename, sb, sb.Capacity, out size); + return sb.ToString(); + } + + /// + /// Prepares the debugger + /// + /// Version of the program to debug - eg. "v1.1.4322" + /// If null, the version of the executing process will be used + internal void InitDebugger(string debuggeeVersion) + { + string version; + if (debuggeeVersion != null) { + version = debuggeeVersion; + } else { + version = GetDebuggerVersion(); + } + + NativeMethods.CreateDebuggingInterfaceFromVersion(3, version, out corDebug); + + managedCallback = new ManagedCallback(this); + managedCallbackProxy = new ManagedCallbackProxy(this, managedCallback); + corDebug.Initialize(); corDebug.SetManagedHandler(managedCallbackProxy); } - internal void ResetEnvironment() + internal void TerminateDebugger() { ClearModules(); @@ -95,6 +118,10 @@ namespace DebuggerLibrary evalQueue = new EvalQueue(this); TraceMessage("Reset done"); + + corDebug.Terminate(); + + TraceMessage("ICorDebug terminated"); } @@ -140,6 +167,7 @@ namespace DebuggerLibrary public void Start(string filename, string workingDirectory, string arguments) { + InitDebugger(GetProgramVersion(filename)); Process process = Process.CreateProcess(this, filename, workingDirectory, arguments); AddProcess(process); } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Modules/Module.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Modules/Module.cs index 0654ab8f8d..8979d2b8c9 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Modules/Module.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Modules/Module.cs @@ -100,7 +100,9 @@ namespace DebuggerLibrary public bool JMCStatus { set { uint unused = 0; - ((ICorDebugModule2)corModule).SetJMCStatus(value?1:0, 0, ref unused); + if (corModule is ICorDebugModule2) { // Is the debuggee .NET 2.0? + ((ICorDebugModule2)corModule).SetJMCStatus(value?1:0, 0, ref unused); + } } } @@ -152,7 +154,9 @@ namespace DebuggerLibrary public void ApplyChanges(byte[] metadata, byte[] il) { - (corModule as ICorDebugModule2).ApplyChanges((uint)metadata.Length, metadata, (uint)il.Length, il); + if (corModule is ICorDebugModule2) { // Is the debuggee .NET 2.0? + (corModule as ICorDebugModule2).ApplyChanges((uint)metadata.Length, metadata, (uint)il.Length, il); + } } public void Dispose() diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs index 6e0ae39a80..dfcf744641 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs @@ -167,8 +167,10 @@ namespace DebuggerLibrary if (stepIn) { corILFrame.CreateStepper(out stepper); - stepper.SetUnmappedStopMask(CorDebugUnmappedStop.STOP_NONE); - (stepper as ICorDebugStepper2).SetJMC(1 /* true */); + if (stepper is ICorDebugStepper2) { // Is the debuggee .NET 2.0? + stepper.SetUnmappedStopMask(CorDebugUnmappedStop.STOP_NONE); + (stepper as ICorDebugStepper2).SetJMC(1 /* true */); + } fixed (int* ranges = nextSt.StepRanges) { stepper.StepRange(1 /* true - step in*/ , (IntPtr)ranges, (uint)nextSt.StepRanges.Length / 2); @@ -178,12 +180,14 @@ namespace DebuggerLibrary } // Mind that step in which ends in code without symblols is cotinued - // so the next step out ensures that we atleast do step over + // so the next step over ensures that we atleast do step over corILFrame.CreateStepper(out stepper); - stepper.SetUnmappedStopMask(CorDebugUnmappedStop.STOP_NONE); - (stepper as ICorDebugStepper2).SetJMC(1 /* true */); + if (stepper is ICorDebugStepper2) { // Is the debuggee .NET 2.0? + stepper.SetUnmappedStopMask(CorDebugUnmappedStop.STOP_NONE); + (stepper as ICorDebugStepper2).SetJMC(1 /* true */); + } fixed (int* ranges = nextSt.StepRanges) { stepper.StepRange(0 /* false - step over*/ , (IntPtr)ranges, (uint)nextSt.StepRanges.Length / 2); diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs index 5afb71f30e..a1032814d2 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs @@ -134,7 +134,9 @@ namespace DebuggerLibrary public void InterceptCurrentException() { - ((ICorDebugThread2)corThread).InterceptCurrentException(LastFunction.CorILFrame); + if (corThread is ICorDebugThread2) { // Is the debuggee .NET 2.0? + ((ICorDebugThread2)corThread).InterceptCurrentException(LastFunction.CorILFrame); + } process.Continue(); }