using ::android::base::AllPids; using ::android::base::ConsumeSuffix; using ::android::base::function_ref; using ::android::base::ReadFileToString; using ::android::base::Readlink; using ::android::base::Result; using ::android::base::unique_fd; using ::android::fs_mgr::Fstab; using ::android::fs_mgr::FstabEntry; using ::android::fs_mgr::ReadFstabFromProcMounts; using ::std::placeholders::_1;
static Result<std::vector<FstabEntry>> GetProcMountsMatches(
function_ref<bool(std::string_view)> predicate) {
Fstab fstab; if (!ReadFstabFromProcMounts(&fstab)) { return Errorf("Failed to read fstab from /proc/mounts");
}
std::vector<FstabEntry> entries; for (FstabEntry& entry : fstab) { // Ignore swap areas as a swap area doesn't have a meaningful `mount_point` (a.k.a., `fs_file`) // field, according to fstab(5). In addition, ignore any other entries whose mount points are // not absolute paths, just in case there are other fs types that also have an meaningless mount // point. if (entry.fs_type == "swap" || !entry.mount_point.starts_with('/')) { continue;
} if (predicate(entry.mount_point)) {
entries.push_back(std::move(entry));
}
} return entries;
}
Result<void> EnsureNoProcessInDir(const std::string& dir, uint32_t timeout_ms, bool try_kill) { // Pairs of pid and process name, indexed by pidfd.
std::unordered_map<int, std::pair<pid_t, std::string>> running_processes;
std::vector<struct pollfd> pollfds;
std::vector<unique_fd> pidfds;
for (pid_t pid : AllPids()) {
std::string exe; if (!Readlink(ART_FORMAT("/proc/{}/exe", pid), &exe)) { // The caller may not have access to all processes. That's okay. When using this method, we // must grant the caller access to the processes that we are interested in. continue;
}
if (PathStartsWith(exe, dir)) {
unique_fd pidfd = PidfdOpen(pid, /*flags=*/0); if (pidfd < 0) { if (errno == ESRCH) { // The process has gone now. continue;
} return ErrnoErrorf("Failed to pidfd_open {}", pid);
}
std::string name; if (!ReadFileToString(ART_FORMAT("/proc/{}/comm", pid), &name)) {
PLOG(WARNING) << "Failed to get process name for pid " << pid;
}
size_t pos = name.find_first_of("\n\0"); if (pos != std::string::npos) {
name.resize(pos);
}
LOG(INFO) << ART_FORMAT( "Process '{}' (pid: {}) is still running. Waiting for it to exit", name, pid);
bool process_killed = false; for (constauto& [pidfd, pair] : running_processes) { constauto& [pid, name] = pair;
LOG(ERROR) << ART_FORMAT( "Process '{}' (pid: {}) is still running after {}ms", name, pid, timeout_ms); if (try_kill) {
LOG(INFO) << ART_FORMAT("Killing '{}' (pid: {})", name, pid); if (kill(pid, SIGKILL) != 0) {
PLOG(ERROR) << ART_FORMAT("Failed to kill '{}' (pid: {})", name, pid);
}
process_killed = true;
}
}
if (process_killed) { // Wait another round for processes to exit after being killed.
OR_RETURN(wait_for_processes());
} if (!running_processes.empty()) { return Errorf("Some process(es) are still running after {}ms", timeout_ms);
} return {};
}
} // namespace tools
} // namespace art
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.