[Libreoffice-commits] online.git: common/Util.hpp tools/map.cpp

Michael Meeks michael.meeks at collabora.com
Fri Dec 15 22:45:23 UTC 2017


 common/Util.hpp |   82 ++++++++++++++++++++++++-----------------
 tools/map.cpp   |  111 ++++++++++++++++++++++++++++++--------------------------
 2 files changed, 109 insertions(+), 84 deletions(-)

New commits:
commit 864b07f5b341956a660dbd37cd13d64daee416d0
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri Dec 15 18:18:23 2017 +0000

    Annotate string pointers in hex dumps to make sense of memory.
    
    Change-Id: I7934ccf379dbca9862ddb911865aaeff692261bf

diff --git a/common/Util.hpp b/common/Util.hpp
index 0fc56eb9..01b0018b 100644
--- a/common/Util.hpp
+++ b/common/Util.hpp
@@ -133,55 +133,69 @@ namespace Util
     // Extract all json entries into a map.
     std::map<std::string, std::string> JsonToMap(const std::string& jsonString);
 
+    /// Dump a lineof data as hex
+    inline std::string stringifyHexLine(
+                            const std::vector<char> &buffer,
+                            unsigned int offset,
+                            const unsigned int width = 32)
+    {
+        char scratch[64];
+        std::stringstream os;
+
+        for (unsigned int i = 0; i < width; i++)
+        {
+            if (i && (i % 8) == 0)
+                os << " ";
+            if ((offset + i) < buffer.size())
+                sprintf (scratch, "%.2x ", (unsigned char)buffer[offset+i]);
+            else
+                sprintf (scratch, "   ");
+            os << scratch;
+        }
+        os << " | ";
+
+        for (unsigned int i = 0; i < width; i++)
+        {
+            if ((offset + i) < buffer.size() && ::isprint(buffer[offset+i]))
+                sprintf (scratch, "%c", buffer[offset+i]);
+            else
+                sprintf (scratch, ".");
+            os << scratch;
+        }
+
+        return os.str();
+    }
+
     /// 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, bool skipDup = true,
                          const unsigned int width = 32)
     {
-        unsigned int i, j;
+        unsigned int j;
         char scratch[64];
+        int skip = 0;
+        std::string lastLine;
 
         os << legend;
         for (j = 0; j < buffer.size() + width - 1; j += width)
         {
-            if (skipDup)
-            {
-                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]);
+            std::string line = stringifyHexLine(buffer, j, width);
+            if (skipDup && lastLine == line)
+                skip++;
+            else {
+                if (skip > 0)
+                {
+                    os << "... dup " << skip - 1 << "...";
+                    skip = 0;
+                }
                 else
-                    sprintf (scratch, ".");
-                os << scratch;
+                    os << line;
             }
+            lastLine.swap(line);
+
             os << "\n";
         }
         os.flush();
diff --git a/tools/map.cpp b/tools/map.cpp
index 35375282..468e986e 100644
--- a/tools/map.cpp
+++ b/tools/map.cpp
@@ -12,6 +12,7 @@
 #include <vector>
 #include <iostream>
 #include <sstream>
+#include <unordered_map>
 
 #include <stdint.h>
 #include <string.h>
@@ -98,49 +99,6 @@ static int openPid(unsigned proc_id, const char *name)
     return fd;
 }
 
