Skip to content

Commit 0ddd9a5

Browse files
committed
handle edge cases better
1 parent 617de12 commit 0ddd9a5

File tree

1 file changed

+58
-32
lines changed

1 file changed

+58
-32
lines changed

lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp

Lines changed: 58 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -480,21 +480,30 @@ std::string PlatformAndroid::GetRunAs() {
480480
uint32_t
481481
PlatformAndroid::FindProcesses(const ProcessInstanceInfoMatch &match_info,
482482
ProcessInstanceInfoList &proc_infos) {
483-
// Use the parent implementation for host platform
483+
proc_infos.clear();
484+
485+
// When LLDB is running natively on an Android device (IsHost() == true),
486+
// use the parent class's standard Linux /proc enumeration. IsHost() is only
487+
// true when compiled for Android (#if defined(__ANDROID__)), so calling
488+
// PlatformLinux methods is safe (Android is Linux-based).
484489
if (IsHost())
485490
return PlatformLinux::FindProcesses(match_info, proc_infos);
486491

487-
// For remote Android platform, implement process name lookup using adb
488-
proc_infos.clear();
492+
// Remote Android platform: implement process name lookup using 'pidof' over
493+
// adb.
489494

490-
// Check if we're looking for a process by name
495+
// LLDB stores the search name in GetExecutableFile() (even though it's
496+
// actually a process name like "com.android.chrome" rather than an
497+
// executable path). If no search name is provided, we can't use
498+
// 'pidof', so return early with no results.
491499
const ProcessInstanceInfo &match_process_info = match_info.GetProcessInfo();
492500
if (!match_process_info.GetExecutableFile() ||
493501
match_info.GetNameMatchType() == NameMatch::Ignore) {
494-
// Fall back to the parent implementation if not searching by name
495-
return PlatformLinux::FindProcesses(match_info, proc_infos);
502+
return 0;
496503
}
497504

505+
// Extract the process name to search for (typically an Android package name
506+
// like "com.example.app" or binary name like "app_process64")
498507
std::string process_name = match_process_info.GetExecutableFile().GetPath();
499508
if (process_name.empty())
500509
return 0;
@@ -509,10 +518,12 @@ PlatformAndroid::FindProcesses(const ProcessInstanceInfoMatch &match_info,
509518
return 0;
510519
}
511520

512-
// Use 'pidof' command to get the PID for the process name
521+
// Use 'pidof' command to get PIDs for the process name.
522+
// Quote the process name to handle special characters (spaces, etc.)
513523
std::string pidof_output;
514-
std::string command = "pidof " + process_name;
515-
error = adb->Shell(command.c_str(), seconds(5), &pidof_output);
524+
StreamString command;
525+
command.Printf("pidof '%s'", process_name.c_str());
526+
error = adb->Shell(command.GetData(), seconds(5), &pidof_output);
516527

517528
if (error.Fail()) {
518529
Log *log = GetLog(LLDBLog::Platform);
@@ -521,39 +532,54 @@ PlatformAndroid::FindProcesses(const ProcessInstanceInfoMatch &match_info,
521532
return 0;
522533
}
523534

524-
// Parse the PID from pidof output
535+
// Parse PIDs from pidof output.
536+
// Note: pidof can return multiple PIDs (space-separated) if multiple
537+
// instances of the same executable are running.
525538
pidof_output = llvm::StringRef(pidof_output).trim().str();
526539
if (pidof_output.empty()) {
527-
// No process found with that name
528-
return 0;
529-
}
530-
531-
// Parse the output as a single PID
532-
lldb::pid_t pid;
533-
if (!llvm::to_integer(pidof_output, pid)) {
534540
Log *log = GetLog(LLDBLog::Platform);
535-
LLDB_LOGF(log, "PlatformAndroid::%s failed to parse PID from output: '%s'",
536-
__FUNCTION__, pidof_output.c_str());
541+
LLDB_LOGF(log, "PlatformAndroid::%s no process found with name '%s'",
542+
__FUNCTION__, process_name.c_str());
537543
return 0;
538544
}
539545

540-
// Create ProcessInstanceInfo for the found process
541-
ProcessInstanceInfo process_info;
542-
process_info.SetProcessID(pid);
543-
process_info.GetExecutableFile().SetFile(process_name,
544-
FileSpec::Style::posix);
546+
// Split the output by whitespace to handle multiple PIDs
547+
llvm::SmallVector<llvm::StringRef, 8> pid_strings;
548+
llvm::StringRef(pidof_output).split(pid_strings, ' ', -1, false);
545549

546-
// Check if this process matches the criteria
547-
if (match_info.Matches(process_info)) {
548-
proc_infos.push_back(process_info);
550+
uint32_t num_matches = 0;
551+
for (llvm::StringRef pid_str : pid_strings) {
552+
pid_str = pid_str.trim();
553+
if (pid_str.empty())
554+
continue;
549555

550-
Log *log = GetLog(LLDBLog::Platform);
551-
LLDB_LOGF(log, "PlatformAndroid::%s found process '%s' with PID %llu",
552-
__FUNCTION__, process_name.c_str(), (unsigned long long)pid);
553-
return 1;
556+
lldb::pid_t pid;
557+
if (!llvm::to_integer(pid_str, pid)) {
558+
Log *log = GetLog(LLDBLog::Platform);
559+
LLDB_LOGF(log,
560+
"PlatformAndroid::%s failed to parse PID from output: '%s'",
561+
__FUNCTION__, pid_str.str().c_str());
562+
continue;
563+
}
564+
565+
// Create ProcessInstanceInfo for the found process
566+
ProcessInstanceInfo process_info;
567+
process_info.SetProcessID(pid);
568+
process_info.GetExecutableFile().SetFile(process_name,
569+
FileSpec::Style::posix);
570+
571+
// Check if this process matches the criteria
572+
if (match_info.Matches(process_info)) {
573+
proc_infos.push_back(process_info);
574+
num_matches++;
575+
576+
Log *log = GetLog(LLDBLog::Platform);
577+
LLDB_LOGF(log, "PlatformAndroid::%s found process '%s' with PID %llu",
578+
__FUNCTION__, process_name.c_str(), (unsigned long long)pid);
579+
}
554580
}
555581

556-
return 0;
582+
return num_matches;
557583
}
558584

559585
std::unique_ptr<AdbSyncService> PlatformAndroid::GetSyncService(Status &error) {

0 commit comments

Comments
 (0)