[Lldb-commits] [lldb] [lldb][Darwin] Fetch detailed binary info in chunks (PR #190720)

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Thu Apr 9 18:16:25 PDT 2026


================
@@ -203,22 +199,53 @@ void DynamicLoaderMacOS::DoInitialImageFetch() {
   UnloadAllImages();
 
   StructuredData::ObjectSP all_image_info_json_sp(
-      m_process->GetLoadedDynamicLibrariesInfos());
+      m_process->GetLoadedDynamicLibrariesInfos(
+          /*include_mh_and_load_commands=*/false));
   ImageInfo::collection image_infos;
   if (all_image_info_json_sp.get() &&
       all_image_info_json_sp->GetAsDictionary() &&
       all_image_info_json_sp->GetAsDictionary()->HasKey("images") &&
       all_image_info_json_sp->GetAsDictionary()
           ->GetValueForKey("images")
           ->GetAsArray()) {
-    if (JSONImageInformationIntoImageInfo(all_image_info_json_sp,
-                                          image_infos)) {
-      LLDB_LOGF(log, "Initial module fetch:  Adding %" PRId64 " modules.\n",
-                (uint64_t)image_infos.size());
-
-      auto images = PreloadModulesFromImageInfos(image_infos);
-      UpdateSpecialBinariesFromPreloadedModules(images);
-      AddModulesUsingPreloadedModules(images);
+
+    // Older debugserver (pre-2024-ish) will not recognize the
+    // include_mh_and_load_commands==false option above, and
+    // will return the full binary information including mach
+    // header and segments/load commands.  The response includes
+    // the full information on all binaries.
+    StructuredData::Array *images = all_image_info_json_sp->GetAsDictionary()
+                                        ->GetValueForKey("images")
+                                        ->GetAsArray();
+    if (images->GetSize() > 0 &&
+        images->GetItemAtIndex(0)->GetAsDictionary()->HasKey("mach_header")) {
+      if (JSONImageInformationIntoImageInfo(all_image_info_json_sp,
+                                            image_infos)) {
+        LLDB_LOGF(log, "Initial module fetch:  Adding %" PRId64 " modules.\n",
+                  (uint64_t)image_infos.size());
+
+        auto images = PreloadModulesFromImageInfos(image_infos);
+        UpdateSpecialBinariesFromPreloadedModules(images);
+        AddModulesUsingPreloadedModules(images);
+      }
+    } else {
+      // This is a newer debugserver which only replied with
+      // `load_address` for all binaries loaded in the process.
+      // We can request detailed information in smaller chunks,
+      // instead of one gigantic packet.
+      size_t image_count = images->GetSize();
+      std::vector<addr_t> load_addresses;
+      for (size_t i = 0; i < image_count; i++) {
+        StructuredData::Dictionary *image =
+            images->GetItemAtIndex(i)->GetAsDictionary();
+        if (image->HasKey("load_address")) {
----------------
jasonmolenda wrote:

Ah, sorry it wasn't clear.  We've requested all binaries with a new "include mach header & load commands==false" option.  An old debugserver that doesn't understand this will still reply with all the mach headers and load commands in the reply.  In the above `if` expression, we check if the first entry has a `mach_header` key, and if so, we're dealing with an old debugserver that ignored our request to skip that.  We process its returned JSON in its entirety.

A new debugserver (this is the `else` block here) returns an array of dictionaries, one per image, with only _one_ field -- `load_address` -- in them.  I am being paranoid in checking that the `load_address` key is present, before I dereference it, that's all this bit is doing.  An image dictionary without `load_address` would be malformed input.

https://github.com/llvm/llvm-project/pull/190720


More information about the lldb-commits mailing list