aboutsummaryrefslogtreecommitdiff
path: root/lldb/tools/debugserver
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/tools/debugserver')
-rw-r--r--lldb/tools/debugserver/source/DNB.cpp2
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachProcess.h14
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachProcess.mm133
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachTask.h2
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachTask.mm13
5 files changed, 145 insertions, 19 deletions
diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp
index 0cd48d9..4d5afcf 100644
--- a/lldb/tools/debugserver/source/DNB.cpp
+++ b/lldb/tools/debugserver/source/DNB.cpp
@@ -1101,7 +1101,7 @@ DNBGetLibrariesInfoForAddresses(nub_process_t pid,
JSONGenerator::ObjectSP DNBGetSharedCacheInfo(nub_process_t pid) {
MachProcessSP procSP;
if (GetProcessSP(pid, procSP)) {
- return procSP->GetSharedCacheInfo(pid);
+ return procSP->GetInferiorSharedCacheInfo(pid);
}
return JSONGenerator::ObjectSP();
}
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
index 56bc9d6..67b27b9 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
@@ -283,7 +283,10 @@ public:
JSONGenerator::ObjectSP
GetAllLoadedLibrariesInfos(nub_process_t pid,
bool fetch_report_load_commands);
- JSONGenerator::ObjectSP GetSharedCacheInfo(nub_process_t pid);
+ bool GetDebugserverSharedCacheInfo(uuid_t &uuid,
+ std::string &shared_cache_path);
+ bool GetInferiorSharedCacheFilepath(std::string &inferior_sc_path);
+ JSONGenerator::ObjectSP GetInferiorSharedCacheInfo(nub_process_t pid);
nub_size_t GetNumThreads() const;
nub_thread_t GetThreadAtIndex(nub_size_t thread_idx) const;
@@ -474,6 +477,14 @@ private:
void *(*m_dyld_process_info_create)(task_t task, uint64_t timestamp,
kern_return_t *kernelError);
+ void *(*m_dyld_process_create_for_task)(task_read_t task, kern_return_t *kr);
+ void *(*m_dyld_process_snapshot_create_for_process)(void *process,
+ kern_return_t *kr);
+ void *(*m_dyld_process_snapshot_get_shared_cache)(void *snapshot);
+ void (*m_dyld_shared_cache_for_each_file)(
+ void *cache, void (^block)(const char *file_path));
+ void (*m_dyld_process_snapshot_dispose)(void *snapshot);
+ void (*m_dyld_process_dispose)(void *process);
void (*m_dyld_process_info_for_each_image)(
void *info, void (^callback)(uint64_t machHeaderAddress,
const uuid_t uuid, const char *path));
@@ -481,6 +492,7 @@ private:
void (*m_dyld_process_info_get_cache)(void *info, void *cacheInfo);
uint32_t (*m_dyld_process_info_get_platform)(void *info);
void (*m_dyld_process_info_get_state)(void *info, void *stateInfo);
+ const char *(*m_dyld_shared_cache_file_path)();
};
#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHPROCESS_H
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
index 3afaaa2..10ed804 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
@@ -534,13 +534,35 @@ MachProcess::MachProcess()
m_image_infos_baton(NULL), m_sent_interrupt_signo(0),
m_auto_resume_signo(0), m_did_exec(false),
m_dyld_process_info_create(nullptr),
+ m_dyld_process_create_for_task(nullptr),
+ m_dyld_process_snapshot_create_for_process(nullptr),
+ m_dyld_process_snapshot_get_shared_cache(nullptr),
+ m_dyld_shared_cache_for_each_file(nullptr),
+ m_dyld_process_snapshot_dispose(nullptr), m_dyld_process_dispose(nullptr),
m_dyld_process_info_for_each_image(nullptr),
m_dyld_process_info_release(nullptr),
m_dyld_process_info_get_cache(nullptr),
- m_dyld_process_info_get_state(nullptr) {
+ m_dyld_process_info_get_state(nullptr),
+ m_dyld_shared_cache_file_path(nullptr) {
m_dyld_process_info_create =
(void *(*)(task_t task, uint64_t timestamp, kern_return_t * kernelError))
dlsym(RTLD_DEFAULT, "_dyld_process_info_create");
+
+ m_dyld_process_create_for_task =
+ (void *(*)(task_read_t, kern_return_t *))dlsym(
+ RTLD_DEFAULT, "dyld_process_create_for_task");
+ m_dyld_process_snapshot_create_for_process =
+ (void *(*)(void *, kern_return_t *))dlsym(
+ RTLD_DEFAULT, "dyld_process_snapshot_create_for_process");
+ m_dyld_process_snapshot_get_shared_cache = (void *(*)(void *))dlsym(
+ RTLD_DEFAULT, "dyld_process_snapshot_get_shared_cache");
+ m_dyld_shared_cache_for_each_file =
+ (void (*)(void *, void (^)(const char *)))dlsym(
+ RTLD_DEFAULT, "dyld_shared_cache_for_each_file");
+ m_dyld_process_snapshot_dispose =
+ (void (*)(void *))dlsym(RTLD_DEFAULT, "dyld_process_snapshot_dispose");
+ m_dyld_process_dispose =
+ (void (*)(void *))dlsym(RTLD_DEFAULT, "dyld_process_dispose");
m_dyld_process_info_for_each_image =
(void (*)(void *info, void (^)(uint64_t machHeaderAddress,
const uuid_t uuid, const char *path)))
@@ -553,6 +575,8 @@ MachProcess::MachProcess()
RTLD_DEFAULT, "_dyld_process_info_get_platform");
m_dyld_process_info_get_state = (void (*)(void *info, void *stateInfo))dlsym(
RTLD_DEFAULT, "_dyld_process_info_get_state");
+ m_dyld_shared_cache_file_path =
+ (const char *(*)())dlsym(RTLD_DEFAULT, "dyld_shared_cache_file_path");
DNBLogThreadedIf(LOG_PROCESS | LOG_VERBOSE, "%s", __PRETTY_FUNCTION__);
}
@@ -1179,13 +1203,82 @@ JSONGenerator::ObjectSP MachProcess::GetLibrariesInfoForAddresses(
/* report_load_commands = */ true);
}
-// From dyld's internal podyld_process_info.h:
+bool MachProcess::GetDebugserverSharedCacheInfo(
+ uuid_t &uuid, std::string &shared_cache_path) {
+ uuid_clear(uuid);
+ shared_cache_path.clear();
+
+ if (m_dyld_process_info_create && m_dyld_process_info_get_cache) {
+ kern_return_t kern_ret;
+ dyld_process_info info =
+ m_dyld_process_info_create(mach_task_self(), 0, &kern_ret);
+ if (info) {
+ struct dyld_process_cache_info shared_cache_info;
+ m_dyld_process_info_get_cache(info, &shared_cache_info);
+ uuid_copy(uuid, shared_cache_info.cacheUUID);
+ m_dyld_process_info_release(info);
+ }
+ }
+ if (m_dyld_shared_cache_file_path) {
+ const char *cache_path = m_dyld_shared_cache_file_path();
+ if (cache_path)
+ shared_cache_path = cache_path;
+ }
+ if (!uuid_is_null(uuid))
+ return true;
+ return false;
+}
+
+bool MachProcess::GetInferiorSharedCacheFilepath(
+ std::string &inferior_sc_path) {
+ inferior_sc_path.clear();
+
+ if (!m_dyld_process_create_for_task ||
+ !m_dyld_process_snapshot_create_for_process ||
+ !m_dyld_process_snapshot_get_shared_cache ||
+ !m_dyld_shared_cache_for_each_file || !m_dyld_process_snapshot_dispose ||
+ !m_dyld_process_dispose)
+ return false;
+
+ __block std::string sc_path;
+ kern_return_t kr;
+ void *process = m_dyld_process_create_for_task(m_task.TaskPort(), &kr);
+ if (kr != KERN_SUCCESS)
+ return false;
+ void *snapshot = m_dyld_process_snapshot_create_for_process(process, &kr);
+ if (kr != KERN_SUCCESS)
+ return false;
+ void *cache = m_dyld_process_snapshot_get_shared_cache(snapshot);
+
+ // The shared cache is a collection of files on disk, this callback
+ // will iterate over all of them.
+ // The first filepath provided is the base filename of the cache.
+ __block bool done = false;
+ m_dyld_shared_cache_for_each_file(cache, ^(const char *path) {
+ if (done) {
+ return;
+ }
+ done = true;
+ sc_path = path;
+ });
+ m_dyld_process_snapshot_dispose(snapshot);
+ m_dyld_process_dispose(process);
+
+ inferior_sc_path = sc_path;
+ if (!sc_path.empty())
+ return true;
+ return false;
+}
+
+// From dyld's internal dyld_process_info.h:
-JSONGenerator::ObjectSP MachProcess::GetSharedCacheInfo(nub_process_t pid) {
+JSONGenerator::ObjectSP
+MachProcess::GetInferiorSharedCacheInfo(nub_process_t pid) {
JSONGenerator::DictionarySP reply_sp(new JSONGenerator::Dictionary());
- kern_return_t kern_ret;
+ uuid_t inferior_sc_uuid;
if (m_dyld_process_info_create && m_dyld_process_info_get_cache) {
+ kern_return_t kern_ret;
dyld_process_info info =
m_dyld_process_info_create(m_task.TaskPort(), 0, &kern_ret);
if (info) {
@@ -1197,6 +1290,7 @@ JSONGenerator::ObjectSP MachProcess::GetSharedCacheInfo(nub_process_t pid) {
uuid_string_t uuidstr;
uuid_unparse_upper(shared_cache_info.cacheUUID, uuidstr);
+ uuid_copy(inferior_sc_uuid, shared_cache_info.cacheUUID);
reply_sp->AddStringItem("shared_cache_uuid", uuidstr);
reply_sp->AddBooleanItem("no_shared_cache", shared_cache_info.noCache);
@@ -1206,6 +1300,29 @@ JSONGenerator::ObjectSP MachProcess::GetSharedCacheInfo(nub_process_t pid) {
m_dyld_process_info_release(info);
}
}
+
+ // If debugserver and the inferior are have the same cache UUID,
+ // use the simple call to get the filepath to debugserver's shared
+ // cache, return that.
+ uuid_t debugserver_sc_uuid;
+ std::string debugserver_sc_path;
+ bool found_sc_filepath = false;
+ if (GetDebugserverSharedCacheInfo(debugserver_sc_uuid, debugserver_sc_path)) {
+ if (uuid_compare(inferior_sc_uuid, debugserver_sc_uuid) == 0 &&
+ !debugserver_sc_path.empty()) {
+ reply_sp->AddStringItem("shared_cache_path", debugserver_sc_path);
+ found_sc_filepath = true;
+ }
+ }
+
+ // Use SPI that are only available on newer OSes to fetch the
+ // filepath of the shared cache of the inferior, if available.
+ if (!found_sc_filepath) {
+ std::string inferior_sc_path;
+ if (GetInferiorSharedCacheFilepath(inferior_sc_path))
+ reply_sp->AddStringItem("shared_cache_path", inferior_sc_path);
+ }
+
return reply_sp;
}
@@ -1739,7 +1856,7 @@ bool MachProcess::Detach() {
ReplyToAllExceptions();
}
- m_task.ShutDownExcecptionThread();
+ m_task.ShutDownExceptionThread();
// Detach from our process
errno = 0;
@@ -2853,12 +2970,6 @@ pid_t MachProcess::AttachForDebug(
if (err.Success()) {
m_flags |= eMachProcessFlagsAttached;
- // Sleep a bit to let the exception get received and set our process
- // status
- // to stopped.
- ::usleep(250000);
- DNBLog("[LaunchAttach] (%d) Done napping after ptrace(PT_ATTACHEXC)'ing",
- getpid());
DNBLogThreadedIf(LOG_PROCESS, "successfully attached to pid %d", pid);
return m_pid;
} else {
diff --git a/lldb/tools/debugserver/source/MacOSX/MachTask.h b/lldb/tools/debugserver/source/MacOSX/MachTask.h
index 915f65a..40fdbe9 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachTask.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachTask.h
@@ -68,7 +68,7 @@ public:
bool ExceptionPortIsValid() const;
kern_return_t SaveExceptionPortInfo();
kern_return_t RestoreExceptionPortInfo();
- kern_return_t ShutDownExcecptionThread();
+ void ShutDownExceptionThread();
bool StartExceptionThread(
const RNBContext::IgnoredExceptions &ignored_exceptions, DNBError &err);
diff --git a/lldb/tools/debugserver/source/MacOSX/MachTask.mm b/lldb/tools/debugserver/source/MacOSX/MachTask.mm
index e5bbab8..22ad0c4 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachTask.mm
+++ b/lldb/tools/debugserver/source/MacOSX/MachTask.mm
@@ -145,10 +145,8 @@ bool MachTask::ExceptionPortIsValid() const {
//----------------------------------------------------------------------
void MachTask::Clear() {
// Do any cleanup needed for this task
- if (m_exception_thread)
- ShutDownExcecptionThread();
+ ShutDownExceptionThread();
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;
@@ -685,8 +683,11 @@ bool MachTask::StartExceptionThread(
return false;
}
-kern_return_t MachTask::ShutDownExcecptionThread() {
+void MachTask::ShutDownExceptionThread() {
DNBError err;
+
+ if (!m_exception_thread)
+ return;
err = RestoreExceptionPortInfo();
@@ -702,6 +703,8 @@ kern_return_t MachTask::ShutDownExcecptionThread() {
if (DNBLogCheckLogBit(LOG_TASK) || err.Fail())
err.LogThreaded("::pthread_join ( thread = %p, value_ptr = NULL)",
m_exception_thread);
+
+ m_exception_thread = nullptr;
// Deallocate our exception port that we used to track our child process
mach_port_t task_self = mach_task_self();
@@ -713,7 +716,7 @@ kern_return_t MachTask::ShutDownExcecptionThread() {
m_exec_will_be_suspended = false;
m_do_double_resume = false;
- return err.Status();
+ return;
}
void *MachTask::ExceptionThread(void *arg) {