summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBernd Weimer <bernd.weimer@pelagicore.com>2018-02-21 12:57:20 +0100
committerRobert Griebl <robert.griebl@pelagicore.com>2018-02-21 15:21:27 +0000
commit2e450db627bbbeb7d6631b698aedf2f806fd442c (patch)
treee485535cc8622bbb630887e5820e127dbb5624fc
parentf741a32756dcb6cc740160265d76da5375e8e918 (diff)
Fix smaps parsing
We cannot rely on a fixed position of Size, Rss and Pss tags in smaps files. Task-number: QTAUTO-785 Change-Id: I12da5b5d21da0846ad57252b176fa204db18704f Reviewed-by: Robert Griebl <robert.griebl@pelagicore.com>
-rw-r--r--src/monitor-lib/processmonitor_p.cpp70
-rw-r--r--tests/processmonitor/advanced.smaps252
-rw-r--r--tests/processmonitor/tst_processmonitor.cpp17
3 files changed, 318 insertions, 21 deletions
diff --git a/src/monitor-lib/processmonitor_p.cpp b/src/monitor-lib/processmonitor_p.cpp
index 90a167d2..3ce11809 100644
--- a/src/monitor-lib/processmonitor_p.cpp
+++ b/src/monitor-lib/processmonitor_p.cpp
@@ -183,6 +183,13 @@ qreal ReadingTask::readLoad()
return load;
}
+static int parseValue(const char *pl)
+{
+ while (*pl && (*pl < '0' || *pl > '9'))
+ pl++;
+ return strtol(pl, 0, 10);
+}
+
bool ReadingTask::readMemory(const QByteArray &smapsFile, ReadingTask::Results::Memory &results)
{
struct ScopedFile {
@@ -227,11 +234,9 @@ bool ReadingTask::readMemory(const QByteArray &smapsFile, ReadingTask::Results::
ok = true;
++blockLen;
}
- if (!ok || blockLen < 12 || blockLen > 24)
+ if (!ok || blockLen < 12 || blockLen > 32)
return false;
- blockLen -= 3; // skip those number of lines below
-
fseek(sf.file, 0, SEEK_SET);
bool wasPrivateOnly = false;
ok = false;
@@ -273,26 +278,49 @@ bool ReadingTask::readMemory(const QByteArray &smapsFile, ReadingTask::Results::
break;
}
- if (Q_UNLIKELY(!fgets(line, lineLen, sf.file)))
- break;
- pl = line;
- while (*pl && (*pl < '0' || *pl > '9'))
- pl++;
- int vm = strtol(pl, 0, 10);
+ int skipLen = blockLen;
+ int vm = 0;
+ int rss = 0;
+ int pss = 0;
+ const int sizeTag = 0x01;
+ const int rssTag = 0x02;
+ const int pssTag = 0x04;
+ const int allTags = sizeTag | rssTag | pssTag;
+ int foundTags = 0;
+
+ while (foundTags < allTags && skipLen > 0) {
+ skipLen--;
+ if (Q_UNLIKELY(!fgets(line, lineLen, sf.file)))
+ break;
+ pl = line;
- if (Q_UNLIKELY(!fgets(line, lineLen, sf.file)))
- break;
- pl = line;
- while (*pl && (*pl < '0' || *pl > '9'))
- pl++;
- int rss = strtol(pl, 0, 10);
+ static const char strSize[] = "ize:";
+ static const char strXss[] = "ss:";
- if (Q_UNLIKELY(!fgets(line, lineLen, sf.file)))
+ switch (*pl) {
+ case 'S':
+ if (!qstrncmp(pl + 1, strSize, sizeof(strSize) - 1)) {
+ foundTags |= sizeTag;
+ vm = parseValue(pl + sizeof(strSize));
+ }
+ break;
+ case 'R':
+ if (!qstrncmp(pl + 1, strXss, sizeof(strXss) - 1)) {
+ foundTags |= rssTag;
+ rss = parseValue(pl + sizeof(strXss));
+ }
+ break;
+ case 'P':
+ if (!qstrncmp(pl + 1, strXss, sizeof(strXss) - 1)) {
+ foundTags |= pssTag;
+ pss = parseValue(pl + sizeof(strXss));
+ }
+ break;
+ }
+ }
+
+ if (foundTags < allTags)
break;
- pl = line;
- while (*pl && (*pl < '0' || *pl > '9'))
- pl++;
- int pss = strtol(pl, 0, 10);
results.totalVm += vm;
results.totalRss += rss;
@@ -315,7 +343,7 @@ bool ReadingTask::readMemory(const QByteArray &smapsFile, ReadingTask::Results::
static const char permP[] = { '-', '-', '-', 'p' };
wasPrivateOnly = !memcmp(permissions, permP, sizeof(permissions));
- for (int skip = blockLen; skip; --skip) {
+ for (int skip = skipLen; skip; --skip) {
if (Q_UNLIKELY(!fgets(line, lineLen, sf.file)))
break;
}
diff --git a/tests/processmonitor/advanced.smaps b/tests/processmonitor/advanced.smaps
new file mode 100644
index 00000000..61212565
--- /dev/null
+++ b/tests/processmonitor/advanced.smaps
@@ -0,0 +1,252 @@
+55e362f85000-55e36315a000 r-xp 00000000 08:05 20988510 /qtbase/bin/appman
+Size: 1876 kB
+KernelPageSize: 4 kB
+MMUPageSize: 4 kB
+Rss: 1704 kB
+Pss: 1704 kB
+Shared_Clean: 0 kB
+Shared_Dirty: 0 kB
+Private_Clean: 1704 kB
+Private_Dirty: 0 kB
+Referenced: 1704 kB
+Anonymous: 0 kB
+LazyFree: 0 kB
+AnonHugePages: 0 kB
+ShmemPmdMapped: 0 kB
+Shared_Hugetlb: 0 kB
+Private_Hugetlb: 0 kB
+Swap: 0 kB
+SwapPss: 0 kB
+Locked: 1704 kB
+VmFlags: rd ex mr mw me dw ?? sd
+55e36315b000-55e363162000 r--p 001d5000 08:05 20988510 /qtbase/bin/appman
+Size: 28 kB
+KernelPageSize: 4 kB
+MMUPageSize: 4 kB
+Rss: 28 kB
+Pss: 28 kB
+Shared_Clean: 0 kB
+Shared_Dirty: 0 kB
+Private_Clean: 0 kB
+Private_Dirty: 28 kB
+Referenced: 28 kB
+Anonymous: 28 kB
+LazyFree: 0 kB
+AnonHugePages: 0 kB
+ShmemPmdMapped: 0 kB
+Shared_Hugetlb: 0 kB
+Private_Hugetlb: 0 kB
+Swap: 0 kB
+SwapPss: 0 kB
+Locked: 28 kB
+VmFlags: rd mr mw me dw ac ?? sd
+55e363162000-55e363164000 rw-p 001dc000 08:05 20988510 /qtbase/bin/appman
+Size: 8 kB
+KernelPageSize: 4 kB
+MMUPageSize: 4 kB
+Rss: 8 kB
+Pss: 8 kB
+Shared_Clean: 0 kB
+Shared_Dirty: 0 kB
+Private_Clean: 0 kB
+Private_Dirty: 8 kB
+Referenced: 8 kB
+Anonymous: 8 kB
+LazyFree: 0 kB
+AnonHugePages: 0 kB
+ShmemPmdMapped: 0 kB
+Shared_Hugetlb: 0 kB
+Private_Hugetlb: 0 kB
+Swap: 0 kB
+SwapPss: 0 kB
+Locked: 8 kB
+VmFlags: rd wr mr mw me dw ac ?? sd
+55e363164000-55e363166000 rw-p 00000000 00:00 0
+Size: 8 kB
+KernelPageSize: 4 kB
+MMUPageSize: 4 kB
+Rss: 4 kB
+Pss: 4 kB
+Shared_Clean: 0 kB
+Shared_Dirty: 0 kB
+Private_Clean: 0 kB
+Private_Dirty: 4 kB
+Referenced: 4 kB
+Anonymous: 4 kB
+LazyFree: 0 kB
+AnonHugePages: 0 kB
+ShmemPmdMapped: 0 kB
+Shared_Hugetlb: 0 kB
+Private_Hugetlb: 0 kB
+Swap: 0 kB
+SwapPss: 0 kB
+Locked: 4 kB
+VmFlags: rd wr mr mw me ac sd
+55e3645eb000-55e364c57000 rw-p 00000000 00:00 0 [heap]
+Size: 6576 kB
+KernelPageSize: 4 kB
+MMUPageSize: 4 kB
+Rss: 6288 kB
+Pss: 6288 kB
+Shared_Clean: 0 kB
+Shared_Dirty: 0 kB
+Private_Clean: 0 kB
+Private_Dirty: 6288 kB
+Referenced: 6288 kB
+Anonymous: 6288 kB
+LazyFree: 0 kB
+AnonHugePages: 0 kB
+ShmemPmdMapped: 0 kB
+Shared_Hugetlb: 0 kB
+Private_Hugetlb: 0 kB
+Swap: 0 kB
+SwapPss: 0 kB
+Locked: 6288 kB
+VmFlags: rd wr mr mw me ac sd
+7f85d0000000-7f85d093a000 rw-p 00000000 00:00 0
+Size: 9448 kB
+KernelPageSize: 4 kB
+MMUPageSize: 4 kB
+Rss: 9448 kB
+Pss: 9448 kB
+Shared_Clean: 0 kB
+Shared_Dirty: 0 kB
+Private_Clean: 0 kB
+Private_Dirty: 9448 kB
+Referenced: 9448 kB
+Anonymous: 9448 kB
+LazyFree: 0 kB
+AnonHugePages: 0 kB
+ShmemPmdMapped: 0 kB
+Shared_Hugetlb: 0 kB
+Private_Hugetlb: 0 kB
+Swap: 0 kB
+SwapPss: 0 kB
+Locked: 9448 kB
+VmFlags: rd wr mr mw me nr sd
+7f85d093a000-7f85d4000000 ---p 00000000 00:00 0
+Size: 56088 kB
+KernelPageSize: 4 kB
+MMUPageSize: 4 kB
+Rss: 0 kB
+Pss: 0 kB
+Shared_Clean: 0 kB
+Shared_Dirty: 0 kB
+Private_Clean: 0 kB
+Private_Dirty: 0 kB
+Referenced: 0 kB
+Anonymous: 0 kB
+LazyFree: 0 kB
+AnonHugePages: 0 kB
+ShmemPmdMapped: 0 kB
+Shared_Hugetlb: 0 kB
+Private_Hugetlb: 0 kB
+Swap: 0 kB
+SwapPss: 0 kB
+Locked: 0 kB
+VmFlags: mr mw me nr sd
+7f85d5fef000-7f85d632d000 rw-s 00000000 00:2e 19336830 /run/user/1000/wayland-cursor-shared-jzyii9 (deleted)
+Size: 3320 kB
+KernelPageSize: 4 kB
+MMUPageSize: 4 kB
+Rss: 0 kB
+Pss: 0 kB
+Shared_Clean: 0 kB
+Shared_Dirty: 0 kB
+Private_Clean: 0 kB
+Private_Dirty: 0 kB
+Referenced: 0 kB
+Anonymous: 0 kB
+LazyFree: 0 kB
+AnonHugePages: 0 kB
+ShmemPmdMapped: 0 kB
+Shared_Hugetlb: 0 kB
+Private_Hugetlb: 0 kB
+Swap: 0 kB
+SwapPss: 0 kB
+Locked: 0 kB
+VmFlags: rd wr sh mr mw me ms sd
+7f85d63c5000-7f85d63fc000 r-xp 00000000 08:01 4984507 /lib/x86_64-linux-gnu/libnss_systemd.so.2
+Size: 220 kB
+KernelPageSize: 4 kB
+MMUPageSize: 4 kB
+Rss: 64 kB
+Pss: 3 kB
+Shared_Clean: 64 kB
+Shared_Dirty: 0 kB
+Private_Clean: 0 kB
+Private_Dirty: 0 kB
+Referenced: 64 kB
+Anonymous: 0 kB
+LazyFree: 0 kB
+AnonHugePages: 0 kB
+ShmemPmdMapped: 0 kB
+Shared_Hugetlb: 0 kB
+Private_Hugetlb: 0 kB
+Swap: 0 kB
+SwapPss: 0 kB
+Locked: 3 kB
+VmFlags: rd ex mr mw me sd
+7ffd75741000-7ffd75763000 rw-p 00000000 00:00 0 [stack]
+Size: 136 kB
+KernelPageSize: 4 kB
+MMUPageSize: 4 kB
+Rss: 64 kB
+Pss: 64 kB
+Shared_Clean: 0 kB
+Shared_Dirty: 0 kB
+Private_Clean: 0 kB
+Private_Dirty: 64 kB
+Referenced: 64 kB
+Anonymous: 64 kB
+LazyFree: 0 kB
+AnonHugePages: 0 kB
+ShmemPmdMapped: 0 kB
+Shared_Hugetlb: 0 kB
+Private_Hugetlb: 0 kB
+Swap: 0 kB
+SwapPss: 0 kB
+Locked: 64 kB
+VmFlags: rd wr mr mw me gd ac
+7ffd757e9000-7ffd757ec000 r--p 00000000 00:00 0 [vvar]
+Size: 12 kB
+KernelPageSize: 4 kB
+MMUPageSize: 4 kB
+Rss: 0 kB
+Pss: 0 kB
+Shared_Clean: 0 kB
+Shared_Dirty: 0 kB
+Private_Clean: 0 kB
+Private_Dirty: 0 kB
+Referenced: 0 kB
+Anonymous: 0 kB
+LazyFree: 0 kB
+AnonHugePages: 0 kB
+ShmemPmdMapped: 0 kB
+Shared_Hugetlb: 0 kB
+Private_Hugetlb: 0 kB
+Swap: 0 kB
+SwapPss: 0 kB
+Locked: 0 kB
+VmFlags: rd mr pf io de dd sd
+7ffd757ec000-7ffd757ee000 r-xp 00000000 00:00 0 [vdso]
+Size: 8 kB
+KernelPageSize: 4 kB
+MMUPageSize: 4 kB
+Rss: 4 kB
+Pss: 0 kB
+Shared_Clean: 4 kB
+Shared_Dirty: 0 kB
+Private_Clean: 0 kB
+Private_Dirty: 0 kB
+Referenced: 4 kB
+Anonymous: 0 kB
+LazyFree: 0 kB
+AnonHugePages: 0 kB
+ShmemPmdMapped: 0 kB
+Shared_Hugetlb: 0 kB
+Private_Hugetlb: 0 kB
+Swap: 0 kB
+SwapPss: 0 kB
+Locked: 0 kB
+VmFlags: rd ex mr mw me de sd
diff --git a/tests/processmonitor/tst_processmonitor.cpp b/tests/processmonitor/tst_processmonitor.cpp
index bd053651..d68c8e74 100644
--- a/tests/processmonitor/tst_processmonitor.cpp
+++ b/tests/processmonitor/tst_processmonitor.cpp
@@ -50,6 +50,7 @@ private slots:
void memInvalid();
void memTestProcess();
void memBasic();
+ void memAdvanced();
private:
void printMem(const ReadingTask::Results::Memory &memres);
@@ -118,6 +119,22 @@ void tst_ProcessMonitor::memBasic()
QCOMPARE(memres.heapPss, 7556u);
}
+void tst_ProcessMonitor::memAdvanced()
+{
+ ReadingTask::Results::Memory memres;
+ QVERIFY(static_cast<ReadingTaskTester*>(&task)->readMemory(QFINDTESTDATA("advanced.smaps").toLocal8Bit(), memres));
+ //printMem(memres);
+ QCOMPARE(memres.totalVm, 77728u);
+ QCOMPARE(memres.totalRss, 17612u);
+ QCOMPARE(memres.totalPss, 17547u);
+ QCOMPARE(memres.textVm, 2104u);
+ QCOMPARE(memres.textRss, 1772u);
+ QCOMPARE(memres.textPss, 1707u);
+ QCOMPARE(memres.heapVm, 16032u);
+ QCOMPARE(memres.heapRss, 15740u);
+ QCOMPARE(memres.heapPss, 15740u);
+}
+
void tst_ProcessMonitor::printMem(const ReadingTask::Results::Memory &memres)
{
qDebug() << "totalVm:" << memres.totalVm;