//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public JavaLangDebugger (DebugEngine debugEngine, DebuggeeProgram debugProgram) { Engine = debugEngine; m_javaLangCallback = new JavaLangDebuggerCallback (debugEngine); JavaProgram = new JavaLangDebuggeeProgram (this, debugProgram); m_jdbSetup = new JdbSetup (debugProgram.DebugProcess.NativeProcess); Engine.Broadcast (new DebugEngineEvent.DebuggerConnectionEvent (DebugEngineEvent.DebuggerConnectionEvent.EventType.LogStatus, string.Format ("Configuring JDB for {0}:{1}...", m_jdbSetup.Host, m_jdbSetup.Port)), null, null); JdbClient = new JdbClient (m_jdbSetup); JdbClient.OnAsyncStdout = OnClientAsyncOutput; JdbClient.OnAsyncStderr = OnClientAsyncOutput; JdbClient.Start (); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public CLangDebugger (DebugEngine debugEngine, LaunchConfiguration launchConfiguration, DebuggeeProgram debugProgram) { Engine = debugEngine; m_launchConfiguration = launchConfiguration; NativeProgram = new CLangDebuggeeProgram (this, debugProgram); NativeMemoryBytes = new CLangDebuggeeMemoryBytes (this); VariableManager = new CLangDebuggerVariableManager (this); // // Evaluate target device's architecture triple. // string preferedGdbAbiToolPrefix = string.Empty; bool allow64BitAbis = true; switch (debugProgram.DebugProcess.NativeProcess.PrimaryCpuAbi) { case "armeabi": case "armeabi-v7a": { preferedGdbAbiToolPrefix = "arm-linux-androideabi"; break; } case "arm64-v8a": { if (allow64BitAbis) { preferedGdbAbiToolPrefix = "aarch64-linux-android"; } else { preferedGdbAbiToolPrefix = "arm-linux-androideabi"; } break; } case "x86": { preferedGdbAbiToolPrefix = "i686-linux-android"; break; } case "x86_64": { if (allow64BitAbis) { preferedGdbAbiToolPrefix = "x86_64-linux-android"; } else { preferedGdbAbiToolPrefix = "i686-linux-android"; } break; } case "mips": { preferedGdbAbiToolPrefix = "mipsel-linux-android"; break; } case "mips64": { if (allow64BitAbis) { preferedGdbAbiToolPrefix = "mips64el-linux-android"; } else { preferedGdbAbiToolPrefix = "mipsel-linux-android"; } break; } } if (string.IsNullOrEmpty (preferedGdbAbiToolPrefix)) { throw new InvalidOperationException (string.Format ("Unrecognised target primary CPU ABI: {0}", debugProgram.DebugProcess.NativeProcess.PrimaryCpuAbi)); } bool preferedGdbAbiIs64Bit = preferedGdbAbiToolPrefix.Contains ("64"); Engine.Broadcast (new DebugEngineEvent.DebuggerConnectionEvent (DebugEngineEvent.DebuggerConnectionEvent.EventType.LogStatus, string.Format ("Configuring GDB for '{0}' target...", preferedGdbAbiToolPrefix)), null, null); // // Android++ bundles its own copies of GDB to get round various NDK issues. Search for these. // string androidPlusPlusRoot = Environment.GetEnvironmentVariable ("ANDROID_PLUS_PLUS"); // // Build GDB version permutations. // List<string> gdbToolPermutations = new List<string> (); string [] availableHostArchitectures = new string [] { "x86", "x86_64" }; foreach (string arch in availableHostArchitectures) { if (arch.Contains ("64") && !Environment.Is64BitOperatingSystem) { continue; } string gdbToolFilePattern = string.Format ("{0}-gdb.cmd", preferedGdbAbiToolPrefix); string [] availableVersionPaths = Directory.GetDirectories (Path.Combine (androidPlusPlusRoot, "contrib", "gdb", "bin", arch), "*.*.*", SearchOption.TopDirectoryOnly); foreach (string versionPath in availableVersionPaths) { string [] gdbToolMatches = Directory.GetFiles (versionPath, gdbToolFilePattern, SearchOption.TopDirectoryOnly); foreach (string tool in gdbToolMatches) { gdbToolPermutations.Add (tool); } } } if (gdbToolPermutations.Count == 0) { throw new InvalidOperationException ("Could not locate required 32/64-bit GDB deployments."); } else { // // Pick the oldest GDB version available if running 'Jelly Bean' or below. // bool forceNdkR9dClient = (debugProgram.DebugProcess.NativeProcess.HostDevice.SdkVersion <= AndroidSettings.VersionCode.JELLY_BEAN); if (forceNdkR9dClient) { m_gdbSetup = new GdbSetup (debugProgram.DebugProcess.NativeProcess, gdbToolPermutations [0]); } else { m_gdbSetup = new GdbSetup (debugProgram.DebugProcess.NativeProcess, gdbToolPermutations [gdbToolPermutations.Count - 1]); } // // A symbolic link to 'share' is placed in the architecture directory, provide GDB with that location. // string architecturePath = Path.GetDirectoryName (Path.GetDirectoryName (m_gdbSetup.GdbToolPath)); string pythonGdbScriptsPath = Path.Combine (architecturePath, "share", "gdb"); m_gdbSetup.GdbToolArguments += " --data-directory " + PathUtils.SantiseWindowsPath (pythonGdbScriptsPath); } if (m_gdbSetup == null) { throw new InvalidOperationException ("Could not evaluate a suitable GDB instance. Ensure you have the correct NDK deployment for your system's architecture."); } if (m_launchConfiguration != null) { string launchDirectory; if (m_launchConfiguration.TryGetValue ("LaunchSuspendedDir", out launchDirectory)) { m_gdbSetup.SymbolDirectories.Add (launchDirectory); } } GdbServer = new GdbServer (m_gdbSetup); GdbClient = new GdbClient (m_gdbSetup); GdbClient.OnResultRecord = OnClientResultRecord; GdbClient.OnAsyncRecord = OnClientAsyncRecord; GdbClient.OnStreamRecord = OnClientStreamRecord; GdbClient.Start (); }