summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/Proc.cpp')
-rw-r--r--daemon/Proc.cpp106
1 files changed, 71 insertions, 35 deletions
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
57 return true; 57 return true;
58} 58}
59 59
60static bool readProcTask(Buffer *const buffer, const int pid, const char *const image, DynBuf *const printb, DynBuf *const b) { 60static const char *readProcExe(DynBuf *const printb, const int pid, const int tid, DynBuf *const b) {
61 if (tid == -1 ? !printb->printf("/proc/%i/exe", pid)
62 : !printb->printf("/proc/%i/task/%i/exe", pid, tid)) {
63 logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
64 return NULL;
65 }
66
67 const int err = b->readlink(printb->getBuf());
68 const char *image;
69 if (err == 0) {
70 image = strrchr(b->getBuf(), '/');
71 if (image == NULL) {
72 image = b->getBuf();
73 } else {
74 ++image;
75 }
76 } else if (err == -ENOENT) {
77 // readlink /proc/[pid]/exe returns ENOENT for kernel threads
78 image = "\0";
79 } else {
80 logg->logMessage("%s(%s:%i): DynBuf::readlink failed", __FUNCTION__, __FILE__, __LINE__);
81 return NULL;
82 }
83
84 // Android apps are run by app_process but the cmdline is changed to reference the actual app name
85 if (strcmp(image, "app_process") != 0) {
86 return image;
87 }
88
89 if (tid == -1 ? !printb->printf("/proc/%i/cmdline", pid)
90 : !printb->printf("/proc/%i/task/%i/cmdline", pid, tid)) {
91 logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
92 return NULL;
93 }
94
95 if (!b->read(printb->getBuf())) {
96 logg->logMessage("%s(%s:%i): DynBuf::read failed, likely because the thread exited", __FUNCTION__, __FILE__, __LINE__);
97 return NULL;
98 }
99
100 return b->getBuf();
101}
102
103static bool readProcTask(Buffer *const buffer, const int pid, DynBuf *const printb, DynBuf *const b1, DynBuf *const b2) {
61 bool result = false; 104 bool result = false;
62 105
63 if (!b->printf("/proc/%i/task", pid)) { 106 if (!b1->printf("/proc/%i/task", pid)) {
64 logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__); 107 logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
65 return result; 108 return result;
66 } 109 }
67 DIR *task = opendir(b->getBuf()); 110 DIR *task = opendir(b1->getBuf());
68 if (task == NULL) { 111 if (task == NULL) {
69 logg->logMessage("%s(%s:%i): opendir failed", __FUNCTION__, __FILE__, __LINE__); 112 logg->logMessage("%s(%s:%i): opendir failed", __FUNCTION__, __FILE__, __LINE__);
70 return result; 113 return result;
@@ -84,11 +127,17 @@ static bool readProcTask(Buffer *const buffer, const int pid, const char *const
84 goto fail; 127 goto fail;
85 } 128 }
86 ProcStat ps; 129 ProcStat ps;
87 if (!readProcStat(&ps, printb->getBuf(), b)) { 130 if (!readProcStat(&ps, printb->getBuf(), b1)) {
88 logg->logMessage("%s(%s:%i): readProcStat failed", __FUNCTION__, __FILE__, __LINE__); 131 logg->logMessage("%s(%s:%i): readProcStat failed", __FUNCTION__, __FILE__, __LINE__);
89 goto fail; 132 goto fail;
90 } 133 }
91 134
135 const char *const image = readProcExe(printb, pid, tid, b2);
136 if (image == NULL) {
137 logg->logMessage("%s(%s:%i): readImage failed", __FUNCTION__, __FILE__, __LINE__);
138 goto fail;
139 }
140
92 buffer->comm(pid, tid, image, ps.comm); 141 buffer->comm(pid, tid, image, ps.comm);
93 } 142 }
94 143
@@ -100,7 +149,7 @@ static bool readProcTask(Buffer *const buffer, const int pid, const char *const
100 return result; 149 return result;
101} 150}
102 151
103bool readProc(Buffer *const buffer, DynBuf *const printb, DynBuf *const b1, DynBuf *const b2, DynBuf *const b3) { 152bool readProc(Buffer *const buffer, bool sendMaps, DynBuf *const printb, DynBuf *const b1, DynBuf *const b2, DynBuf *const b3) {
104 bool result = false; 153 bool result = false;
105 154
106 DIR *proc = opendir("/proc"); 155 DIR *proc = opendir("/proc");
@@ -128,42 +177,29 @@ bool readProc(Buffer *const buffer, DynBuf *const printb, DynBuf *const b1, DynB
128 goto fail; 177 goto fail;
129 } 178 }
130 179
131 if (!printb->printf("/proc/%i/exe", pid)) { 180 if (sendMaps) {
132 logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__); 181 if (!printb->printf("/proc/%i/maps", pid)) {
133 goto fail; 182 logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
134 } 183 goto fail;
135 const int err = b1->readlink(printb->getBuf()); 184 }
136 const char *image; 185 if (!b2->read(printb->getBuf())) {
137 if (err == 0) { 186 logg->logMessage("%s(%s:%i): DynBuf::read failed, likely because the process exited", __FUNCTION__, __FILE__, __LINE__);
138 image = strrchr(b1->getBuf(), '/'); 187 // This is not a fatal error - the process just doesn't exist any more
139 if (image == NULL) { 188 continue;
140 image = b1->getBuf();
141 } else {
142 ++image;
143 } 189 }
144 } else if (err == -ENOENT) {
145 // readlink /proc/[pid]/exe returns ENOENT for kernel threads
146 image = "\0";
147 } else {
148 logg->logMessage("%s(%s:%i): DynBuf::readlink failed", __FUNCTION__, __FILE__, __LINE__);
149 goto fail;
150 }
151 190
152 if (!printb->printf("/proc/%i/maps", pid)) { 191 buffer->maps(pid, pid, b2->getBuf());
153 logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
154 goto fail;
155 } 192 }
156 if (!b2->read(printb->getBuf())) {
157 logg->logMessage("%s(%s:%i): DynBuf::read failed, likely because the process exited", __FUNCTION__, __FILE__, __LINE__);
158 // This is not a fatal error - the process just doesn't exist any more
159 continue;
160 }
161
162 buffer->maps(pid, pid, b2->getBuf());
163 if (ps.numThreads <= 1) { 193 if (ps.numThreads <= 1) {
194 const char *const image = readProcExe(printb, pid, -1, b1);
195 if (image == NULL) {
196 logg->logMessage("%s(%s:%i): readImage failed", __FUNCTION__, __FILE__, __LINE__);
197 goto fail;
198 }
199
164 buffer->comm(pid, pid, image, ps.comm); 200 buffer->comm(pid, pid, image, ps.comm);
165 } else { 201 } else {
166 if (!readProcTask(buffer, pid, image, printb, b3)) { 202 if (!readProcTask(buffer, pid, printb, b1, b3)) {
167 logg->logMessage("%s(%s:%i): readProcTask failed", __FUNCTION__, __FILE__, __LINE__); 203 logg->logMessage("%s(%s:%i): readProcTask failed", __FUNCTION__, __FILE__, __LINE__);
168 goto fail; 204 goto fail;
169 } 205 }