public virtual async Task<bool> StartAsync(IToolChain toolchain, IConsole console, IProject project)
{
this.console = console;
var startInfo = new ProcessStartInfo();
console.WriteLine("[GDB] - Starting...");
// This information should be part of this extension... or configurable internally?
// This maybe indicates that debuggers are part of toolchain?
if (toolchain is GCCToolchain)
{
startInfo.FileName = (toolchain as GCCToolchain).GDBExecutable;
}
else
{
console.WriteLine("[GDB] - Error GDB is not able to debug projects compiled on this kind of toolchain (" +
toolchain.GetType() + ")");
return false;
}
startInfo.Arguments = string.Format("--interpreter=mi \"{0}\"",
Path.Combine(project.CurrentDirectory, project.Executable).ToPlatformPath());
if (Path.IsPathRooted(startInfo.FileName) && !System.IO.File.Exists(startInfo.FileName))
{
console.WriteLine("[GDB] - Error unable to find executable.");
return false;
}
// Hide console window
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardInput = true;
startInfo.CreateNoWindow = true;
process = Process.Start(startInfo);
input = process.StandardInput;
var attempts = 0;
while (!Platform.FreeConsole() && attempts < 10)
{
Console.WriteLine(Marshal.GetLastWin32Error());
Thread.Sleep(10);
attempts++;
}
attempts = 0;
while (!Platform.AttachConsole(process.Id) && attempts < 10)
{
Thread.Sleep(10);
attempts++;
}
while (!Platform.SetConsoleCtrlHandler(null, true))
{
Console.WriteLine(Marshal.GetLastWin32Error());
Thread.Sleep(10);
}
TaskCompletionSource<JobRunner> transmitRunnerSet = new TaskCompletionSource<JobRunner>();
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Task.Factory.StartNew(() =>
{
transmitRunner = new JobRunner();
transmitRunnerSet.SetResult(transmitRunner);
closeTokenSource = new CancellationTokenSource();
transmitRunner.RunLoop(closeTokenSource.Token);
transmitRunner = null;
});
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
await transmitRunnerSet.Task;
Task.Factory.StartNew(() =>
{
console.WriteLine("[GDB] - Started");
process.OutputDataReceived += (sender, e) =>
{
if (e.Data != null)
{
ProcessOutput(e.Data);
}
};
process.ErrorDataReceived += (sender, e) =>
{
if (e.Data != null)
{
console.WriteLine("[GDB] - " + e.Data);
}
};
process.BeginOutputReadLine();
process.BeginErrorReadLine();
try
{
process.WaitForExit();
Platform.FreeConsole();
Platform.SetConsoleCtrlHandler(null, false);
}
catch (Exception e)
{
Console.WriteLine(e);
}
console.WriteLine("[GDB] - Closed");
closeTokenSource?.Cancel();
});
await SafelyExecuteCommand(async () => await new EnablePrettyPrintingCommand().Execute(this));
return true;
}