This commit is contained in:
mterwoord_cp 2009-11-01 18:50:19 +00:00
parent aaf46a8d8e
commit df5e23225c
12 changed files with 375 additions and 69 deletions

View file

@ -19,65 +19,71 @@ namespace Cosmos.Build.MSBuild {
{ {
buildFailed = false; buildFailed = false;
Log.LogMessage(MessageImportance.High, "Building Cosmos System Image"); //Log.LogMessage(MessageImportance.High, "Building Cosmos System Image");
String buildOutputPath; //String buildOutputPath;
String buildKernelAssemblyPath; //String buildKernelAssemblyPath;
Boolean buildUseInternalAssembler; //Boolean buildUseInternalAssembler;
TargetHost buildTarget; //TargetHost buildTarget;
Framework buildFramework; //Framework buildFramework;
if (System.IO.Path.IsPathRooted(this.OutputPath) == false) //if (System.IO.Path.IsPathRooted(this.OutputPath) == false)
{ buildOutputPath = (new System.IO.DirectoryInfo(this.OutputPath)).FullName; } //{ buildOutputPath = (new System.IO.DirectoryInfo(this.OutputPath)).FullName; }
else //else
{ buildOutputPath = this.OutputPath; } //{ buildOutputPath = this.OutputPath; }
buildKernelAssemblyPath = System.IO.Path.Combine(buildOutputPath, this.KernelAssembly); //buildKernelAssemblyPath = System.IO.Path.Combine(buildOutputPath, this.KernelAssembly);
buildUseInternalAssembler = this.UseInternalAssembler; //buildUseInternalAssembler = this.UseInternalAssembler;
buildFramework = EnumValue.Parse(this.Framework, Cosmos.Build.Common.Framework.MicrosoftNET); //buildFramework = EnumValue.Parse(this.Framework, Cosmos.Build.Common.Framework.MicrosoftNET);
buildTarget = EnumValue.Parse(this.BuildTarget, TargetHost.QEMU); //buildTarget = EnumValue.Parse(this.BuildTarget, TargetHost.QEMU);
Log.LogMessage(MessageImportance.High, "Output Path: {0}", buildOutputPath); //Log.LogMessage(MessageImportance.High, "Output Path: {0}", buildOutputPath);
Log.LogMessage(MessageImportance.High, "Kernal Assembly: {0}", buildKernelAssemblyPath); //Log.LogMessage(MessageImportance.High, "Kernal Assembly: {0}", buildKernelAssemblyPath);
Log.LogMessage(MessageImportance.High, "Use Internal Assembler: {0}", buildUseInternalAssembler); //Log.LogMessage(MessageImportance.High, "Use Internal Assembler: {0}", buildUseInternalAssembler);
Log.LogMessage(MessageImportance.High, "Framework: {0}", buildFramework); //Log.LogMessage(MessageImportance.High, "Framework: {0}", buildFramework);
Log.LogMessage(MessageImportance.High, "Target: {0}", buildTarget); //Log.LogMessage(MessageImportance.High, "Target: {0}", buildTarget);
System.Reflection.Assembly kernelAssembly; //System.Reflection.Assembly kernelAssembly;
var builtEvent = new System.Threading.AutoResetEvent(false); //var builtEvent = new System.Threading.AutoResetEvent(false);
var builder = new Builder(); //var builder = new Builder();
var xOptions = BuildOptions.Load(); //var xOptions = BuildOptions.Load();
xOptions.Target = "ISO"; //xOptions.Target = "ISO";
//builder.UseInternalAssembler = this.UseInternalAssembler; ////builder.UseInternalAssembler = this.UseInternalAssembler;
builder.CompileCompleted += delegate { builtEvent.Set(); }; //builder.BuildCompleted += delegate { builtEvent.Set(); };
builder.LogMessage += delegate(LogSeverityEnum aSeverity, string aMessage) //builder.LogMessage += delegate(LogSeverityEnum aSeverity, string aMessage)
{ // {
switch (aSeverity) // switch (aSeverity)
{ // {
case LogSeverityEnum.Informational: // case LogSeverityEnum.Informational:
Log.LogMessage(aMessage); // Log.LogMessage(aMessage);
break; // break;
case LogSeverityEnum.Warning: // case LogSeverityEnum.Warning:
Log.LogWarning(aMessage); // Log.LogWarning(aMessage);
break; // break;
case LogSeverityEnum.Error: // case LogSeverityEnum.Error:
Log.LogError(aMessage); // Log.LogError(aMessage);
this.buildFailed = true; // this.buildFailed = true;
break; // break;
} // }
}; // };
kernelAssembly = System.Reflection.Assembly.LoadFile(Path.Combine(buildOutputPath, this.KernelAssembly)); //kernelAssembly = System.Reflection.Assembly.LoadFile(Path.Combine(buildOutputPath, this.KernelAssembly));
builder.TargetAssembly = kernelAssembly; //builder.TargetAssembly = kernelAssembly;
builder.BeginCompile(xOptions); //builder.BeginCompile(xOptions);
builtEvent.WaitOne(); //builtEvent.WaitOne();
return (this.buildFailed == false) && !builder.HasErrors; //if (!builder.HasErrors)
//{
// File.Copy(Path.Combine(builder.BuildPath, "Cosmos.iso"), Path.Combine(OutputPath, Path.GetFileNameWithoutExtension(KernelAssembly) + ".iso"), true);
//}
//return (this.buildFailed == false) && !builder.HasErrors;
Log.LogWarning("Not rebuilding image");
return true;
} }
[Required] [Required]

View file

@ -5,6 +5,6 @@ using System.Text;
namespace Cosmos.Debug.Common { namespace Cosmos.Debug.Common {
public class Consts { public class Consts {
public const string EngineGUID = "{DFE8F1F6-691C-4c08-8FFA-54551AD8FEAF}"; public const string EngineGUID = "DFE8F1F6-691C-4c08-8FFA-54551AD8FEAF";
} }
} }

View file

@ -22,7 +22,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// //
// IDebugEngineProgram2: This interface provides simultanious debugging of multiple threads in a debuggee. // IDebugEngineProgram2: This interface provides simultanious debugging of multiple threads in a debuggee.
[ComVisible(true)] [ComVisible(false)]
[Guid("D3788C06-09DE-46b3-B61B-A8A56ADA8B99")] [Guid("D3788C06-09DE-46b3-B61B-A8A56ADA8B99")]
public class AD7Engine : IDebugEngine2, IDebugEngineLaunch2, IDebugProgram3, IDebugEngineProgram2 { public class AD7Engine : IDebugEngine2, IDebugEngineLaunch2, IDebugProgram3, IDebugEngineProgram2 {
// used to send events to the debugger. Some examples of these events are thread create, exception thrown, module load. // used to send events to the debugger. Some examples of these events are thread create, exception thrown, module load.
@ -42,19 +42,22 @@ namespace Cosmos.Debug.VSDebugEngine {
// A unique identifier for the program being debugged. // A unique identifier for the program being debugged.
Guid m_ad7ProgramId; Guid m_ad7ProgramId;
public static string ID; public const string ID = "FA1DA3A6-66FF-4c65-B077-E65F7164EF83";
static AD7Engine() { static AD7Engine() {
ID = Cosmos.Debug.Common.Consts.EngineGUID; Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
} }
public AD7Engine() { public AD7Engine() {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
m_breakpointManager = new BreakpointManager(this); m_breakpointManager = new BreakpointManager(this);
//Worker.Initialize(); //Worker.Initialize();
} }
~AD7Engine() { ~AD7Engine() {
if (m_pollThread != null) { Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
if (m_pollThread != null)
{
m_pollThread.Close(); m_pollThread.Close();
} }
} }
@ -71,6 +74,7 @@ namespace Cosmos.Debug.VSDebugEngine {
public string GetAddressDescription(uint ip) public string GetAddressDescription(uint ip)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
// DebuggedModule module = m_debuggedProcess.ResolveAddress(ip); // DebuggedModule module = m_debuggedProcess.ResolveAddress(ip);
return "";// EngineUtils.GetAddressDescription(module, ip); return "";// EngineUtils.GetAddressDescription(module, ip);
@ -81,6 +85,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// Attach the debug engine to a program. // Attach the debug engine to a program.
int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, uint dwReason) int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, uint dwReason)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
//System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId); //System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
System.Diagnostics.Debug.Assert(m_ad7ProgramId == Guid.Empty); System.Diagnostics.Debug.Assert(m_ad7ProgramId == Guid.Empty);
@ -153,6 +158,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// When the break is complete, an AsyncBreakComplete event will be sent back to the debugger. // When the break is complete, an AsyncBreakComplete event will be sent back to the debugger.
int IDebugEngine2.CauseBreak() int IDebugEngine2.CauseBreak()
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
//System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId); //System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
return ((IDebugProgram2)this).CauseBreak(); return ((IDebugProgram2)this).CauseBreak();
} }
@ -162,6 +168,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// It responds to that event by shutting down the engine. // It responds to that event by shutting down the engine.
int IDebugEngine2.ContinueFromSynchronousEvent(IDebugEvent2 eventObject) int IDebugEngine2.ContinueFromSynchronousEvent(IDebugEvent2 eventObject)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
//System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId); //System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
try try
@ -196,6 +203,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// a location in the debuggee. // a location in the debuggee.
int IDebugEngine2.CreatePendingBreakpoint(IDebugBreakpointRequest2 pBPRequest, out IDebugPendingBreakpoint2 ppPendingBP) int IDebugEngine2.CreatePendingBreakpoint(IDebugBreakpointRequest2 pBPRequest, out IDebugPendingBreakpoint2 ppPendingBP)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
System.Diagnostics.Debug.Assert(m_breakpointManager != null); System.Diagnostics.Debug.Assert(m_breakpointManager != null);
ppPendingBP = null; ppPendingBP = null;
@ -215,6 +223,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// clean up all references to the program and send a program destroy event. // clean up all references to the program and send a program destroy event.
int IDebugEngine2.DestroyProgram(IDebugProgram2 pProgram) int IDebugEngine2.DestroyProgram(IDebugProgram2 pProgram)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
// Tell the SDM that the engine knows that the program is exiting, and that the // Tell the SDM that the engine knows that the program is exiting, and that the
// engine will send a program destroy. We do this because the Win32 debug api will always // engine will send a program destroy. We do this because the Win32 debug api will always
// tell us that the process exited, and otherwise we have a race condition. // tell us that the process exited, and otherwise we have a race condition.
@ -224,6 +233,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// Gets the GUID of the DE. // Gets the GUID of the DE.
int IDebugEngine2.GetEngineId(out Guid guidEngine) { int IDebugEngine2.GetEngineId(out Guid guidEngine) {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
guidEngine = new Guid(ID); guidEngine = new Guid(ID);
return VSConstants.S_OK; return VSConstants.S_OK;
} }
@ -232,6 +242,8 @@ namespace Cosmos.Debug.VSDebugEngine {
// The sample engine does not support exceptions in the debuggee so this method is not actually implemented. // The sample engine does not support exceptions in the debuggee so this method is not actually implemented.
int IDebugEngine2.RemoveAllSetExceptions(ref Guid guidType) int IDebugEngine2.RemoveAllSetExceptions(ref Guid guidType)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
return VSConstants.S_OK; return VSConstants.S_OK;
} }
@ -239,6 +251,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// The sample engine does not support exceptions in the debuggee so this method is not actually implemented. // The sample engine does not support exceptions in the debuggee so this method is not actually implemented.
int IDebugEngine2.RemoveSetException(EXCEPTION_INFO[] pException) int IDebugEngine2.RemoveSetException(EXCEPTION_INFO[] pException)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
// The sample engine will always stop on all exceptions. // The sample engine will always stop on all exceptions.
return VSConstants.S_OK; return VSConstants.S_OK;
@ -248,6 +261,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// The sample engine does not support exceptions in the debuggee so this method is not actually implemented. // The sample engine does not support exceptions in the debuggee so this method is not actually implemented.
int IDebugEngine2.SetException(EXCEPTION_INFO[] pException) int IDebugEngine2.SetException(EXCEPTION_INFO[] pException)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
return VSConstants.S_OK; return VSConstants.S_OK;
} }
@ -256,6 +270,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// strings returned by the DE are properly localized. The sample engine is not localized so this is not implemented. // strings returned by the DE are properly localized. The sample engine is not localized so this is not implemented.
int IDebugEngine2.SetLocale(ushort wLangID) int IDebugEngine2.SetLocale(ushort wLangID)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
return VSConstants.S_OK; return VSConstants.S_OK;
} }
@ -263,6 +278,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// This method can forward the call to the appropriate form of the Debugging SDK Helpers function, SetMetric. // This method can forward the call to the appropriate form of the Debugging SDK Helpers function, SetMetric.
int IDebugEngine2.SetMetric(string pszMetric, object varValue) int IDebugEngine2.SetMetric(string pszMetric, object varValue)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
// The sample engine does not need to understand any metric settings. // The sample engine does not need to understand any metric settings.
return VSConstants.S_OK; return VSConstants.S_OK;
} }
@ -271,6 +287,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// This allows the debugger to tell the engine where that location is. // This allows the debugger to tell the engine where that location is.
int IDebugEngine2.SetRegistryRoot(string pszRegistryRoot) int IDebugEngine2.SetRegistryRoot(string pszRegistryRoot)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
// The sample engine does not read settings from the registry. // The sample engine does not read settings from the registry.
return VSConstants.S_OK; return VSConstants.S_OK;
} }
@ -282,6 +299,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// Determines if a process can be terminated. // Determines if a process can be terminated.
int IDebugEngineLaunch2.CanTerminateProcess(IDebugProcess2 process) int IDebugEngineLaunch2.CanTerminateProcess(IDebugProcess2 process)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
//System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId); //System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
//System.Diagnostics.Debug.Assert(m_pollThread != null); //System.Diagnostics.Debug.Assert(m_pollThread != null);
//System.Diagnostics.Debug.Assert(m_engineCallback != null); //System.Diagnostics.Debug.Assert(m_engineCallback != null);
@ -317,6 +335,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// in which case Visual Studio uses the IDebugEngineLaunch2::LaunchSuspended method // in which case Visual Studio uses the IDebugEngineLaunch2::LaunchSuspended method
// The IDebugEngineLaunch2::ResumeProcess method is called to start the process after the process has been successfully launched in a suspended state. // The IDebugEngineLaunch2::ResumeProcess method is called to start the process after the process has been successfully launched in a suspended state.
int IDebugEngineLaunch2.LaunchSuspended(string aPszServer, IDebugPort2 aPort, string aExe, string aArgs, string aDir, string aEnv, string aOptions, uint aLaunchFlags, uint aStdInputHandle, uint aStdOutputHandle, uint hStdError, IDebugEventCallback2 aAD7Callback, out IDebugProcess2 aProcess) { int IDebugEngineLaunch2.LaunchSuspended(string aPszServer, IDebugPort2 aPort, string aExe, string aArgs, string aDir, string aEnv, string aOptions, uint aLaunchFlags, uint aStdInputHandle, uint aStdOutputHandle, uint hStdError, IDebugEventCallback2 aAD7Callback, out IDebugProcess2 aProcess) {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
//System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId); //System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
//System.Diagnostics.Debug.Assert(m_pollThread == null); //System.Diagnostics.Debug.Assert(m_pollThread == null);
//System.Diagnostics.Debug.Assert(m_engineCallback == null); //System.Diagnostics.Debug.Assert(m_engineCallback == null);
@ -334,16 +353,26 @@ namespace Cosmos.Debug.VSDebugEngine {
// Complete the win32 attach on the poll thread // Complete the win32 attach on the poll thread
//m_pollThread.RunOperation(new Operation(delegate //m_pollThread.RunOperation(new Operation(delegate
//{ //{
// m_debuggedProcess = Worker.LaunchProcess(m_engineCallback, processLaunchInfo); // var m_debuggedProcess = Worker.LaunchProcess(m_engineCallback, processLaunchInfo);
//})); //}));
var xTarget = new Cosmos.Build.Launch.Target.QEMU(); var xTarget = new Cosmos.Build.Launch.Target.QEMU();
var xProcessID = new AD_PROCESS_ID(); var xProcess = new AD7Process(aExe);
xProcessID.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM; aProcess = xProcess;
m_ad7ProgramId = xProcess.mID;
//var xProcessID = new AD_PROCESS_ID();
//xProcessID.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM;
//adProcessId.dwProcessId = (uint)m_debuggedProcess.Id; //adProcessId.dwProcessId = (uint)m_debuggedProcess.Id;
AD7EngineCreateEvent.Send(this);
AD7ProgramCreateEvent.Send(this);
mThread = new AD7Thread(this);
AD7ThreadCreateEvent.Send(this);
mModule = new AD7Module();
AD7ModuleLoadEvent.Send(this, mModule, true);
Callback.OnLoadComplete(mThread);
EngineUtils.RequireOk(aPort.GetProcess(xProcessID, out aProcess)); //EngineUtils.RequireOk(aPort.GetProcess(xProcessID, out aProcess));
return VSConstants.S_OK; return VSConstants.S_OK;
} }
@ -352,9 +381,13 @@ namespace Cosmos.Debug.VSDebugEngine {
} }
} }
private AD7Module mModule;
private AD7Thread mThread;
// Resume a process launched by IDebugEngineLaunch2.LaunchSuspended // Resume a process launched by IDebugEngineLaunch2.LaunchSuspended
int IDebugEngineLaunch2.ResumeProcess(IDebugProcess2 process) int IDebugEngineLaunch2.ResumeProcess(IDebugProcess2 process)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
//System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId); //System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
//System.Diagnostics.Debug.Assert(m_pollThread != null); //System.Diagnostics.Debug.Assert(m_pollThread != null);
//System.Diagnostics.Debug.Assert(m_engineCallback != null); //System.Diagnostics.Debug.Assert(m_engineCallback != null);
@ -410,6 +443,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// The debugger will call IDebugEngineLaunch2::CanTerminateProcess before calling this method. // The debugger will call IDebugEngineLaunch2::CanTerminateProcess before calling this method.
int IDebugEngineLaunch2.TerminateProcess(IDebugProcess2 process) int IDebugEngineLaunch2.TerminateProcess(IDebugProcess2 process)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
//System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId); //System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
//System.Diagnostics.Debug.Assert(m_pollThread != null); //System.Diagnostics.Debug.Assert(m_pollThread != null);
//System.Diagnostics.Debug.Assert(m_engineCallback != null); //System.Diagnostics.Debug.Assert(m_engineCallback != null);
@ -444,6 +478,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// Determines if a debug engine (DE) can detach from the program. // Determines if a debug engine (DE) can detach from the program.
public int CanDetach() public int CanDetach()
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
// The sample engine always supports detach // The sample engine always supports detach
return VSConstants.S_OK; return VSConstants.S_OK;
} }
@ -452,6 +487,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// breakmode. // breakmode.
public int CauseBreak() public int CauseBreak()
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
//System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId); //System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
m_pollThread.RunOperation(new Operation(delegate m_pollThread.RunOperation(new Operation(delegate
@ -467,6 +503,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// and the debugger does not want to actually enter break mode. // and the debugger does not want to actually enter break mode.
public int Continue(IDebugThread2 pThread) public int Continue(IDebugThread2 pThread)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
//System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId); //System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
AD7Thread thread = (AD7Thread)pThread; AD7Thread thread = (AD7Thread)pThread;
@ -483,6 +520,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// or when one of the Detach commands are executed in the UI. // or when one of the Detach commands are executed in the UI.
public int Detach() public int Detach()
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
//System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId); //System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
m_breakpointManager.ClearBoundBreakpoints(); m_breakpointManager.ClearBoundBreakpoints();
@ -498,6 +536,8 @@ namespace Cosmos.Debug.VSDebugEngine {
// Enumerates the code contexts for a given position in a source file. // Enumerates the code contexts for a given position in a source file.
public int EnumCodeContexts(IDebugDocumentPosition2 pDocPos, out IEnumDebugCodeContexts2 ppEnum) public int EnumCodeContexts(IDebugDocumentPosition2 pDocPos, out IEnumDebugCodeContexts2 ppEnum)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
throw new Exception("The method or operation is not implemented."); throw new Exception("The method or operation is not implemented.");
} }
@ -505,6 +545,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// function to step into. This is not something that the SampleEngine supports. // function to step into. This is not something that the SampleEngine supports.
public int EnumCodePaths(string hint, IDebugCodeContext2 start, IDebugStackFrame2 frame, int fSource, out IEnumCodePaths2 pathEnum, out IDebugCodeContext2 safetyContext) public int EnumCodePaths(string hint, IDebugCodeContext2 start, IDebugStackFrame2 frame, int fSource, out IEnumCodePaths2 pathEnum, out IDebugCodeContext2 safetyContext)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
pathEnum = null; pathEnum = null;
safetyContext = null; safetyContext = null;
return VSConstants.E_NOTIMPL; return VSConstants.E_NOTIMPL;
@ -513,6 +554,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// EnumModules is called by the debugger when it needs to enumerate the modules in the program. // EnumModules is called by the debugger when it needs to enumerate the modules in the program.
public int EnumModules(out IEnumDebugModules2 ppEnum) public int EnumModules(out IEnumDebugModules2 ppEnum)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
//System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId); //System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
//DebuggedModule[] modules = m_debuggedProcess.GetModules(); //DebuggedModule[] modules = m_debuggedProcess.GetModules();
@ -531,6 +573,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// EnumThreads is called by the debugger when it needs to enumerate the threads in the program. // EnumThreads is called by the debugger when it needs to enumerate the threads in the program.
public int EnumThreads(out IEnumDebugThreads2 ppEnum) public int EnumThreads(out IEnumDebugThreads2 ppEnum)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
//System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId); //System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
//DebuggedThread[] threads = m_debuggedProcess.GetThreads(); //DebuggedThread[] threads = m_debuggedProcess.GetThreads();
@ -555,6 +598,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// The sample engine does not support this // The sample engine does not support this
public int GetDebugProperty(out IDebugProperty2 ppProperty) public int GetDebugProperty(out IDebugProperty2 ppProperty)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
throw new Exception("The method or operation is not implemented."); throw new Exception("The method or operation is not implemented.");
} }
@ -562,6 +606,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// The sample engine does not support dissassembly so it returns E_NOTIMPL // The sample engine does not support dissassembly so it returns E_NOTIMPL
public int GetDisassemblyStream(uint dwScope, IDebugCodeContext2 codeContext, out IDebugDisassemblyStream2 disassemblyStream) public int GetDisassemblyStream(uint dwScope, IDebugCodeContext2 codeContext, out IDebugDisassemblyStream2 disassemblyStream)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
disassemblyStream = null; disassemblyStream = null;
return VSConstants.E_NOTIMPL; return VSConstants.E_NOTIMPL;
} }
@ -569,6 +614,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// This method gets the Edit and Continue (ENC) update for this program. A custom debug engine always returns E_NOTIMPL // This method gets the Edit and Continue (ENC) update for this program. A custom debug engine always returns E_NOTIMPL
public int GetENCUpdate(out object update) public int GetENCUpdate(out object update)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
// The sample engine does not participate in managed edit & continue. // The sample engine does not participate in managed edit & continue.
update = null; update = null;
return VSConstants.S_OK; return VSConstants.S_OK;
@ -577,6 +623,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// Gets the name and identifier of the debug engine (DE) running this program. // Gets the name and identifier of the debug engine (DE) running this program.
public int GetEngineInfo(out string engineName, out Guid engineGuid) public int GetEngineInfo(out string engineName, out Guid engineGuid)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
engineName = ResourceStrings.EngineName; engineName = ResourceStrings.EngineName;
engineGuid = new Guid(AD7Engine.ID); engineGuid = new Guid(AD7Engine.ID);
return VSConstants.S_OK; return VSConstants.S_OK;
@ -586,6 +633,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// that was allocated when the program was executed. // that was allocated when the program was executed.
public int GetMemoryBytes(out IDebugMemoryBytes2 ppMemoryBytes) public int GetMemoryBytes(out IDebugMemoryBytes2 ppMemoryBytes)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
throw new Exception("The method or operation is not implemented."); throw new Exception("The method or operation is not implemented.");
} }
@ -593,6 +641,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// The name returned by this method is always a friendly, user-displayable name that describes the program. // The name returned by this method is always a friendly, user-displayable name that describes the program.
public int GetName(out string programName) public int GetName(out string programName)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
// The Sample engine uses default transport and doesn't need to customize the name of the program, // The Sample engine uses default transport and doesn't need to customize the name of the program,
// so return NULL. // so return NULL.
programName = null; programName = null;
@ -602,6 +651,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// Gets a GUID for this program. A debug engine (DE) must return the program identifier originally passed to the IDebugProgramNodeAttach2::OnAttach // Gets a GUID for this program. A debug engine (DE) must return the program identifier originally passed to the IDebugProgramNodeAttach2::OnAttach
// or IDebugEngine2::Attach methods. This allows identification of the program across debugger components. // or IDebugEngine2::Attach methods. This allows identification of the program across debugger components.
public int GetProgramId(out Guid guidProgramId) { public int GetProgramId(out Guid guidProgramId) {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
System.Diagnostics.Debug.Assert(m_ad7ProgramId != Guid.Empty); System.Diagnostics.Debug.Assert(m_ad7ProgramId != Guid.Empty);
guidProgramId = m_ad7ProgramId; guidProgramId = m_ad7ProgramId;
@ -611,12 +661,16 @@ namespace Cosmos.Debug.VSDebugEngine {
// This method is deprecated. Use the IDebugProcess3::Step method instead. // This method is deprecated. Use the IDebugProcess3::Step method instead.
public int Step(IDebugThread2 pThread, uint sk, uint Step) public int Step(IDebugThread2 pThread, uint sk, uint Step)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
return VSConstants.S_OK; return VSConstants.S_OK;
} }
// Terminates the program. // Terminates the program.
public int Terminate() public int Terminate()
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
// Because the sample engine is a native debugger, it implements IDebugEngineLaunch2, and will terminate // Because the sample engine is a native debugger, it implements IDebugEngineLaunch2, and will terminate
// the process in IDebugEngineLaunch2.TerminateProcess // the process in IDebugEngineLaunch2.TerminateProcess
return VSConstants.S_OK; return VSConstants.S_OK;
@ -625,6 +679,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// Writes a dump to a file. // Writes a dump to a file.
public int WriteDump(uint DUMPTYPE, string pszDumpUrl) public int WriteDump(uint DUMPTYPE, string pszDumpUrl)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
// The sample debugger does not support creating or reading mini-dumps. // The sample debugger does not support creating or reading mini-dumps.
return VSConstants.E_NOTIMPL; return VSConstants.E_NOTIMPL;
} }
@ -637,6 +692,7 @@ namespace Cosmos.Debug.VSDebugEngine {
// stepping state cleared. // stepping state cleared.
public int ExecuteOnThread(IDebugThread2 pThread) public int ExecuteOnThread(IDebugThread2 pThread)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
//System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId); //System.Diagnostics.Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
//AD7Thread thread = (AD7Thread)pThread; //AD7Thread thread = (AD7Thread)pThread;
@ -662,6 +718,8 @@ namespace Cosmos.Debug.VSDebugEngine {
// The sample engine only supports debugging native applications and therefore only has one program per-process // The sample engine only supports debugging native applications and therefore only has one program per-process
public int Stop() public int Stop()
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
throw new Exception("The method or operation is not implemented."); throw new Exception("The method or operation is not implemented.");
} }
@ -670,6 +728,8 @@ namespace Cosmos.Debug.VSDebugEngine {
// to do here. // to do here.
public int WatchForExpressionEvaluationOnThread(IDebugProgram2 pOriginatingProgram, uint dwTid, uint dwEvalFlags, IDebugEventCallback2 pExprCallback, int fWatch) public int WatchForExpressionEvaluationOnThread(IDebugProgram2 pOriginatingProgram, uint dwTid, uint dwEvalFlags, IDebugEventCallback2 pExprCallback, int fWatch)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
return VSConstants.S_OK; return VSConstants.S_OK;
} }
@ -677,6 +737,8 @@ namespace Cosmos.Debug.VSDebugEngine {
// The sample engine doesn't cooperate with other engines, so it has nothing to do here. // The sample engine doesn't cooperate with other engines, so it has nothing to do here.
public int WatchForThreadStep(IDebugProgram2 pOriginatingProgram, uint dwTid, int fWatch, uint dwFrame) public int WatchForThreadStep(IDebugProgram2 pOriginatingProgram, uint dwTid, int fWatch, uint dwFrame)
{ {
Trace.WriteLine(new StackTrace(false).GetFrame(0).GetMethod().GetFullName());
return VSConstants.S_OK; return VSConstants.S_OK;
} }

View file

@ -130,6 +130,12 @@ namespace Cosmos.Debug.VSDebugEngine
return VSConstants.S_OK; return VSConstants.S_OK;
} }
internal static void Send(AD7Engine engine, AD7Module aModule, bool fLoad)
{
var eventObject = new AD7ModuleLoadEvent(aModule, fLoad);
engine.Callback.Send(eventObject, IID, null);
}
} }
// This interface is sent by the debug engine (DE) to the session debug manager (SDM) when a program has run to completion // This interface is sent by the debug engine (DE) to the session debug manager (SDM) when a program has run to completion
@ -160,6 +166,11 @@ namespace Cosmos.Debug.VSDebugEngine
sealed class AD7ThreadCreateEvent : AD7AsynchronousEvent, IDebugThreadCreateEvent2 sealed class AD7ThreadCreateEvent : AD7AsynchronousEvent, IDebugThreadCreateEvent2
{ {
public const string IID = "2090CCFC-70C5-491D-A5E8-BAD2DD9EE3EA"; public const string IID = "2090CCFC-70C5-491D-A5E8-BAD2DD9EE3EA";
internal static void Send(AD7Engine engine)
{
var eventObject = new AD7ThreadCreateEvent();
engine.Callback.Send(eventObject, IID, null);
}
} }
// This interface is sent by the debug engine (DE) to the session debug manager (SDM) when a thread has exited. // This interface is sent by the debug engine (DE) to the session debug manager (SDM) when a thread has exited.
@ -193,6 +204,12 @@ namespace Cosmos.Debug.VSDebugEngine
public AD7LoadCompleteEvent() public AD7LoadCompleteEvent()
{ {
} }
internal static void Send(AD7Engine aEngine)
{
var xMessage = new AD7LoadCompleteEvent();
aEngine.Callback.Send(xMessage, IID, null);
}
} }
// This interface tells the session debug manager (SDM) that an asynchronous break has been successfully completed. // This interface tells the session debug manager (SDM) that an asynchronous break has been successfully completed.

View file

@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.Debugger.Interop;
using Microsoft.VisualStudio;
namespace Cosmos.Debug.VSDebugEngine
{
public class AD7Process: IDebugProcess2
{
private string mISO;
internal Guid mID = Guid.NewGuid();
public AD7Process(string aISOFile)
{
mISO = aISOFile;
}
#region IDebugProcess2 Members
public int Attach(IDebugEventCallback2 pCallback, Guid[] rgguidSpecificEngines, uint celtSpecificEngines, int[] rghrEngineAttach)
{
throw new NotImplementedException();
}
public int CanDetach()
{
throw new NotImplementedException();
}
public int CauseBreak()
{
throw new NotImplementedException();
}
public int Detach()
{
throw new NotImplementedException();
}
public int EnumPrograms(out IEnumDebugPrograms2 ppEnum)
{
throw new NotImplementedException();
}
public int EnumThreads(out IEnumDebugThreads2 ppEnum)
{
throw new NotImplementedException();
}
public int GetAttachedSessionName(out string pbstrSessionName)
{
throw new NotImplementedException();
}
public int GetInfo(uint Fields, PROCESS_INFO[] pProcessInfo)
{
throw new NotImplementedException();
}
public int GetName(uint gnType, out string pbstrName)
{
throw new NotImplementedException();
}
public int GetPhysicalProcessId(AD_PROCESS_ID[] pProcessId)
{
pProcessId[0].dwProcessId = (uint)mISO.Length;
pProcessId[0].guidProcessId = mID;
return VSConstants.S_OK;
}
public int GetPort(out IDebugPort2 ppPort)
{
throw new NotImplementedException();
}
public int GetProcessId(out Guid pguidProcessId)
{
pguidProcessId = mID;
return VSConstants.S_OK;
}
public int GetServer(out IDebugCoreServer2 ppServer)
{
throw new NotImplementedException();
}
public int Terminate()
{
return VSConstants.S_OK;
}
#endregion
}
}

View file

@ -83,6 +83,7 @@
<Compile Include="AD7.Impl\AD7Enums.cs" /> <Compile Include="AD7.Impl\AD7Enums.cs" />
<Compile Include="AD7.Impl\AD7Events.cs" /> <Compile Include="AD7.Impl\AD7Events.cs" />
<Compile Include="AD7.Impl\AD7Expression.cs" /> <Compile Include="AD7.Impl\AD7Expression.cs" />
<Compile Include="AD7.Impl\AD7Process.cs" />
<Compile Include="AD7.Impl\AD7ProgramProvider.cs" /> <Compile Include="AD7.Impl\AD7ProgramProvider.cs" />
<Compile Include="AD7.Impl\AD7StackFrame.cs" /> <Compile Include="AD7.Impl\AD7StackFrame.cs" />
<Compile Include="AD7.Impl\AD7MemoryAddress.cs" /> <Compile Include="AD7.Impl\AD7MemoryAddress.cs" />
@ -103,6 +104,7 @@
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<DependentUpon>ResourceStrings.resx</DependentUpon> <DependentUpon>ResourceStrings.resx</DependentUpon>
</Compile> </Compile>
<Compile Include="Utilities\Extensions.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="ResourceStrings.resx"> <EmbeddedResource Include="ResourceStrings.resx">

