Skip to content

Commit 11c1d1c

Browse files
authored
Merge pull request #616 from jasonmolenda/r29760580-launch-in-term-fix-bbranch
Fix an over-suspend bug with LaunchInNewTerminalWithAppleScript sessions
2 parents 03f5015 + fee6a7a commit 11c1d1c

File tree

5 files changed

+44
-33
lines changed

5 files changed

+44
-33
lines changed

lldb/source/Host/macosx/objcxx/Host.mm

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -153,33 +153,6 @@
153153
return NULL;
154154
}
155155

156-
static bool WaitForProcessToSIGSTOP(const lldb::pid_t pid,
157-
const int timeout_in_seconds) {
158-
const int time_delta_usecs = 100000;
159-
const int num_retries = timeout_in_seconds / time_delta_usecs;
160-
for (int i = 0; i < num_retries; i++) {
161-
struct proc_bsdinfo bsd_info;
162-
int error = ::proc_pidinfo(pid, PROC_PIDTBSDINFO, (uint64_t)0, &bsd_info,
163-
PROC_PIDTBSDINFO_SIZE);
164-
165-
switch (error) {
166-
case EINVAL:
167-
case ENOTSUP:
168-
case ESRCH:
169-
case EPERM:
170-
return false;
171-
172-
default:
173-
break;
174-
175-
case 0:
176-
if (bsd_info.pbi_status == SSTOP)
177-
return true;
178-
}
179-
::usleep(time_delta_usecs);
180-
}
181-
return false;
182-
}
183156
#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__)
184157

185158
const char *applscript_in_new_tty = "tell application \"Terminal\"\n"
@@ -325,11 +298,6 @@ repeat with the_window in (get windows)\n\
325298
lldb_error = accept_thread->Join(&accept_thread_result);
326299
if (lldb_error.Success() && accept_thread_result) {
327300
pid = (intptr_t)accept_thread_result;
328-
329-
// Wait for process to be stopped at the entry point by watching
330-
// for the process status to be set to SSTOP which indicates it it
331-
// SIGSTOP'ed at the entry point
332-
WaitForProcessToSIGSTOP(pid, 5);
333301
}
334302

335303
llvm::sys::fs::remove(unix_socket_name);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
2+
# Create an LC_SEGMENT with the special name ExecExtraSuspend which
3+
# debugserver can detect - it tells debugserver that it will exec a
4+
# process and that process will start suspended, so debugserver will
5+
# need to double-resume it to make it run. A random file is copied
6+
# into the segment.
7+
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-sectcreate,ExecExtraSuspend,ExecExtraSuspend,${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt")
8+
19
add_lldb_tool(darwin-debug ADD_TO_FRAMEWORK
210
darwin-debug.cpp
311
)

lldb/tools/debugserver/source/MacOSX/MachProcess.mm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,8 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
734734
this_seg.nsects = seg.nsects;
735735
this_seg.flags = seg.flags;
736736
inf.segments.push_back(this_seg);
737+
if (this_seg.name == "ExecExtraSuspend")
738+
m_task.TaskWillExecProcessesSuspended();
737739
}
738740
if (lc.cmd == LC_SEGMENT_64) {
739741
struct segment_command_64 seg;
@@ -755,6 +757,8 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
755757
this_seg.nsects = seg.nsects;
756758
this_seg.flags = seg.flags;
757759
inf.segments.push_back(this_seg);
760+
if (this_seg.name == "ExecExtraSuspend")
761+
m_task.TaskWillExecProcessesSuspended();
758762
}
759763
if (lc.cmd == LC_UUID) {
760764
struct uuid_command uuidcmd;

lldb/tools/debugserver/source/MacOSX/MachTask.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class MachTask {
8585
const MachProcess *Process() const { return m_process; }
8686

8787
nub_size_t PageSize();
88+
void TaskWillExecProcessesSuspended() { m_exec_will_be_suspended = true; }
8889

8990
protected:
9091
MachProcess *m_process; // The mach process that owns this MachTask
@@ -97,6 +98,12 @@ class MachTask {
9798
// need it
9899
mach_port_t m_exception_port; // Exception port on which we will receive child
99100
// exceptions
101+
bool m_exec_will_be_suspended; // If this task exec's another process, that
102+
// process will be launched suspended and we will
103+
// need to execute one extra Resume to get it
104+
// to progress from dyld_start.
105+
bool m_do_double_resume; // next time we task_resume(), do it twice to
106+
// fix a too-high suspend count.
100107

101108
typedef std::map<mach_vm_address_t, size_t> allocation_collection;
102109
allocation_collection m_allocations;

lldb/tools/debugserver/source/MacOSX/MachTask.mm

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@
6969
//----------------------------------------------------------------------
7070
MachTask::MachTask(MachProcess *process)
7171
: m_process(process), m_task(TASK_NULL), m_vm_memory(),
72-
m_exception_thread(0), m_exception_port(MACH_PORT_NULL) {
72+
m_exception_thread(0), m_exception_port(MACH_PORT_NULL),
73+
m_exec_will_be_suspended(false), m_do_double_resume(false) {
7374
memset(&m_exc_port_info, 0, sizeof(m_exc_port_info));
7475
}
7576

@@ -103,6 +104,14 @@
103104
err = BasicInfo(task, &task_info);
104105

105106
if (err.Success()) {
107+
if (m_do_double_resume && task_info.suspend_count == 2) {
108+
err = ::task_resume(task);
109+
if (DNBLogCheckLogBit(LOG_TASK) || err.Fail())
110+
err.LogThreaded("::task_resume double-resume after exec-start-stopped "
111+
"( target_task = 0x%4.4x )", task);
112+
}
113+
m_do_double_resume = false;
114+
106115
// task_resume isn't counted like task_suspend calls are, are, so if the
107116
// task is not suspended, don't try and resume it since it is already
108117
// running
@@ -135,6 +144,8 @@
135144
m_task = TASK_NULL;
136145
m_exception_thread = 0;
137146
m_exception_port = MACH_PORT_NULL;
147+
m_exec_will_be_suspended = false;
148+
m_do_double_resume = false;
138149
}
139150

140151
//----------------------------------------------------------------------
@@ -651,6 +662,9 @@ static void get_threads_profile_data(DNBProfileDataScanType scanType,
651662
err.LogThreaded("::mach_port_deallocate ( task = 0x%4.4x, name = 0x%4.4x )",
652663
task_self, exception_port);
653664

665+
m_exec_will_be_suspended = false;
666+
m_do_double_resume = false;
667+
654668
return err.Status();
655669
}
656670

@@ -960,4 +974,14 @@ static void get_threads_profile_data(DNBProfileDataScanType scanType,
960974
void MachTask::TaskPortChanged(task_t task)
961975
{
962976
m_task = task;
977+
978+
// If we've just exec'd to a new process, and it
979+
// is started suspended, we'll need to do two
980+
// task_resume's to get the inferior process to
981+
// continue.
982+
if (m_exec_will_be_suspended)
983+
m_do_double_resume = true;
984+
else
985+
m_do_double_resume = false;
986+
m_exec_will_be_suspended = false;
963987
}

0 commit comments

Comments
 (0)