From 8b39b6c50a01bcfa280151b43079dab428cbab45 Mon Sep 17 00:00:00 2001 From: Drew Richardson Date: Wed, 16 Jul 2014 12:00:00 -0700 Subject: gator: Version 5.19 Signed-off-by: Drew Richardson --- daemon/Proc.cpp | 106 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 35 deletions(-) (limited to 'daemon/Proc.cpp') diff --git a/daemon/Proc.cpp b/daemon/Proc.cpp index e0b9e22..9f01770 100644 --- a/daemon/Proc.cpp +++ b/daemon/Proc.cpp @@ -57,14 +57,57 @@ static bool readProcStat(ProcStat *const ps, const char *const pathname, DynBuf return true; } -static bool readProcTask(Buffer *const buffer, const int pid, const char *const image, DynBuf *const printb, DynBuf *const b) { +static const char *readProcExe(DynBuf *const printb, const int pid, const int tid, DynBuf *const b) { + if (tid == -1 ? !printb->printf("/proc/%i/exe", pid) + : !printb->printf("/proc/%i/task/%i/exe", pid, tid)) { + logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__); + return NULL; + } + + const int err = b->readlink(printb->getBuf()); + const char *image; + if (err == 0) { + image = strrchr(b->getBuf(), '/'); + if (image == NULL) { + image = b->getBuf(); + } else { + ++image; + } + } else if (err == -ENOENT) { + // readlink /proc/[pid]/exe returns ENOENT for kernel threads + image = "\0"; + } else { + logg->logMessage("%s(%s:%i): DynBuf::readlink failed", __FUNCTION__, __FILE__, __LINE__); + return NULL; + } + + // Android apps are run by app_process but the cmdline is changed to reference the actual app name + if (strcmp(image, "app_process") != 0) { + return image; + } + + if (tid == -1 ? !printb->printf("/proc/%i/cmdline", pid) + : !printb->printf("/proc/%i/task/%i/cmdline", pid, tid)) { + logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__); + return NULL; + } + + if (!b->read(printb->getBuf())) { + logg->logMessage("%s(%s:%i): DynBuf::read failed, likely because the thread exited", __FUNCTION__, __FILE__, __LINE__); + return NULL; + } + + return b->getBuf(); +} + +static bool readProcTask(Buffer *const buffer, const int pid, DynBuf *const printb, DynBuf *const b1, DynBuf *const b2) { bool result = false; - if (!b->printf("/proc/%i/task", pid)) { + if (!b1->printf("/proc/%i/task", pid)) { logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__); return result; } - DIR *task = opendir(b->getBuf()); + DIR *task = opendir(b1->getBuf()); if (task == NULL) { logg->logMessage("%s(%s:%i): opendir failed", __FUNCTION__, __FILE__, __LINE__); return result; @@ -84,11 +127,17 @@ static bool readProcTask(Buffer *const buffer, const int pid, const char *const goto fail; } ProcStat ps; - if (!readProcStat(&ps, printb->getBuf(), b)) { + if (!readProcStat(&ps, printb->getBuf(), b1)) { logg->logMessage("%s(%s:%i): readProcStat failed", __FUNCTION__, __FILE__, __LINE__); goto fail; } + const char *const image = readProcExe(printb, pid, tid, b2); + if (image == NULL) { + logg->logMessage("%s(%s:%i): readImage failed", __FUNCTION__, __FILE__, __LINE__); + goto fail; + } + buffer->comm(pid, tid, image, ps.comm); } @@ -100,7 +149,7 @@ static bool readProcTask(Buffer *const buffer, const int pid, const char *const return result; } -bool readProc(Buffer *const buffer, DynBuf *const printb, DynBuf *const b1, DynBuf *const b2, DynBuf *const b3) { +bool readProc(Buffer *const buffer, bool sendMaps, DynBuf *const printb, DynBuf *const b1, DynBuf *const b2, DynBuf *const b3) { bool result = false; DIR *proc = opendir("/proc"); @@ -128,42 +177,29 @@ bool readProc(Buffer *const buffer, DynBuf *const printb, DynBuf *const b1, DynB goto fail; } - if (!printb->printf("/proc/%i/exe", pid)) { - logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__); - goto fail; - } - const int err = b1->readlink(printb->getBuf()); - const char *image; - if (err == 0) { - image = strrchr(b1->getBuf(), '/'); - if (image == NULL) { - image = b1->getBuf(); - } else { - ++image; + if (sendMaps) { + if (!printb->printf("/proc/%i/maps", pid)) { + logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__); + goto fail; + } + if (!b2->read(printb->getBuf())) { + logg->logMessage("%s(%s:%i): DynBuf::read failed, likely because the process exited", __FUNCTION__, __FILE__, __LINE__); + // This is not a fatal error - the process just doesn't exist any more + continue; } - } else if (err == -ENOENT) { - // readlink /proc/[pid]/exe returns ENOENT for kernel threads - image = "\0"; - } else { - logg->logMessage("%s(%s:%i): DynBuf::readlink failed", __FUNCTION__, __FILE__, __LINE__); - goto fail; - } - if (!printb->printf("/proc/%i/maps", pid)) { - logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__); - goto fail; + buffer->maps(pid, pid, b2->getBuf()); } - if (!b2->read(printb->getBuf())) { - logg->logMessage("%s(%s:%i): DynBuf::read failed, likely because the process exited", __FUNCTION__, __FILE__, __LINE__); - // This is not a fatal error - the process just doesn't exist any more - continue; - } - - buffer->maps(pid, pid, b2->getBuf()); if (ps.numThreads <= 1) { + const char *const image = readProcExe(printb, pid, -1, b1); + if (image == NULL) { + logg->logMessage("%s(%s:%i): readImage failed", __FUNCTION__, __FILE__, __LINE__); + goto fail; + } + buffer->comm(pid, pid, image, ps.comm); } else { - if (!readProcTask(buffer, pid, image, printb, b3)) { + if (!readProcTask(buffer, pid, printb, b1, b3)) { logg->logMessage("%s(%s:%i): readProcTask failed", __FUNCTION__, __FILE__, __LINE__); goto fail; } -- cgit v1.2.3