////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public void Start()
{
LoggingUtils.PrintFunction();
//
// Check the target 'gdbserver' binary exits on target device/emulator.
//
string gdbServerPath = string.Empty;
List <string> potentialGdbServerPaths = new List <string> ();
foreach (string libraryPath in m_gdbSetup.Process.NativeLibraryAbiPaths)
{
potentialGdbServerPaths.Add(string.Format("{0}/gdbserver", libraryPath));
}
potentialGdbServerPaths.Add(string.Format("{0}/gdbserver", m_gdbSetup.Process.NativeLibraryPath));
foreach (string path in potentialGdbServerPaths)
{
using (SyncRedirectProcess checkGdbServer = AndroidAdb.AdbCommand(m_gdbSetup.Process.HostDevice, "shell", "ls " + path))
{
int exitCode = checkGdbServer.StartAndWaitForExit(1000);
if ((exitCode == 0) && !checkGdbServer.StandardOutput.ToLower().Contains("no such file"))
{
gdbServerPath = path;
break;
}
}
}
if (string.IsNullOrWhiteSpace(gdbServerPath))
{
// TODO: Push the required gdbserver binary, so we can attach to any app.
throw new InvalidOperationException(string.Format("Failed to locate required 'gdbserver' binary on device ({0}).", m_gdbSetup.Process.HostDevice.ID));
}
KillActiveGdbServerSessions();
//
// Construct a adaptive command line based on GdbSetup requirements.
//
StringBuilder commandLineArgumentsBuilder = new StringBuilder();
commandLineArgumentsBuilder.AppendFormat("run-as {0} {1} ", m_gdbSetup.Process.Name, gdbServerPath);
if (!string.IsNullOrWhiteSpace(m_gdbSetup.Socket))
{
commandLineArgumentsBuilder.AppendFormat("+{0} ", m_gdbSetup.Socket);
}
commandLineArgumentsBuilder.Append("--attach ");
if (string.IsNullOrWhiteSpace(m_gdbSetup.Socket)) // Don't need a host if we have a bound socket?
{
commandLineArgumentsBuilder.AppendFormat("{0}:{1} ", m_gdbSetup.Host, m_gdbSetup.Port);
}
commandLineArgumentsBuilder.Append(m_gdbSetup.Process.Pid);
//
// Launch 'gdbserver' and wait for output to determine success.
//
Stopwatch waitForConnectionTimer = new Stopwatch();
waitForConnectionTimer.Start();
m_gdbServerAttached = new ManualResetEvent(false);
m_gdbServerInstance = AndroidAdb.AdbCommandAsync(m_gdbSetup.Process.HostDevice, "shell", commandLineArgumentsBuilder.ToString());
m_gdbServerInstance.Start(this);
LoggingUtils.Print(string.Format("[GdbServer] Waiting to attach..."));
uint timeout = 5000;
bool responseSignaled = false;
while ((!responseSignaled) && (waitForConnectionTimer.ElapsedMilliseconds < timeout))
{
responseSignaled = m_gdbServerAttached.WaitOne(0);
if (!responseSignaled)
{
Thread.Sleep(100);
}
}
if (!responseSignaled)
{
throw new TimeoutException("Timed out waiting for GdbServer to execute.");
}
}