-static std::vector<std::string> lineBreak(std::string str)
-{
-    std::vector<std::string> lines;
-    while (str.size())
-    {
-        size_t idx = str.find('\n');
-        if (idx != std::string::npos) {
-            lines.push_back(str.substr(0,idx));
-            str = str.substr(idx+1);
-        }
-    }
-    lines.push_back(str);
-
-    return lines;
-}
-
-static void dumpDiff(const std::string &pageStr, const std::string &parentStr)
-{
-    std::vector<std::string> page = lineBreak(pageStr);
-    std::vector<std::string> parent = lineBreak(parentStr);
-    assert(page.size() == parent.size());
-    for (size_t i = 0; i < page.size(); ++i)
-    {
-        printf("%s\n", page[i].c_str());
-        if (page[i] != parent[i])
-        {
-            printf ("----");
-            assert(page[i].length() == parent[i].length());
-            for (size_t j = 4; j < page[i].length(); ++j)
-            {
-                if (page[i][j] == parent[i][j])
-                    printf(" ");
-                else {
-                    printf("%c", parent[i][j]);
-                }
-            }
-            printf("\n");
-        }
-    }
-}
-
-struct AddrSpace;
-
 struct Map {
     addr_t _start;
     addr_t _end;
@@ -160,6 +118,7 @@ struct StringData {
 struct AddrSpace {
     unsigned _proc_id;
     std::vector<Map> _maps;
+    std::unordered_map<addr_t, std::string> _addrToStr;
     StringData _strings[3];
 
     AddrSpace(unsigned proc_id) :
@@ -236,6 +195,7 @@ struct AddrSpace {
                     if (DumpStrings)
                         printf("string address 0x%.8llx %s\n",
                                map._start + i, str.c_str());
+                    _addrToStr[map._start + i] = str;
                 }
                 i += 8;
             }
@@ -264,6 +224,59 @@ struct AddrSpace {
     }
 };
 
+
+static void dumpDiff(const AddrSpace &space,
+                     const std::vector<char> &pageData,
+                     const std::vector<char> &parentData)
+{
+    assert(pageData.size() == parentData.size());
+
+    const unsigned int width = 32;
+
+    for (unsigned int i = 0; i < pageData.size(); i += width)
+    {
+        std::string page = Util::stringifyHexLine(pageData, i, width);
+        std::string parent = Util::stringifyHexLine(parentData, i, width);
+
+        // page
+        printf("0x%.4x  %s\n", i, page.c_str());
+
+        // strings
+        const addr_t *ptrs = reinterpret_cast<const addr_t *>(&pageData[i]);
+        std::stringstream annots;
+        bool haveAnnots = false;
+        for (unsigned int j = 0; j < width/8; j++)
+        {
+            std::string str;
+            auto it = space._addrToStr.find(ptrs[j]);
+            if (it != space._addrToStr.end())
+            {
+                str = it->second;
+                haveAnnots = true;
+            }
+            str.resize(24, ' ');
+            annots << str << " ";
+        }
+        if (haveAnnots)
+            printf ("annot:  %s\n", annots.str().c_str());
+
+        // parent
+        if (page != parent)
+        {
+            printf ("-par't- ");
+            assert(page.length() == parent.length());
+            for (size_t j = 0; j < page.length(); ++j)
+            {
+                if (page[j] == parent[j] && page[j] != '|')
+                    printf(" ");
+                else
+                    printf("%c", parent[j]);
+            }
+            printf("\n");
+        }
+    }
+}
+
 static void dumpPages(unsigned proc_id, unsigned parent_id, const char *type, const std::vector<addr_t> &pages, const AddrSpace &space)
 {
     int mem_fd = openPid(proc_id, "mem");
@@ -326,20 +339,18 @@ static void dumpPages(unsigned proc_id, unsigned parent_id, const char *type, co
 
         if (DumpHex)
         {
-            // Diff as ASCII
-            std::stringstream pageStr;
-            Util::dumpHex(pageStr, "", "", pageData, false);
-            std::stringstream parentStr;
-            Util::dumpHex(parentStr, "", "", parentData, false);
-
             printf ("%s page: 0x%.8llx (%d/%d) - touched: %d - %s - from %s\n",
                     type, page, (int)++cnt, (int)pages.size(), touched,
                     style, space.findName(page).c_str());
 
             if (touched == 0)
+            {
+                std::stringstream pageStr;
+                Util::dumpHex(pageStr, "", "", pageData, false);
                 printf("%s", pageStr.str().c_str());
+            }
             else
-                dumpDiff(pageStr.str(), parentStr.str());
+                dumpDiff(space, pageData, parentData);
         }
 
         bytesTouched += touched;


More information about the Libreoffice-commits mailing list