[Lldb-commits] [PATCH] D62503: Add ReadCStringFromMemory for faster string reads

António Afonso via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Mon May 27 15:26:38 PDT 2019


aadsm created this revision.
aadsm added reviewers: clayborg, xiaobai.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.
aadsm added a parent revision: D62502: Implement xfer:libraries-svr4:read packet.

This is the fifth and final patch to improve module loading in a series that started here (where I explain the motivation and solution): D62499 <https://reviews.llvm.org/D62499>

Reading strings with ReadMemory is really slow when reading the path of the shared library. This is because we don't know the length of the path so use PATH_MAX (4096) and these strings are actually super close to the boundary of an unreadable page. So even though we use process_vm_readv it will usually fail because the read size spans to the unreadable page and we then default to read the string word by word with ptrace.

This new function is very similar to another ReadCStringFromMemory that already exists in lldb that makes sure it never reads cross page boundaries and checks if we already read the entire string by finding '\0'.

I was able to reduce the GetLoadedSharedLibraries call from 30ms to 4ms (or something of that order).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D62503

Files:
  lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp


Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -1499,6 +1499,44 @@
   return Status();
 }
 
+Status NativeProcessLinux::ReadCStringFromMemory(lldb::addr_t addr,
+                                                 char *buffer, size_t max_size,
+                                                 size_t &total_bytes_read) {
+  const size_t cache_line_size = 4096;
+  size_t bytes_read = 0;
+  size_t bytes_left = max_size;
+  addr_t curr_addr = addr;
+  char *curr_buffer = buffer;
+  total_bytes_read = 0;
+  Status error;
+
+  while (bytes_left > 0 && error.Success()) {
+    addr_t cache_line_bytes_left =
+        cache_line_size - (curr_addr % cache_line_size);
+    addr_t bytes_to_read = std::min<addr_t>(bytes_left, cache_line_bytes_left);
+    error = ReadMemory(curr_addr, reinterpret_cast<void *>(curr_buffer),
+                       bytes_to_read, bytes_read);
+
+    if (bytes_read == 0)
+      break;
+
+    auto str_end = std::memchr(curr_buffer, '\0', bytes_read);
+    if (str_end != NULL) {
+      total_bytes_read = (size_t)(reinterpret_cast<char *>(str_end) - buffer);
+      error.Clear();
+      break;
+    }
+
+    total_bytes_read += bytes_read;
+    curr_buffer += bytes_read;
+    curr_addr = reinterpret_cast<addr_t>(reinterpret_cast<char *>(curr_addr) +
+                                         bytes_read);
+    bytes_left -= bytes_read;
+  }
+
+  return error;
+}
+
 Status NativeProcessLinux::WriteMemory(lldb::addr_t addr, const void *buf,
                                        size_t size, size_t &bytes_written) {
   const unsigned char *src = static_cast<const unsigned char *>(buf);
@@ -2181,8 +2219,9 @@
     return error;
 
   char name_buffer[PATH_MAX];
-  error = ReadMemory(link_map.l_name, &name_buffer, sizeof(name_buffer),
-                     bytes_read);
+  error = ReadCStringFromMemory(link_map.l_name,
+                                reinterpret_cast<char *>(&name_buffer),
+                                sizeof(name_buffer), bytes_read);
   if (!error.Success())
     return error;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D62503.201591.patch
Type: text/x-patch
Size: 2249 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20190527/8d1f5996/attachment-0001.bin>


More information about the lldb-commits mailing list