This revision was not accepted when it landed; it landed in state "Needs
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rG83a131b27642: Fix an over-suspend bug with
LaunchInNewTerminalWithAppleScript sessions (authored by jasonmolenda).
Changed prior to commit:
https://reviews.llvm.org/D72963?vs=238909&id=239440#toc
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D72963/new/
https://reviews.llvm.org/D72963
Files:
lldb/source/Host/macosx/objcxx/Host.mm
lldb/tools/darwin-debug/CMakeLists.txt
lldb/tools/debugserver/source/MacOSX/MachProcess.mm
lldb/tools/debugserver/source/MacOSX/MachTask.h
lldb/tools/debugserver/source/MacOSX/MachTask.mm
Index: lldb/tools/debugserver/source/MacOSX/MachTask.mm
===================================================================
--- lldb/tools/debugserver/source/MacOSX/MachTask.mm
+++ lldb/tools/debugserver/source/MacOSX/MachTask.mm
@@ -69,7 +69,8 @@
//----------------------------------------------------------------------
MachTask::MachTask(MachProcess *process)
: m_process(process), m_task(TASK_NULL), m_vm_memory(),
- m_exception_thread(0), m_exception_port(MACH_PORT_NULL) {
+ m_exception_thread(0), m_exception_port(MACH_PORT_NULL),
+ m_exec_will_be_suspended(false), m_do_double_resume(false) {
memset(&m_exc_port_info, 0, sizeof(m_exc_port_info));
}
@@ -103,6 +104,14 @@
err = BasicInfo(task, &task_info);
if (err.Success()) {
+ if (m_do_double_resume && task_info.suspend_count == 2) {
+ err = ::task_resume(task);
+ if (DNBLogCheckLogBit(LOG_TASK) || err.Fail())
+ err.LogThreaded("::task_resume double-resume after exec-start-stopped "
+ "( target_task = 0x%4.4x )", task);
+ }
+ m_do_double_resume = false;
+
// task_resume isn't counted like task_suspend calls are, are, so if the
// task is not suspended, don't try and resume it since it is already
// running
@@ -135,6 +144,8 @@
m_task = TASK_NULL;
m_exception_thread = 0;
m_exception_port = MACH_PORT_NULL;
+ m_exec_will_be_suspended = false;
+ m_do_double_resume = false;
}
//----------------------------------------------------------------------
@@ -651,6 +662,9 @@
err.LogThreaded("::mach_port_deallocate ( task = 0x%4.4x, name = 0x%4.4x )",
task_self, exception_port);
+ m_exec_will_be_suspended = false;
+ m_do_double_resume = false;
+
return err.Status();
}
@@ -960,4 +974,14 @@
void MachTask::TaskPortChanged(task_t task)
{
m_task = task;
+
+ // If we've just exec'd to a new process, and it
+ // is started suspended, we'll need to do two
+ // task_resume's to get the inferior process to
+ // continue.
+ if (m_exec_will_be_suspended)
+ m_do_double_resume = true;
+ else
+ m_do_double_resume = false;
+ m_exec_will_be_suspended = false;
}
Index: lldb/tools/debugserver/source/MacOSX/MachTask.h
===================================================================
--- lldb/tools/debugserver/source/MacOSX/MachTask.h
+++ lldb/tools/debugserver/source/MacOSX/MachTask.h
@@ -85,6 +85,7 @@
const MachProcess *Process() const { return m_process; }
nub_size_t PageSize();
+ void TaskWillExecProcessesSuspended() { m_exec_will_be_suspended = true; }
protected:
MachProcess *m_process; // The mach process that owns this MachTask
@@ -97,6 +98,12 @@
// need it
mach_port_t m_exception_port; // Exception port on which we will receive child
// exceptions
+ bool m_exec_will_be_suspended; // If this task exec's another process, that
+ // process will be launched suspended and we will
+ // need to execute one extra Resume to get it
+ // to progress from dyld_start.
+ bool m_do_double_resume; // next time we task_resume(), do it twice to
+ // fix a too-high suspend count.
typedef std::map<mach_vm_address_t, size_t> allocation_collection;
allocation_collection m_allocations;
Index: lldb/tools/debugserver/source/MacOSX/MachProcess.mm
===================================================================
--- lldb/tools/debugserver/source/MacOSX/MachProcess.mm
+++ lldb/tools/debugserver/source/MacOSX/MachProcess.mm
@@ -734,6 +734,8 @@
this_seg.nsects = seg.nsects;
this_seg.flags = seg.flags;
inf.segments.push_back(this_seg);
+ if (this_seg.name == "ExecExtraSuspend")
+ m_task.TaskWillExecProcessesSuspended();
}
if (lc.cmd == LC_SEGMENT_64) {
struct segment_command_64 seg;
@@ -755,6 +757,8 @@
this_seg.nsects = seg.nsects;
this_seg.flags = seg.flags;
inf.segments.push_back(this_seg);
+ if (this_seg.name == "ExecExtraSuspend")
+ m_task.TaskWillExecProcessesSuspended();
}
if (lc.cmd == LC_UUID) {
struct uuid_command uuidcmd;
Index: lldb/tools/darwin-debug/CMakeLists.txt
===================================================================
--- lldb/tools/darwin-debug/CMakeLists.txt
+++ lldb/tools/darwin-debug/CMakeLists.txt
@@ -1,3 +1,11 @@
+
+# Create an LC_SEGMENT with the special name ExecExtraSuspend which
+# debugserver can detect - it tells debugserver that it will exec a
+# process and that process will start suspended, so debugserver will
+# need to double-resume it to make it run. A random file is copied
+# into the segment.
+set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-sectcreate,ExecExtraSuspend,ExecExtraSuspend,${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt")
+
add_lldb_tool(darwin-debug ADD_TO_FRAMEWORK
darwin-debug.cpp
)
Index: lldb/source/Host/macosx/objcxx/Host.mm
===================================================================
--- lldb/source/Host/macosx/objcxx/Host.mm
+++ lldb/source/Host/macosx/objcxx/Host.mm
@@ -153,33 +153,6 @@
return NULL;
}
-static bool WaitForProcessToSIGSTOP(const lldb::pid_t pid,
- const int timeout_in_seconds) {
- const int time_delta_usecs = 100000;
- const int num_retries = timeout_in_seconds / time_delta_usecs;
- for (int i = 0; i < num_retries; i++) {
- struct proc_bsdinfo bsd_info;
- int error = ::proc_pidinfo(pid, PROC_PIDTBSDINFO, (uint64_t)0, &bsd_info,
- PROC_PIDTBSDINFO_SIZE);
-
- switch (error) {
- case EINVAL:
- case ENOTSUP:
- case ESRCH:
- case EPERM:
- return false;
-
- default:
- break;
-
- case 0:
- if (bsd_info.pbi_status == SSTOP)
- return true;
- }
- ::usleep(time_delta_usecs);
- }
- return false;
-}
#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__)
const char *applscript_in_new_tty = "tell application \"Terminal\"\n"
@@ -325,11 +298,6 @@
lldb_error = accept_thread->Join(&accept_thread_result);
if (lldb_error.Success() && accept_thread_result) {
pid = (intptr_t)accept_thread_result;
-
- // Wait for process to be stopped at the entry point by watching
- // for the process status to be set to SSTOP which indicates it it
- // SIGSTOP'ed at the entry point
- WaitForProcessToSIGSTOP(pid, 5);
}
llvm::sys::fs::remove(unix_socket_name);
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits