// This file defines the handler for the reserved signal sent by the Android // platform's profilers. The accompanying signal value discriminates between // specific requestors: // 0: heapprofd heap profiler. // 1: traced_perf perf profiler. static constexpr int kHeapprofdSignalValue = 0; static constexpr int kTracedPerfSignalValue = 1;
// The perfetto_hprof ART plugin installs a signal handler to handle this signal. That plugin // does not get loaded for a) non-apps, b) non-profilable apps on user. The default signal // disposition is to crash. We do not want the target to crash if we accidentally target a // non-app or non-profilable process.
signal(BIONIC_SIGNAL_ART_PROFILER, SIG_IGN);
}
int signal_value = info->si_value.sival_int;
async_safe_format_log(ANDROID_LOG_INFO, "libc", "%s: received profiling signal with si_value: %d",
getprogname(), signal_value);
// Proceed only if the process is considered profileable. bool profileable = false;
android_mallopt(M_GET_PROCESS_PROFILEABLE, &profileable, sizeof(profileable)); if (!profileable) {
async_safe_write_log(ANDROID_LOG_ERROR, "libc", "profiling signal rejected (not profileable)"); return;
}
// Temporarily override SIGSYS handling, in a best-effort attempt at not // crashing if we happen to be running in a process with a seccomp filter that // disallows some of the syscalls done by this signal handler. This protects // against SECCOMP_RET_TRAP with a crashing SIGSYS handler (typical of android // minijails). Won't help if the filter is using SECCOMP_RET_KILL_*. // Note: the override is process-wide, but short-lived. The syscalls are still // blocked, but the overridden handler recovers from SIGSYS, and fakes the // syscall return value as ENOSYS. struct sigaction sigsys_override = {};
sigsys_override.sa_sigaction = &HandleSigsysSeccompOverride;
sigsys_override.sa_flags = SA_SIGINFO;
// Open /proc/self/{maps,mem}, connect to traced_perf, send the fds over the // socket. Everything happens synchronously within the signal handler. Socket // is made non-blocking, and we do not retry. staticvoid HandleTracedPerfSignal() {
ScopedFd sock_fd{ socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0/*protocol*/) }; if (sock_fd.get() == -1) {
async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to create socket: %m"); return;
}
sockaddr_un saddr{ AF_UNIX, "/dev/socket/traced_perf" };
size_t addrlen = sizeof(sockaddr_un); if (connect(sock_fd.get(), reinterpret_cast<conststruct sockaddr*>(&saddr), addrlen) == -1) {
async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to connect to traced_perf socket: %m"); return;
}
// If the process is undumpable, /proc/self/mem will be owned by root:root, and therefore // inaccessible to the process itself (see man 5 proc). We temporarily mark the process as // dumpable to allow for the open. Note: prctl is not async signal safe per posix, but bionic's // implementation is. Error checking on prctls is omitted due to them being trivial. int orig_dumpable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0); if (!orig_dumpable) {
prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
}
ScopedFd maps_fd{ open("/proc/self/maps", O_RDONLY | O_CLOEXEC) };
ScopedFd mem_fd{ open("/proc/self/mem", O_RDONLY | O_CLOEXEC) }; if (!orig_dumpable) {
prctl(PR_SET_DUMPABLE, orig_dumpable, 0, 0, 0);
}
if (maps_fd.get() == -1) {
async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open /proc/self/maps: %m"); return;
} if (mem_fd.get() == -1) {
async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open /proc/self/mem: %m"); return;
}
async_safe_format_log(
ANDROID_LOG_WARN, "libc", "Profiling setup: trapped seccomp SIGSYS for syscall %d. Returning ENOSYS to caller.",
info->si_syscall);
// The handler is responsible for setting the return value as if the system // call happened (which is arch-specific). Use a plausible unsuccessful value. auto ret = -ENOSYS;
ucontext_t* ctx = reinterpret_cast<ucontext_t*>(void_context);
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.