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.");
}
}