View file

@ -168,8 +168,10 @@ namespace Cosmos.Debug.VSDebugEngine
//Send(eventObject, AD7AsyncBreakCompleteEvent.IID, ad7Thread); //Send(eventObject, AD7AsyncBreakCompleteEvent.IID, ad7Thread);
} }
public void OnLoadComplete()//DebuggedThread thread) public void OnLoadComplete(AD7Thread aThread)
{ {
var xMsg = new AD7LoadCompleteEvent();
Send(xMsg, AD7LoadCompleteEvent.IID, aThread);
//AD7Thread ad7Thread = (AD7Thread)thread.Client; //AD7Thread ad7Thread = (AD7Thread)thread.Client;
//AD7LoadCompleteEvent eventObject = new AD7LoadCompleteEvent(); //AD7LoadCompleteEvent eventObject = new AD7LoadCompleteEvent();
//Send(eventObject, AD7LoadCompleteEvent.IID, ad7Thread); //Send(eventObject, AD7LoadCompleteEvent.IID, ad7Thread);

View file

@ -0,0 +1,123 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace System
{
public static class Extensions
{
public static string GetFullName(this MethodBase aMethod)
{
if (aMethod == null)
{
throw new ArgumentNullException("aMethod");
}
var xBuilder = new StringBuilder(256);
var xParts = aMethod.ToString().Split(' ');
var xParts2 = xParts.Skip(1).ToArray();
var xMethodInfo = aMethod as System.Reflection.MethodInfo;
if (xMethodInfo != null)
{
xBuilder.Append(GetFullName(xMethodInfo.ReturnType));
}
else
{
var xCtor = aMethod as ConstructorInfo;
if (xCtor != null)
{
xBuilder.Append(typeof(void).FullName);
}
else
{
xBuilder.Append(xParts[0]);
}
}
xBuilder.Append(" ");
xBuilder.Append(GetFullName(aMethod.DeclaringType));
xBuilder.Append(".");
xBuilder.Append(aMethod.Name);
if (aMethod.IsGenericMethod || aMethod.IsGenericMethodDefinition)
{
var xGenArgs = aMethod.GetGenericArguments();
if (xGenArgs.Length > 0)
{
xBuilder.Append("<");
for (int i = 0; i < xGenArgs.Length - 1; i++)
{
xBuilder.Append(GetFullName(xGenArgs[i]));
xBuilder.Append(", ");
}
xBuilder.Append(GetFullName(xGenArgs.Last()));
xBuilder.Append(">");
}
}
xBuilder.Append("(");
var xParams = aMethod.GetParameters();
for (var i = 0; i < xParams.Length; i++)
{
if (xParams[i].Name == "aThis" && i == 0)
{
continue;
}
xBuilder.Append(GetFullName(xParams[i].ParameterType));
if (i < (xParams.Length - 1))
{
xBuilder.Append(", ");
}
}
xBuilder.Append(")");
return String.Intern(xBuilder.ToString());
}
public static string GetFullName(this Type aType)
{
if (aType.IsGenericParameter)
{
return aType.FullName;
}
var xSB = new StringBuilder();
if (aType.IsArray)
{
xSB.Append(GetFullName(aType.GetElementType()));
xSB.Append("[");
int xRank = aType.GetArrayRank();
while (xRank > 1)
{
xSB.Append(",");
xRank--;
}
xSB.Append("]");
return xSB.ToString();
}
if (aType.IsByRef && aType.HasElementType)
{
return "&" + GetFullName(aType.GetElementType());
}
if (aType.IsGenericType && !aType.IsGenericTypeDefinition)
{
xSB.Append(GetFullName(aType.GetGenericTypeDefinition()));
}
else
{
xSB.Append(aType.FullName);
}
if (aType.IsGenericType)
{
xSB.Append("<");
var xArgs = aType.GetGenericArguments();
for (int i = 0; i < xArgs.Length - 1; i++)
{
xSB.Append(GetFullName(xArgs[i]));
xSB.Append(", ");
}
xSB.Append(GetFullName(xArgs.Last()));
xSB.Append(">");
}
//xSB.Append(", ");
//xSB.Append(aType.Assembly.FullName);
return xSB.ToString();
}
}
}

View file

@ -7,7 +7,7 @@
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Cosmos.VS.Package</RootNamespace> <RootNamespace>Cosmos.VS.Package</RootNamespace>
<AssemblyName>SimpleProject</AssemblyName> <AssemblyName>Cosmos.VS.Package</AssemblyName>
<SignAssembly>False</SignAssembly> <SignAssembly>False</SignAssembly>
<AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion> <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>

View file

@ -2,7 +2,7 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<StartAction>Program</StartAction> <StartAction>Program</StartAction>
<StartProgram>$(ProgramFiles)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe</StartProgram> <StartProgram>$(ProgramFiles)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe</StartProgram>
<StartArguments>/ranu /rootsuffix Exp</StartArguments> <StartArguments>/ranu /rootsuffix Exp /log</StartArguments>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<StartAction>Program</StartAction> <StartAction>Program</StartAction>

View file

@ -30,12 +30,9 @@ namespace Cosmos.VS.Package {
// On first call, reset the cache, following calls will use the cached values // On first call, reset the cache, following calls will use the cached values
// Think we will change this to a dummy program when we get our debugger working // Think we will change this to a dummy program when we get our debugger working
// This is the program that gest launched after build // This is the program that gest launched after build
string xProp = GetConfigurationProperty("StartProgram", true);
if (string.IsNullOrEmpty(xProp)) {
xInfo.bstrExe = ProjectMgr.GetOutputAssembly(this.ConfigName); xInfo.bstrExe = ProjectMgr.GetOutputAssembly(this.ConfigName);
} else { xInfo.bstrExe = Path.Combine(Path.GetDirectoryName(xInfo.bstrExe), Path.GetFileNameWithoutExtension(xInfo.bstrExe) + ".iso");
xInfo.bstrExe = xProp;
}
// Select the debugger // Select the debugger
// Managed debugger // Managed debugger