diff options
author | Bernd Weimer <bernd.weimer@pelagicore.com> | 2018-02-21 12:57:20 +0100 |
---|---|---|
committer | Robert Griebl <robert.griebl@pelagicore.com> | 2018-02-21 15:21:27 +0000 |
commit | 2e450db627bbbeb7d6631b698aedf2f806fd442c (patch) | |
tree | e485535cc8622bbb630887e5820e127dbb5624fc | |
parent | f741a32756dcb6cc740160265d76da5375e8e918 (diff) | |
download | qtapplicationmanager-2e450db627bbbeb7d6631b698aedf2f806fd442c.tar.gz |
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.cpp | 70 | ||||
-rw-r--r-- | tests/processmonitor/advanced.smaps | 252 | ||||
-rw-r--r-- | tests/processmonitor/tst_processmonitor.cpp | 17 |
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; |