Author: Jim Ingham Date: 2021-11-16T16:46:21-08:00 New Revision: dd5505a8f2c75a903ec944b6e46aed2042610673
URL: https://github.com/llvm/llvm-project/commit/dd5505a8f2c75a903ec944b6e46aed2042610673 DIFF: https://github.com/llvm/llvm-project/commit/dd5505a8f2c75a903ec944b6e46aed2042610673.diff LOG: Revert "Make it possible for lldb to launch a remote binary with no local file." The reworking of the gdb client tests into the PlatformClientTestBase broke the test for this. I did the mutatis mutandis for the move, but the test still fails. Reverting till I have time to figure out why. This reverts commit b715b79d54d5ca2d4e8c91089b8f6a9389d9dc48. Added: Modified: lldb/source/Commands/CommandObjectProcess.cpp lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp lldb/source/Target/Process.cpp Removed: lldb/test/API/functionalities/gdb_remote_client/TestNoLocalFile.py ################################################################################ diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index 5fd1718e84840..8ce14f2a96d5e 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -159,12 +159,7 @@ class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach { // If our listener is nullptr, users aren't allows to launch ModuleSP exe_module_sp = target->GetExecutableModule(); - // If the target already has an executable module, then use that. If it - // doesn't then someone must be trying to launch using a path that will - // make sense to the remote stub, but doesn't exist on the local host. - // In that case use the ExecutableFile that was set in the target's - // ProcessLaunchInfo. - if (exe_module_sp == nullptr && !target->GetProcessLaunchInfo().GetExecutableFile()) { + if (exe_module_sp == nullptr) { result.AppendError("no file in target, create a debug target using the " "'target create' command"); return false; @@ -224,17 +219,11 @@ class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach { if (!target_settings_argv0.empty()) { m_options.launch_info.GetArguments().AppendArgument( target_settings_argv0); - if (exe_module_sp) - m_options.launch_info.SetExecutableFile( - exe_module_sp->GetPlatformFileSpec(), false); - else - m_options.launch_info.SetExecutableFile(target->GetProcessLaunchInfo().GetExecutableFile(), false); + m_options.launch_info.SetExecutableFile( + exe_module_sp->GetPlatformFileSpec(), false); } else { - if (exe_module_sp) - m_options.launch_info.SetExecutableFile( - exe_module_sp->GetPlatformFileSpec(), true); - else - m_options.launch_info.SetExecutableFile(target->GetProcessLaunchInfo().GetExecutableFile(), true); + m_options.launch_info.SetExecutableFile( + exe_module_sp->GetPlatformFileSpec(), true); } if (launch_args.GetArgumentCount() == 0) { @@ -261,20 +250,11 @@ class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach { llvm::StringRef data = stream.GetString(); if (!data.empty()) result.AppendMessage(data); - // If we didn't have a local executable, then we wouldn't have had an - // executable module before launch. - if (!exe_module_sp) - exe_module_sp = target->GetExecutableModule(); - if (!exe_module_sp) { - result.AppendWarning("Could not get executable module after launch."); - } else { - - const char *archname = - exe_module_sp->GetArchitecture().GetArchitectureName(); - result.AppendMessageWithFormat( - "Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), - exe_module_sp->GetFileSpec().GetPath().c_str(), archname); - } + const char *archname = + exe_module_sp->GetArchitecture().GetArchitectureName(); + result.AppendMessageWithFormat( + "Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), + exe_module_sp->GetFileSpec().GetPath().c_str(), archname); result.SetStatus(eReturnStatusSuccessFinishResult); result.SetDidChangeProcessState(true); } else { diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 2233bf6758190..a666aeb8bb3f6 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -677,133 +677,143 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module, // LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD); // ::LogSetLogFile ("/dev/stdout"); - error = EstablishConnectionIfNeeded(launch_info); - if (error.Success()) { - PseudoTerminal pty; - const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0; - - PlatformSP platform_sp(GetTarget().GetPlatform()); - if (disable_stdio) { - // set to /dev/null unless redirected to a file above - if (!stdin_file_spec) - stdin_file_spec.SetFile(FileSystem::DEV_NULL, - FileSpec::Style::native); - if (!stdout_file_spec) - stdout_file_spec.SetFile(FileSystem::DEV_NULL, - FileSpec::Style::native); - if (!stderr_file_spec) - stderr_file_spec.SetFile(FileSystem::DEV_NULL, - FileSpec::Style::native); - } else if (platform_sp && platform_sp->IsHost()) { - // If the debugserver is local and we aren't disabling STDIO, lets use - // a pseudo terminal to instead of relying on the 'O' packets for stdio - // since 'O' packets can really slow down debugging if the inferior - // does a lot of output. - if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) && - !errorToBool(pty.OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY))) { - FileSpec secondary_name(pty.GetSecondaryName()); + ObjectFile *object_file = exe_module->GetObjectFile(); + if (object_file) { + error = EstablishConnectionIfNeeded(launch_info); + if (error.Success()) { + PseudoTerminal pty; + const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0; + PlatformSP platform_sp(GetTarget().GetPlatform()); + if (disable_stdio) { + // set to /dev/null unless redirected to a file above if (!stdin_file_spec) - stdin_file_spec = secondary_name; - + stdin_file_spec.SetFile(FileSystem::DEV_NULL, + FileSpec::Style::native); if (!stdout_file_spec) - stdout_file_spec = secondary_name; - + stdout_file_spec.SetFile(FileSystem::DEV_NULL, + FileSpec::Style::native); if (!stderr_file_spec) - stderr_file_spec = secondary_name; + stderr_file_spec.SetFile(FileSystem::DEV_NULL, + FileSpec::Style::native); + } else if (platform_sp && platform_sp->IsHost()) { + // If the debugserver is local and we aren't disabling STDIO, lets use + // a pseudo terminal to instead of relying on the 'O' packets for stdio + // since 'O' packets can really slow down debugging if the inferior + // does a lot of output. + if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) && + !errorToBool(pty.OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY))) { + FileSpec secondary_name(pty.GetSecondaryName()); + + if (!stdin_file_spec) + stdin_file_spec = secondary_name; + + if (!stdout_file_spec) + stdout_file_spec = secondary_name; + + if (!stderr_file_spec) + stderr_file_spec = secondary_name; + } + LLDB_LOGF( + log, + "ProcessGDBRemote::%s adjusted STDIO paths for local platform " + "(IsHost() is true) using secondary: stdin=%s, stdout=%s, " + "stderr=%s", + __FUNCTION__, + stdin_file_spec ? stdin_file_spec.GetCString() : "<null>", + stdout_file_spec ? stdout_file_spec.GetCString() : "<null>", + stderr_file_spec ? stderr_file_spec.GetCString() : "<null>"); } - LLDB_LOGF( - log, - "ProcessGDBRemote::%s adjusted STDIO paths for local platform " - "(IsHost() is true) using secondary: stdin=%s, stdout=%s, " - "stderr=%s", - __FUNCTION__, - stdin_file_spec ? stdin_file_spec.GetCString() : "<null>", - stdout_file_spec ? stdout_file_spec.GetCString() : "<null>", - stderr_file_spec ? stderr_file_spec.GetCString() : "<null>"); - } - LLDB_LOGF(log, - "ProcessGDBRemote::%s final STDIO paths after all " - "adjustments: stdin=%s, stdout=%s, stderr=%s", - __FUNCTION__, - stdin_file_spec ? stdin_file_spec.GetCString() : "<null>", - stdout_file_spec ? stdout_file_spec.GetCString() : "<null>", - stderr_file_spec ? stderr_file_spec.GetCString() : "<null>"); - - if (stdin_file_spec) - m_gdb_comm.SetSTDIN(stdin_file_spec); - if (stdout_file_spec) - m_gdb_comm.SetSTDOUT(stdout_file_spec); - if (stderr_file_spec) - m_gdb_comm.SetSTDERR(stderr_file_spec); - - m_gdb_comm.SetDisableASLR(launch_flags & eLaunchFlagDisableASLR); - m_gdb_comm.SetDetachOnError(launch_flags & eLaunchFlagDetachOnError); - - m_gdb_comm.SendLaunchArchPacket( - GetTarget().GetArchitecture().GetArchitectureName()); - - const char *launch_event_data = launch_info.GetLaunchEventData(); - if (launch_event_data != nullptr && *launch_event_data != '\0') - m_gdb_comm.SendLaunchEventDataPacket(launch_event_data); - - if (working_dir) { - m_gdb_comm.SetWorkingDir(working_dir); - } + LLDB_LOGF(log, + "ProcessGDBRemote::%s final STDIO paths after all " + "adjustments: stdin=%s, stdout=%s, stderr=%s", + __FUNCTION__, + stdin_file_spec ? stdin_file_spec.GetCString() : "<null>", + stdout_file_spec ? stdout_file_spec.GetCString() : "<null>", + stderr_file_spec ? stderr_file_spec.GetCString() : "<null>"); - // Send the environment and the program + arguments after we connect - m_gdb_comm.SendEnvironment(launch_info.GetEnvironment()); + if (stdin_file_spec) + m_gdb_comm.SetSTDIN(stdin_file_spec); + if (stdout_file_spec) + m_gdb_comm.SetSTDOUT(stdout_file_spec); + if (stderr_file_spec) + m_gdb_comm.SetSTDERR(stderr_file_spec); - { - // Scope for the scoped timeout object - GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_comm, - std::chrono::seconds(10)); - - int arg_packet_err = m_gdb_comm.SendArgumentsPacket(launch_info); - if (arg_packet_err == 0) { - std::string error_str; - if (m_gdb_comm.GetLaunchSuccess(error_str)) { - SetID(m_gdb_comm.GetCurrentProcessID()); + m_gdb_comm.SetDisableASLR(launch_flags & eLaunchFlagDisableASLR); + m_gdb_comm.SetDetachOnError(launch_flags & eLaunchFlagDetachOnError); + + m_gdb_comm.SendLaunchArchPacket( + GetTarget().GetArchitecture().GetArchitectureName()); + + const char *launch_event_data = launch_info.GetLaunchEventData(); + if (launch_event_data != nullptr && *launch_event_data != '\0') + m_gdb_comm.SendLaunchEventDataPacket(launch_event_data); + + if (working_dir) { + m_gdb_comm.SetWorkingDir(working_dir); + } + + // Send the environment and the program + arguments after we connect + m_gdb_comm.SendEnvironment(launch_info.GetEnvironment()); + + { + // Scope for the scoped timeout object + GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_comm, + std::chrono::seconds(10)); + + int arg_packet_err = m_gdb_comm.SendArgumentsPacket(launch_info); + if (arg_packet_err == 0) { + std::string error_str; + if (m_gdb_comm.GetLaunchSuccess(error_str)) { + SetID(m_gdb_comm.GetCurrentProcessID()); + } else { + error.SetErrorString(error_str.c_str()); + } } else { - error.SetErrorString(error_str.c_str()); + error.SetErrorStringWithFormat("'A' packet returned an error: %i", + arg_packet_err); } - } else { - error.SetErrorStringWithFormat("'A' packet returned an error: %i", - arg_packet_err); } - } - if (GetID() == LLDB_INVALID_PROCESS_ID) { - LLDB_LOGF(log, "failed to connect to debugserver: %s", - error.AsCString()); - KillDebugserverProcess(); - return error; - } + if (GetID() == LLDB_INVALID_PROCESS_ID) { + LLDB_LOGF(log, "failed to connect to debugserver: %s", + error.AsCString()); + KillDebugserverProcess(); + return error; + } - StringExtractorGDBRemote response; - if (m_gdb_comm.GetStopReply(response)) { - SetLastStopPacket(response); + StringExtractorGDBRemote response; + if (m_gdb_comm.GetStopReply(response)) { + SetLastStopPacket(response); - const ArchSpec &process_arch = m_gdb_comm.GetProcessArchitecture(); + const ArchSpec &process_arch = m_gdb_comm.GetProcessArchitecture(); - if (process_arch.IsValid()) { - GetTarget().MergeArchitecture(process_arch); - } else { - const ArchSpec &host_arch = m_gdb_comm.GetHostArchitecture(); - if (host_arch.IsValid()) - GetTarget().MergeArchitecture(host_arch); - } + if (process_arch.IsValid()) { + GetTarget().MergeArchitecture(process_arch); + } else { + const ArchSpec &host_arch = m_gdb_comm.GetHostArchitecture(); + if (host_arch.IsValid()) + GetTarget().MergeArchitecture(host_arch); + } - SetPrivateState(SetThreadStopInfo(response)); + SetPrivateState(SetThreadStopInfo(response)); - if (!disable_stdio) { - if (pty.GetPrimaryFileDescriptor() != PseudoTerminal::invalid_fd) - SetSTDIOFileDescriptor(pty.ReleasePrimaryFileDescriptor()); + if (!disable_stdio) { + if (pty.GetPrimaryFileDescriptor() != PseudoTerminal::invalid_fd) + SetSTDIOFileDescriptor(pty.ReleasePrimaryFileDescriptor()); + } } + } else { + LLDB_LOGF(log, "failed to connect to debugserver: %s", error.AsCString()); } } else { - LLDB_LOGF(log, "failed to connect to debugserver: %s", error.AsCString()); + // Set our user ID to an invalid process ID. + SetID(LLDB_INVALID_PROCESS_ID); + error.SetErrorStringWithFormat( + "failed to get object file from '%s' for arch %s", + exe_module->GetFileSpec().GetFilename().AsCString(), + exe_module->GetArchitecture().GetArchitectureName()); } return error; } diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 3fbd6434e8683..519db0482e4ba 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -2493,125 +2493,118 @@ Status Process::Launch(ProcessLaunchInfo &launch_info) { m_process_input_reader.reset(); Module *exe_module = GetTarget().GetExecutableModulePointer(); - - // The "remote executable path" is hooked up to the local Executable - // module. But we should be able to debug a remote process even if the - // executable module only exists on the remote. However, there needs to - // be a way to express this path, without actually having a module. - // The way to do that is to set the ExecutableFile in the LaunchInfo. - // Figure that out here: - - FileSpec exe_spec_to_use; if (!exe_module) { - if (!launch_info.GetExecutableFile()) { - error.SetErrorString("executable module does not exist"); - return error; - } - exe_spec_to_use = launch_info.GetExecutableFile(); - } else - exe_spec_to_use = exe_module->GetFileSpec(); - - if (exe_module && FileSystem::Instance().Exists(exe_module->GetFileSpec())) { + error.SetErrorString("executable module does not exist"); + return error; + } + + char local_exec_file_path[PATH_MAX]; + char platform_exec_file_path[PATH_MAX]; + exe_module->GetFileSpec().GetPath(local_exec_file_path, + sizeof(local_exec_file_path)); + exe_module->GetPlatformFileSpec().GetPath(platform_exec_file_path, + sizeof(platform_exec_file_path)); + if (FileSystem::Instance().Exists(exe_module->GetFileSpec())) { // Install anything that might need to be installed prior to launching. // For host systems, this will do nothing, but if we are connected to a // remote platform it will install any needed binaries error = GetTarget().Install(&launch_info); if (error.Fail()) return error; - } - // Listen and queue events that are broadcasted during the process launch. - ListenerSP listener_sp(Listener::MakeListener("LaunchEventHijack")); - HijackProcessEvents(listener_sp); - auto on_exit = llvm::make_scope_exit([this]() { RestoreProcessEvents(); }); - if (PrivateStateThreadIsValid()) - PausePrivateStateThread(); + // Listen and queue events that are broadcasted during the process launch. + ListenerSP listener_sp(Listener::MakeListener("LaunchEventHijack")); + HijackProcessEvents(listener_sp); + auto on_exit = llvm::make_scope_exit([this]() { RestoreProcessEvents(); }); - error = WillLaunch(exe_module); - if (error.Success()) { - const bool restarted = false; - SetPublicState(eStateLaunching, restarted); - m_should_detach = false; + if (PrivateStateThreadIsValid()) + PausePrivateStateThread(); - if (m_public_run_lock.TrySetRunning()) { - // Now launch using these arguments. - error = DoLaunch(exe_module, launch_info); - } else { - // This shouldn't happen - error.SetErrorString("failed to acquire process run lock"); - } + error = WillLaunch(exe_module); + if (error.Success()) { + const bool restarted = false; + SetPublicState(eStateLaunching, restarted); + m_should_detach = false; - if (error.Fail()) { - if (GetID() != LLDB_INVALID_PROCESS_ID) { - SetID(LLDB_INVALID_PROCESS_ID); - const char *error_string = error.AsCString(); - if (error_string == nullptr) - error_string = "launch failed"; - SetExitStatus(-1, error_string); + if (m_public_run_lock.TrySetRunning()) { + // Now launch using these arguments. + error = DoLaunch(exe_module, launch_info); + } else { + // This shouldn't happen + error.SetErrorString("failed to acquire process run lock"); } - } else { - EventSP event_sp; - // Now wait for the process to launch and return control to us, and then - // call DidLaunch: - StateType state = WaitForProcessStopPrivate(event_sp, seconds(10)); - - if (state == eStateInvalid || !event_sp) { - // We were able to launch the process, but we failed to catch the - // initial stop. - error.SetErrorString("failed to catch stop after launch"); - SetExitStatus(0, "failed to catch stop after launch"); - Destroy(false); - } else if (state == eStateStopped || state == eStateCrashed) { - DidLaunch(); - - DynamicLoader *dyld = GetDynamicLoader(); - if (dyld) - dyld->DidLaunch(); - - GetJITLoaders().DidLaunch(); - - SystemRuntime *system_runtime = GetSystemRuntime(); - if (system_runtime) - system_runtime->DidLaunch(); - - if (!m_os_up) - LoadOperatingSystemPlugin(false); - - // We successfully launched the process and stopped, now it the - // right time to set up signal filters before resuming. - UpdateAutomaticSignalFiltering(); - - // Note, the stop event was consumed above, but not handled. This - // was done to give DidLaunch a chance to run. The target is either - // stopped or crashed. Directly set the state. This is done to - // prevent a stop message with a bunch of spurious output on thread - // status, as well as not pop a ProcessIOHandler. - // We are done with the launch hijack listener, and this stop should - // go to the public state listener: - RestoreProcessEvents(); - SetPublicState(state, false); - - if (PrivateStateThreadIsValid()) - ResumePrivateStateThread(); - else - StartPrivateStateThread(); + if (error.Fail()) { + if (GetID() != LLDB_INVALID_PROCESS_ID) { + SetID(LLDB_INVALID_PROCESS_ID); + const char *error_string = error.AsCString(); + if (error_string == nullptr) + error_string = "launch failed"; + SetExitStatus(-1, error_string); + } + } else { + EventSP event_sp; + + // Now wait for the process to launch and return control to us, and then + // call DidLaunch: + StateType state = WaitForProcessStopPrivate(event_sp, seconds(10)); + + if (state == eStateInvalid || !event_sp) { + // We were able to launch the process, but we failed to catch the + // initial stop. + error.SetErrorString("failed to catch stop after launch"); + SetExitStatus(0, "failed to catch stop after launch"); + Destroy(false); + } else if (state == eStateStopped || state == eStateCrashed) { + DidLaunch(); + + DynamicLoader *dyld = GetDynamicLoader(); + if (dyld) + dyld->DidLaunch(); + + GetJITLoaders().DidLaunch(); + + SystemRuntime *system_runtime = GetSystemRuntime(); + if (system_runtime) + system_runtime->DidLaunch(); + + if (!m_os_up) + LoadOperatingSystemPlugin(false); + + // We successfully launched the process and stopped, now it the + // right time to set up signal filters before resuming. + UpdateAutomaticSignalFiltering(); + + // Note, the stop event was consumed above, but not handled. This + // was done to give DidLaunch a chance to run. The target is either + // stopped or crashed. Directly set the state. This is done to + // prevent a stop message with a bunch of spurious output on thread + // status, as well as not pop a ProcessIOHandler. + // We are done with the launch hijack listener, and this stop should + // go to the public state listener: + RestoreProcessEvents(); + SetPublicState(state, false); + + if (PrivateStateThreadIsValid()) + ResumePrivateStateThread(); + else + StartPrivateStateThread(); - // Target was stopped at entry as was intended. Need to notify the - // listeners about it. - if (state == eStateStopped && - launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) + // Target was stopped at entry as was intended. Need to notify the + // listeners about it. + if (state == eStateStopped && + launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) + HandlePrivateEvent(event_sp); + } else if (state == eStateExited) { + // We exited while trying to launch somehow. Don't call DidLaunch + // as that's not likely to work, and return an invalid pid. HandlePrivateEvent(event_sp); - } else if (state == eStateExited) { - // We exited while trying to launch somehow. Don't call DidLaunch - // as that's not likely to work, and return an invalid pid. - HandlePrivateEvent(event_sp); + } } } } else { - std::string local_exec_file_path = exe_spec_to_use.GetPath(); error.SetErrorStringWithFormat("file doesn't exist: '%s'", - local_exec_file_path.c_str()); + local_exec_file_path); } return error; diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestNoLocalFile.py b/lldb/test/API/functionalities/gdb_remote_client/TestNoLocalFile.py deleted file mode 100644 index fd9dc3ef592b1..0000000000000 --- a/lldb/test/API/functionalities/gdb_remote_client/TestNoLocalFile.py +++ /dev/null @@ -1,88 +0,0 @@ -import lldb -from lldbsuite.test.lldbtest import * -from lldbsuite.test.decorators import * -from gdbclientutils import * - - -class TestNoLocalFile(GDBRemoteTestBase): - """ Test the case where there is NO local copy of the file - being debugged. We shouldn't immediately error out, but - rather lldb should ask debugserver if it knows about the file. """ - - - @skipIfXmlSupportMissing - def test(self): - self.absent_file = '/nosuch_dir/nosuch_subdir/nosuch_executable' - self.a_packet_file = None - class MyResponder(MockGDBServerResponder): - def __init__(self, testcase): - MockGDBServerResponder.__init__(self) - self.after_launch = False - self.testcase = testcase - self.current_thread = 0 - - def A(self, packet): - # This is the main test, we want to see that lldb DID send the - # A packet to get debugserver to load the file. - # Skip the length and second length: - a_arr = packet.split(",") - self.testcase.a_packet_file = bytearray.fromhex(a_arr[2]).decode() - return "OK" - - def qXferRead(self, obj, annex, offset, length): - if annex == "target.xml": - return """<?xml version="1.0"?> - <target version="1.0"> - <architecture>i386:x86-64</architecture> - <feature name="org.gnu.gdb.i386.core"> - <reg name="rip" bitsize="64" regnum="0" type="code_ptr" group="general"/> - </feature> - </target>""", False - else: - return None, False - - def qC(self): - if not self.after_launch: - return "QC0" - return "0" - - def qfThreadInfo(self): - if not self.after_launch: - return "OK" - return "m0" - - def qsThreadInfo(self): - if not self.after_launch: - return "OK" - return "l" - - def qLaunchSuccess(self): - return "OK" - - def qProcessInfo(self): - return "$pid:10b70;parent-pid:10b20;real-uid:1f6;real-gid:14;effective-uid:1f6;effective-gid:14;cputype:1000007;cpusubtype:8;ptrsize:8;ostype:macosx;vendor:apple;endian:little;" - - - error = lldb.SBError() - self.server.responder = MyResponder(self) - target = self.dbg.CreateTarget(None, "x86_64-apple-macosx", "remote-macosx", False, error) - self.assertSuccess(error, "Made a valid target") - launch_info = target.GetLaunchInfo() - launch_info.SetExecutableFile(lldb.SBFileSpec(self.absent_file), True) - flags = launch_info.GetLaunchFlags() - flags |= lldb.eLaunchFlagStopAtEntry - launch_info.SetLaunchFlags(flags) - - process = self.connect(target) - self.assertTrue(process.IsValid(), "Process is valid") - - # We need to fetch the connected event: - lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, [lldb.eStateConnected]) - - self.server.responder.after_launch = True - - process = target.Launch(launch_info, error) - self.assertSuccess(error, "Successfully launched.") - self.assertEqual(process.GetState(), lldb.eStateStopped, "Should be stopped at entry") - self.assertIsNotNone(self.a_packet_file, "A packet was sent") - self.assertEqual(self.absent_file, self.a_packet_file, "The A packet file was correct") _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits