Skip to content

Commit 4a62991

Browse files
authored
Merge pull request #12001 from jasonmolenda/debugserver-report-shared-cache-filepath
2 parents eecec9a + e227d83 commit 4a62991

File tree

3 files changed

+135
-6
lines changed

3 files changed

+135
-6
lines changed

lldb/tools/debugserver/source/DNB.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1101,7 +1101,7 @@ DNBGetLibrariesInfoForAddresses(nub_process_t pid,
11011101
JSONGenerator::ObjectSP DNBGetSharedCacheInfo(nub_process_t pid) {
11021102
MachProcessSP procSP;
11031103
if (GetProcessSP(pid, procSP)) {
1104-
return procSP->GetSharedCacheInfo(pid);
1104+
return procSP->GetInferiorSharedCacheInfo(pid);
11051105
}
11061106
return JSONGenerator::ObjectSP();
11071107
}

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,10 @@ class MachProcess {
283283
JSONGenerator::ObjectSP
284284
GetAllLoadedLibrariesInfos(nub_process_t pid,
285285
bool fetch_report_load_commands);
286-
JSONGenerator::ObjectSP GetSharedCacheInfo(nub_process_t pid);
286+
bool GetDebugserverSharedCacheInfo(uuid_t &uuid,
287+
std::string &shared_cache_path);
288+
bool GetInferiorSharedCacheFilepath(std::string &inferior_sc_path);
289+
JSONGenerator::ObjectSP GetInferiorSharedCacheInfo(nub_process_t pid);
287290

288291
nub_size_t GetNumThreads() const;
289292
nub_thread_t GetThreadAtIndex(nub_size_t thread_idx) const;
@@ -474,13 +477,22 @@ class MachProcess {
474477

475478
void *(*m_dyld_process_info_create)(task_t task, uint64_t timestamp,
476479
kern_return_t *kernelError);
480+
void *(*m_dyld_process_create_for_task)(task_read_t task, kern_return_t *kr);
481+
void *(*m_dyld_process_snapshot_create_for_process)(void *process,
482+
kern_return_t *kr);
483+
void *(*m_dyld_process_snapshot_get_shared_cache)(void *snapshot);
484+
void (*m_dyld_shared_cache_for_each_file)(
485+
void *cache, void (^block)(const char *file_path));
486+
void (*m_dyld_process_snapshot_dispose)(void *snapshot);
487+
void (*m_dyld_process_dispose)(void *process);
477488
void (*m_dyld_process_info_for_each_image)(
478489
void *info, void (^callback)(uint64_t machHeaderAddress,
479490
const uuid_t uuid, const char *path));
480491
void (*m_dyld_process_info_release)(void *info);
481492
void (*m_dyld_process_info_get_cache)(void *info, void *cacheInfo);
482493
uint32_t (*m_dyld_process_info_get_platform)(void *info);
483494
void (*m_dyld_process_info_get_state)(void *info, void *stateInfo);
495+
const char *(*m_dyld_shared_cache_file_path)();
484496
};
485497

486498
#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHPROCESS_H

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

Lines changed: 121 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -534,13 +534,35 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
534534
m_image_infos_baton(NULL), m_sent_interrupt_signo(0),
535535
m_auto_resume_signo(0), m_did_exec(false),
536536
m_dyld_process_info_create(nullptr),
537+
m_dyld_process_create_for_task(nullptr),
538+
m_dyld_process_snapshot_create_for_process(nullptr),
539+
m_dyld_process_snapshot_get_shared_cache(nullptr),
540+
m_dyld_shared_cache_for_each_file(nullptr),
541+
m_dyld_process_snapshot_dispose(nullptr), m_dyld_process_dispose(nullptr),
537542
m_dyld_process_info_for_each_image(nullptr),
538543
m_dyld_process_info_release(nullptr),
539544
m_dyld_process_info_get_cache(nullptr),
540-
m_dyld_process_info_get_state(nullptr) {
545+
m_dyld_process_info_get_state(nullptr),
546+
m_dyld_shared_cache_file_path(nullptr) {
541547
m_dyld_process_info_create =
542548
(void *(*)(task_t task, uint64_t timestamp, kern_return_t * kernelError))
543549
dlsym(RTLD_DEFAULT, "_dyld_process_info_create");
550+
551+
m_dyld_process_create_for_task =
552+
(void *(*)(task_read_t, kern_return_t *))dlsym(
553+
RTLD_DEFAULT, "dyld_process_create_for_task");
554+
m_dyld_process_snapshot_create_for_process =
555+
(void *(*)(void *, kern_return_t *))dlsym(
556+
RTLD_DEFAULT, "dyld_process_snapshot_create_for_process");
557+
m_dyld_process_snapshot_get_shared_cache = (void *(*)(void *))dlsym(
558+
RTLD_DEFAULT, "dyld_process_snapshot_get_shared_cache");
559+
m_dyld_shared_cache_for_each_file =
560+
(void (*)(void *, void (^)(const char *)))dlsym(
561+
RTLD_DEFAULT, "dyld_shared_cache_for_each_file");
562+
m_dyld_process_snapshot_dispose =
563+
(void (*)(void *))dlsym(RTLD_DEFAULT, "dyld_process_snapshot_dispose");
564+
m_dyld_process_dispose =
565+
(void (*)(void *))dlsym(RTLD_DEFAULT, "dyld_process_dispose");
544566
m_dyld_process_info_for_each_image =
545567
(void (*)(void *info, void (^)(uint64_t machHeaderAddress,
546568
const uuid_t uuid, const char *path)))
@@ -553,6 +575,8 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
553575
RTLD_DEFAULT, "_dyld_process_info_get_platform");
554576
m_dyld_process_info_get_state = (void (*)(void *info, void *stateInfo))dlsym(
555577
RTLD_DEFAULT, "_dyld_process_info_get_state");
578+
m_dyld_shared_cache_file_path =
579+
(const char *(*)())dlsym(RTLD_DEFAULT, "dyld_shared_cache_file_path");
556580

557581
DNBLogThreadedIf(LOG_PROCESS | LOG_VERBOSE, "%s", __PRETTY_FUNCTION__);
558582
}
@@ -1179,13 +1203,82 @@ static bool mach_header_validity_test(uint32_t magic, uint32_t cputype) {
11791203
/* report_load_commands = */ true);
11801204
}
11811205

1182-
// From dyld's internal podyld_process_info.h:
1206+
bool MachProcess::GetDebugserverSharedCacheInfo(
1207+
uuid_t &uuid, std::string &shared_cache_path) {
1208+
uuid_clear(uuid);
1209+
shared_cache_path.clear();
1210+
1211+
if (m_dyld_process_info_create && m_dyld_process_info_get_cache) {
1212+
kern_return_t kern_ret;
1213+
dyld_process_info info =
1214+
m_dyld_process_info_create(mach_task_self(), 0, &kern_ret);
1215+
if (info) {
1216+
struct dyld_process_cache_info shared_cache_info;
1217+
m_dyld_process_info_get_cache(info, &shared_cache_info);
1218+
uuid_copy(uuid, shared_cache_info.cacheUUID);
1219+
m_dyld_process_info_release(info);
1220+
}
1221+
}
1222+
if (m_dyld_shared_cache_file_path) {
1223+
const char *cache_path = m_dyld_shared_cache_file_path();
1224+
if (cache_path)
1225+
shared_cache_path = cache_path;
1226+
}
1227+
if (!uuid_is_null(uuid))
1228+
return true;
1229+
return false;
1230+
}
1231+
1232+
bool MachProcess::GetInferiorSharedCacheFilepath(
1233+
std::string &inferior_sc_path) {
1234+
inferior_sc_path.clear();
1235+
1236+
if (!m_dyld_process_create_for_task ||
1237+
!m_dyld_process_snapshot_create_for_process ||
1238+
!m_dyld_process_snapshot_get_shared_cache ||
1239+
!m_dyld_shared_cache_for_each_file || !m_dyld_process_snapshot_dispose ||
1240+
!m_dyld_process_dispose)
1241+
return false;
1242+
1243+
__block std::string sc_path;
1244+
kern_return_t kr;
1245+
void *process = m_dyld_process_create_for_task(m_task.TaskPort(), &kr);
1246+
if (kr != KERN_SUCCESS)
1247+
return false;
1248+
void *snapshot = m_dyld_process_snapshot_create_for_process(process, &kr);
1249+
if (kr != KERN_SUCCESS)
1250+
return false;
1251+
void *cache = m_dyld_process_snapshot_get_shared_cache(snapshot);
1252+
1253+
// The shared cache is a collection of files on disk, this callback
1254+
// will iterate over all of them.
1255+
// The first filepath provided is the base filename of the cache.
1256+
__block bool done = false;
1257+
m_dyld_shared_cache_for_each_file(cache, ^(const char *path) {
1258+
if (done) {
1259+
return;
1260+
}
1261+
done = true;
1262+
sc_path = path;
1263+
});
1264+
m_dyld_process_snapshot_dispose(snapshot);
1265+
m_dyld_process_dispose(process);
1266+
1267+
inferior_sc_path = sc_path;
1268+
if (!sc_path.empty())
1269+
return true;
1270+
return false;
1271+
}
1272+
1273+
// From dyld's internal dyld_process_info.h:
11831274

1184-
JSONGenerator::ObjectSP MachProcess::GetSharedCacheInfo(nub_process_t pid) {
1275+
JSONGenerator::ObjectSP
1276+
MachProcess::GetInferiorSharedCacheInfo(nub_process_t pid) {
11851277
JSONGenerator::DictionarySP reply_sp(new JSONGenerator::Dictionary());
11861278

1187-
kern_return_t kern_ret;
1279+
uuid_t inferior_sc_uuid;
11881280
if (m_dyld_process_info_create && m_dyld_process_info_get_cache) {
1281+
kern_return_t kern_ret;
11891282
dyld_process_info info =
11901283
m_dyld_process_info_create(m_task.TaskPort(), 0, &kern_ret);
11911284
if (info) {
@@ -1197,6 +1290,7 @@ static bool mach_header_validity_test(uint32_t magic, uint32_t cputype) {
11971290

11981291
uuid_string_t uuidstr;
11991292
uuid_unparse_upper(shared_cache_info.cacheUUID, uuidstr);
1293+
uuid_copy(inferior_sc_uuid, shared_cache_info.cacheUUID);
12001294
reply_sp->AddStringItem("shared_cache_uuid", uuidstr);
12011295

12021296
reply_sp->AddBooleanItem("no_shared_cache", shared_cache_info.noCache);
@@ -1206,6 +1300,29 @@ static bool mach_header_validity_test(uint32_t magic, uint32_t cputype) {
12061300
m_dyld_process_info_release(info);
12071301
}
12081302
}
1303+
1304+
// If debugserver and the inferior are have the same cache UUID,
1305+
// use the simple call to get the filepath to debugserver's shared
1306+
// cache, return that.
1307+
uuid_t debugserver_sc_uuid;
1308+
std::string debugserver_sc_path;
1309+
bool found_sc_filepath = false;
1310+
if (GetDebugserverSharedCacheInfo(debugserver_sc_uuid, debugserver_sc_path)) {
1311+
if (uuid_compare(inferior_sc_uuid, debugserver_sc_uuid) == 0 &&
1312+
!debugserver_sc_path.empty()) {
1313+
reply_sp->AddStringItem("shared_cache_path", debugserver_sc_path);
1314+
found_sc_filepath = true;
1315+
}
1316+
}
1317+
1318+
// Use SPI that are only available on newer OSes to fetch the
1319+
// filepath of the shared cache of the inferior, if available.
1320+
if (!found_sc_filepath) {
1321+
std::string inferior_sc_path;
1322+
if (GetInferiorSharedCacheFilepath(inferior_sc_path))
1323+
reply_sp->AddStringItem("shared_cache_path", inferior_sc_path);
1324+
}
1325+
12091326
return reply_sp;
12101327
}
12111328

0 commit comments

Comments
 (0)