JDevlieghere created this revision.
JDevlieghere added a reviewer: aprantl.
Herald added a project: All.
JDevlieghere requested review of this revision.

Make LLDB resilient against failing dyld introspection APIs: 
`dyld_process_create_for_current_task`, 
`dyld_process_snapshot_create_for_process` and 
`dyld_process_snapshot_get_shared_cache` can all fail and return a nullptr. 
Instead of having an assert, which doesn't really make sense as we have no 
control over whether these calls succeed or not, bail out gracefully and use 
the fallback logic.

rdar://98070414


https://reviews.llvm.org/D131110

Files:
  lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm


Index: lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
===================================================================
--- lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -16,6 +16,7 @@
 #include "lldb/Utility/Timer.h"
 #include "Utility/UuidCompatibility.h"
 
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/Support/FileSystem.h"
@@ -529,34 +530,39 @@
 #if defined(SDK_HAS_NEW_DYLD_INTROSPECTION_SPIS)
   if (__builtin_available(macOS 12, *)) {
     if (dyld_process_create_for_current_task) {
-      auto dyld_process = dyld_process_create_for_current_task();
-      auto snapshot =
-          dyld_process_snapshot_create_for_process(dyld_process, nullptr);
-      auto shared_cache = dyld_process_snapshot_get_shared_cache(snapshot);
-      assert(dyld_process && snapshot && shared_cache);
-
-      dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) {
-        __block uint64_t minVmAddr = UINT64_MAX;
-        __block uint64_t maxVmAddr = 0;
-        uuid_t uuidStore;
-        __block uuid_t *uuid = &uuidStore;
-
-        dyld_image_for_each_segment_info(image, ^(const char *segmentName,
-                                                  uint64_t vmAddr,
-                                                  uint64_t vmSize, int perm) {
-          minVmAddr = std::min(minVmAddr, vmAddr);
-          maxVmAddr = std::max(maxVmAddr, vmAddr + vmSize);
-          dyld_image_copy_uuid(image, uuid);
-        });
-        assert(minVmAddr != UINT_MAX);
-        assert(maxVmAddr != 0);
-        m_images[dyld_image_get_installname(image)] = SharedCacheImageInfo{
-            UUID::fromData(uuid, 16),
-            std::make_shared<DataBufferUnowned>((uint8_t *)minVmAddr,
-                                                maxVmAddr - minVmAddr)};
-      });
-      dyld_process_snapshot_dispose(snapshot);
-      return;
+      if (auto dyld_process = dyld_process_create_for_current_task()) {
+        if (auto snapshot = dyld_process_snapshot_create_for_process(
+                dyld_process, nullptr)) {
+          auto on_exit = llvm::make_scope_exit(
+              [&]() { dyld_process_snapshot_dispose(snapshot); });
+          if (auto shared_cache =
+                  dyld_process_snapshot_get_shared_cache(snapshot)) {
+            dyld_shared_cache_for_each_image(
+                shared_cache, ^(dyld_image_t image) {
+                  __block uint64_t minVmAddr = UINT64_MAX;
+                  __block uint64_t maxVmAddr = 0;
+                  uuid_t uuidStore;
+                  __block uuid_t *uuid = &uuidStore;
+
+                  dyld_image_for_each_segment_info(
+                      image, ^(const char *segmentName, uint64_t vmAddr,
+                               uint64_t vmSize, int perm) {
+                        minVmAddr = std::min(minVmAddr, vmAddr);
+                        maxVmAddr = std::max(maxVmAddr, vmAddr + vmSize);
+                        dyld_image_copy_uuid(image, uuid);
+                      });
+                  assert(minVmAddr != UINT_MAX);
+                  assert(maxVmAddr != 0);
+                  m_images[dyld_image_get_installname(image)] =
+                      SharedCacheImageInfo{
+                          UUID::fromData(uuid, 16),
+                          std::make_shared<DataBufferUnowned>(
+                              (uint8_t *)minVmAddr, maxVmAddr - minVmAddr)};
+                });
+            return;
+          }
+        }
+      }
     }
   }
 #endif


Index: lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
===================================================================
--- lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -16,6 +16,7 @@
 #include "lldb/Utility/Timer.h"
 #include "Utility/UuidCompatibility.h"
 
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/Support/FileSystem.h"
@@ -529,34 +530,39 @@
 #if defined(SDK_HAS_NEW_DYLD_INTROSPECTION_SPIS)
   if (__builtin_available(macOS 12, *)) {
     if (dyld_process_create_for_current_task) {
-      auto dyld_process = dyld_process_create_for_current_task();
-      auto snapshot =
-          dyld_process_snapshot_create_for_process(dyld_process, nullptr);
-      auto shared_cache = dyld_process_snapshot_get_shared_cache(snapshot);
-      assert(dyld_process && snapshot && shared_cache);
-
-      dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) {
-        __block uint64_t minVmAddr = UINT64_MAX;
-        __block uint64_t maxVmAddr = 0;
-        uuid_t uuidStore;
-        __block uuid_t *uuid = &uuidStore;
-
-        dyld_image_for_each_segment_info(image, ^(const char *segmentName,
-                                                  uint64_t vmAddr,
-                                                  uint64_t vmSize, int perm) {
-          minVmAddr = std::min(minVmAddr, vmAddr);
-          maxVmAddr = std::max(maxVmAddr, vmAddr + vmSize);
-          dyld_image_copy_uuid(image, uuid);
-        });
-        assert(minVmAddr != UINT_MAX);
-        assert(maxVmAddr != 0);
-        m_images[dyld_image_get_installname(image)] = SharedCacheImageInfo{
-            UUID::fromData(uuid, 16),
-            std::make_shared<DataBufferUnowned>((uint8_t *)minVmAddr,
-                                                maxVmAddr - minVmAddr)};
-      });
-      dyld_process_snapshot_dispose(snapshot);
-      return;
+      if (auto dyld_process = dyld_process_create_for_current_task()) {
+        if (auto snapshot = dyld_process_snapshot_create_for_process(
+                dyld_process, nullptr)) {
+          auto on_exit = llvm::make_scope_exit(
+              [&]() { dyld_process_snapshot_dispose(snapshot); });
+          if (auto shared_cache =
+                  dyld_process_snapshot_get_shared_cache(snapshot)) {
+            dyld_shared_cache_for_each_image(
+                shared_cache, ^(dyld_image_t image) {
+                  __block uint64_t minVmAddr = UINT64_MAX;
+                  __block uint64_t maxVmAddr = 0;
+                  uuid_t uuidStore;
+                  __block uuid_t *uuid = &uuidStore;
+
+                  dyld_image_for_each_segment_info(
+                      image, ^(const char *segmentName, uint64_t vmAddr,
+                               uint64_t vmSize, int perm) {
+                        minVmAddr = std::min(minVmAddr, vmAddr);
+                        maxVmAddr = std::max(maxVmAddr, vmAddr + vmSize);
+                        dyld_image_copy_uuid(image, uuid);
+                      });
+                  assert(minVmAddr != UINT_MAX);
+                  assert(maxVmAddr != 0);
+                  m_images[dyld_image_get_installname(image)] =
+                      SharedCacheImageInfo{
+                          UUID::fromData(uuid, 16),
+                          std::make_shared<DataBufferUnowned>(
+                              (uint8_t *)minVmAddr, maxVmAddr - minVmAddr)};
+                });
+            return;
+          }
+        }
+      }
     }
   }
 #endif
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to