[Libreoffice-commits] online.git: 2 commits - common/Util.hpp net/Socket.cpp tools/map.cpp
Michael Meeks
michael.meeks at collabora.com
Wed Nov 29 04:11:50 UTC 2017
common/Util.hpp | 51 +++++++++++++++++++++++++
net/Socket.cpp | 44 +--------------------
tools/map.cpp | 114 +++++++++++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 154 insertions(+), 55 deletions(-)
New commits:
commit 0778b726978fffd83f6cc1e75e4f3291ef2b69a4
Author: Michael Meeks <michael.meeks at collabora.com>
Date: Wed Nov 29 03:23:45 2017 +0000
Dump hex contents of un-shared memory.
Change-Id: I47dfa8a0b48d0ba34b7462301b83e2721617814d
diff --git a/common/Util.hpp b/common/Util.hpp
index e97d1808..c2495a11 100644
--- a/common/Util.hpp
+++ b/common/Util.hpp
@@ -18,6 +18,7 @@
#include <set>
#include <sstream>
#include <string>
+#include <memory.h>
#include <Poco/File.h>
#include <Poco/Path.h>
@@ -131,6 +132,56 @@ namespace Util
// Extract all json entries into a map.
std::map<std::string, std::string> JsonToMap(const std::string& jsonString);
+ /// Dump data as hex and chars to stream
+ inline void dumpHex (std::ostream &os, const char *legend, const char *prefix,
+ const std::vector<char> &buffer, const unsigned int width = 32)
+ {
+ unsigned int i, j;
+ char scratch[64];
+
+ os << legend;
+ for (j = 0; j < buffer.size() + width - 1; j += width)
+ {
+ int skip = 0;
+ while (j >= width && j < buffer.size() - width &&
+ !memcmp(&buffer[j], &buffer[j-width], width))
+ {
+ skip++;
+ j += width;
+ }
+ if (skip > 1)
+ {
+ j -= width;
+ os << "... dup " << skip - 1 << "...\n";
+ }
+
+ sprintf (scratch, "%s0x%.4x ", prefix, j);
+ os << scratch;
+ for (i = 0; i < width; i++)
+ {
+ if (i && (i % 8) == 0)
+ os << " ";
+ if ((j + i) < buffer.size())
+ sprintf (scratch, "%.2x ", (unsigned char)buffer[j+i]);
+ else
+ sprintf (scratch, " ");
+ os << scratch;
+ }
+ os << " | ";
+
+ for (i = 0; i < width; i++)
+ {
+ if ((j + i) < buffer.size() && ::isprint(buffer[j+i]))
+ sprintf (scratch, "%c", buffer[j+i]);
+ else
+ sprintf (scratch, ".");
+ os << scratch;
+ }
+ os << "\n";
+ }
+ os.flush();
+ }
+
/// Trim spaces from the left. Just spaces.
inline std::string& ltrim(std::string& s)
{
diff --git a/net/Socket.cpp b/net/Socket.cpp
index 13424cd3..475649ac 100644
--- a/net/Socket.cpp
+++ b/net/Socket.cpp
@@ -137,50 +137,12 @@ void SocketDisposition::execute()
_socketMove = nullptr;
}
-namespace {
-
-void dump_hex (std::ostream &os, const char *legend, const char *prefix, std::vector<char> buffer)
-{
- unsigned int i, j;
- char scratch[64];
-
- os << legend;
- for (j = 0; j < buffer.size() + 15; j += 16)
- {
- sprintf (scratch, "%s0x%.4x ", prefix, j);
- os << scratch;
- for (i = 0; i < 16; i++)
- {
- if ((j + i) < buffer.size())
- sprintf (scratch, "%.2x ", (unsigned char)buffer[j+i]);
- else
- sprintf (scratch, " ");
- os << scratch;
- if (i == 8)
- os << " ";
- }
- os << " | ";
-
- for (i = 0; i < 16; i++)
- {
- if ((j + i) < buffer.size() && ::isprint(buffer[j+i]))
- sprintf (scratch, "%c", buffer[j+i]);
- else
- sprintf (scratch, ".");
- os << scratch;
- }
- os << "\n";
- }
-}
-
-} // namespace
-
void WebSocketHandler::dumpState(std::ostream& os)
{
os << (_shuttingDown ? "shutd " : "alive ")
<< std::setw(5) << 1.0*_pingTimeUs/1000 << "ms ";
if (_wsPayload.size() > 0)
- dump_hex(os, "\t\tws queued payload:\n", "\t\t", _wsPayload);
+ Util::dumpHex(os, "\t\tws queued payload:\n", "\t\t", _wsPayload);
os << "\n";
}
@@ -193,9 +155,9 @@ void StreamSocket::dumpState(std::ostream& os)
<< " r: " << _bytesRecvd << "\t w: " << _bytesSent << "\t";
_socketHandler->dumpState(os);
if (_inBuffer.size() > 0)
- dump_hex(os, "\t\tinBuffer:\n", "\t\t", _inBuffer);
+ Util::dumpHex(os, "\t\tinBuffer:\n", "\t\t", _inBuffer);
if (_outBuffer.size() > 0)
- dump_hex(os, "\t\toutBuffer:\n", "\t\t", _inBuffer);
+ Util::dumpHex(os, "\t\toutBuffer:\n", "\t\t", _inBuffer);
}
void StreamSocket::send(Poco::Net::HTTPResponse& response)
diff --git a/tools/map.cpp b/tools/map.cpp
index 09cec706..6a1aaefa 100644
--- a/tools/map.cpp
+++ b/tools/map.cpp
@@ -10,6 +10,7 @@
#include "config.h"
#include <vector>
+#include <iostream>
#include <stdint.h>
#include <string.h>
@@ -23,8 +24,12 @@
#include <dirent.h>
#include <locale.h>
+#include <Util.hpp>
+
typedef unsigned long long addr_t;
+bool DumpHex = false;
+
#define MAP_SIZE 20
#define PATH_SIZE 1000 // No harm in having it much larger than strictly necessary. Avoids compiler warning.
#define BUFFER_SIZE 9600
@@ -80,6 +85,33 @@ static int read_buffer(char *buffer, unsigned size,
return total_bytes;
}
+static void dumpPages(unsigned proc_id, const char *type, const std::vector<addr_t> &pages)
+{
+ char path_proc[PATH_SIZE];
+ snprintf(path_proc, sizeof(path_proc), "/proc/%d/mem", proc_id);
+ int mem_fd = open(path_proc, 0);
+ if (mem_fd < 0)
+ error(EXIT_FAILURE, errno, "Failed to open %s", path_proc);
+
+ size_t cnt = 0;
+ for (auto page : pages)
+ {
+ printf ("%s page: 0x%.8llx (%d/%d)\n",
+ type, page, (int)++cnt, (int)pages.size());
+
+ std::vector<char> pageData;
+ pageData.resize(0x1000);
+
+ if (lseek(mem_fd, page, SEEK_SET) < 0)
+ error(EXIT_FAILURE, errno, "Failed to seek in /proc/<pid>/mem to %lld", page);
+ if (read(mem_fd, &pageData[0], 0x1000) != 0x1000)
+ error(EXIT_FAILURE, errno, "Failed to read page %lld from /proc/<pid>/mem", page);
+ Util::dumpHex(std::cout, "", "", pageData);
+ }
+
+ close (mem_fd);
+}
+
static std::vector<char> compressBitmap(const std::vector<char> &bitmap)
{
size_t i;
@@ -117,6 +149,7 @@ static void dump_unshared(unsigned proc_id, const char *type, const std::vector<
error(EXIT_FAILURE, errno, "Failed to open %s", path_proc);
std::vector<char> bitmap;
+ std::vector<addr_t> vunshared;
addr_t numShared = 0, numOwn = 0;
for (auto p : vaddrs)
{
@@ -133,6 +166,7 @@ static void dump_unshared(unsigned proc_id, const char *type, const std::vector<
{
numOwn++;
bitmap.push_back('*');
+ vunshared.push_back(p);
}
else
{
@@ -141,6 +175,7 @@ static void dump_unshared(unsigned proc_id, const char *type, const std::vector<
}
}
}
+ close (fd);
printf ("Totals for %s\n", type);
printf ("\tshared %5lld (%lldkB)\n", numShared, numShared * 4);
@@ -148,6 +183,12 @@ static void dump_unshared(unsigned proc_id, const char *type, const std::vector<
std::vector<char> compressed = compressBitmap(bitmap);
printf ("RLE sharing bitmap:\n%s\n\n", &compressed[0]);
+
+ if (DumpHex)
+ {
+ printf ("Un-shared data dump\n");
+ dumpPages(proc_id, type, vunshared);
+ }
}
static void total_smaps(unsigned proc_id, const char *file, const char *cmdline)
@@ -246,19 +287,35 @@ int main(int argc, char **argv)
char path_proc[PATH_SIZE];
char cmdline[BUFFER_SIZE];
+
+ bool help = false;
unsigned forPid = 0;
+ const char *appOrPid = nullptr;
setlocale (LC_ALL, "");
getopt(argc, argv, "");
- if (argc < 1 || strstr(argv[1], "--help"))
+ for (int i = 1; i < argc; ++i)
+ {
+ const char *arg = argv[i];
+ if (strstr(arg, "--help"))
+ help = true;
+ else if (strstr(arg, "--hex"))
+ DumpHex = true;
+ else
+ appOrPid = arg;
+ }
+ if (appOrPid == NULL && forPid == 0)
+ help = true;
+
+ if (help)
{
- fprintf(stderr, "Usage: loolmap <name of process|pid>\n");
+ fprintf(stderr, "Usage: loolmap --hex <name of process|pid>\n");
fprintf(stderr, "Dump memory map information for a given process\n");
return 0;
}
- forPid = atoi(argv[1]);
+ forPid = atoi(appOrPid);
root_proc = opendir("/proc");
if (!root_proc)
@@ -274,7 +331,7 @@ int main(int argc, char **argv)
unsigned pid_proc = strtoul(dir_proc->d_name, nullptr, 10);
snprintf(path_proc, sizeof(path_proc), "/proc/%s/%s", dir_proc->d_name, "cmdline");
if (read_buffer(cmdline, sizeof(cmdline), path_proc, ' ') &&
- (forPid == pid_proc || (forPid == 0 && strstr(cmdline, argv[1]) && !strstr(cmdline, argv[0]))))
+ (forPid == pid_proc || (forPid == 0 && strstr(cmdline, appOrPid) && !strstr(cmdline, argv[0]))))
{
snprintf(path_proc, sizeof(path_proc), "/proc/%s/%s", dir_proc->d_name, "smaps");
total_smaps(pid_proc, path_proc, cmdline);
commit 16898cbffc5d8ae4da88a7be0c5d30f7869ce2e8
Author: Michael Meeks <michael.meeks at collabora.com>
Date: Wed Nov 29 02:38:33 2017 +0000
RLE compress sharing bitmap for display.
Change-Id: Ib47e2ceb481c0a9b4c36fc6f5304bf03acec128b
diff --git a/tools/map.cpp b/tools/map.cpp
index f3fb76b5..09cec706 100644
--- a/tools/map.cpp
+++ b/tools/map.cpp
@@ -80,8 +80,35 @@ static int read_buffer(char *buffer, unsigned size,
return total_bytes;
}
+static std::vector<char> compressBitmap(const std::vector<char> &bitmap)
+{
+ size_t i;
+ std::vector<char> output;
+ for (i = 0; i < bitmap.size(); ++i)
+ {
+ char cur;
+ int cnt = 0;
+ size_t j = i;
+ for (cur = bitmap[j]; bitmap[j] == cur; ++j)
+ ++cnt;
+ output.push_back(cur);
+ if (cnt > 3)
+ {
+ char num[16];
+ output.push_back('[');
+ sprintf(num, "%d", cnt);
+ for (int cpy = 0; num[cpy] != '\0'; ++cpy)
+ output.push_back(num[cpy]);
+ output.push_back(']');
+ i += cnt - 1;
+ }
+ }
-static void dump_unshared(unsigned proc_id, const std::vector<addr_t> &vaddrs)
+ output.push_back('\0');
+ return output;
+}
+
+static void dump_unshared(unsigned proc_id, const char *type, const std::vector<addr_t> &vaddrs)
{
char path_proc[PATH_SIZE];
snprintf(path_proc, sizeof(path_proc), "/proc/%d/pagemap", proc_id);
@@ -89,7 +116,7 @@ static void dump_unshared(unsigned proc_id, const std::vector<addr_t> &vaddrs)
if (fd < 0)
error(EXIT_FAILURE, errno, "Failed to open %s", path_proc);
- printf("Sharing map:\n");
+ std::vector<char> bitmap;
addr_t numShared = 0, numOwn = 0;
for (auto p : vaddrs)
{
@@ -105,20 +132,22 @@ static void dump_unshared(unsigned proc_id, const std::vector<addr_t> &vaddrs)
if (vaddrData & ((addr_t)1 << 56))
{
numOwn++;
- printf("*");
+ bitmap.push_back('*');
}
else
{
numShared++;
- printf(".");
+ bitmap.push_back('.');
}
}
- if (!((numShared + numOwn) % 128))
- printf("\n");
}
- printf ("\nTotals:\n");
+
+ printf ("Totals for %s\n", type);
printf ("\tshared %5lld (%lldkB)\n", numShared, numShared * 4);
printf ("\tunshared %5lld (%lldkB)\n", numOwn, numOwn * 4);
+
+ std::vector<char> compressed = compressBitmap(bitmap);
+ printf ("RLE sharing bitmap:\n%s\n\n", &compressed[0]);
}
static void total_smaps(unsigned proc_id, const char *file, const char *cmdline)
@@ -205,9 +234,9 @@ static void total_smaps(unsigned proc_id, const char *file, const char *cmdline)
printf("Anon page cnt :%20lld\n", (addr_t)anonVAddrs.size());
printf("File page cnt :%20lld\n", (addr_t)fileVAddrs.size());
printf("\n");
- dump_unshared(proc_id, heapVAddrs);
- dump_unshared(proc_id, anonVAddrs);
- dump_unshared(proc_id, fileVAddrs);
+ dump_unshared(proc_id, "heap", heapVAddrs);
+ dump_unshared(proc_id, "anon", anonVAddrs);
+ dump_unshared(proc_id, "file", fileVAddrs);
}
int main(int argc, char **argv)
More information about the Libreoffice-commits
mailing list