aboutsummaryrefslogtreecommitdiff
path: root/src/client/mac/handler
diff options
context:
space:
mode:
authormmentovai <mmentovai@4c0a9323-5329-0410-9bdc-e9ce6186880e>2011-04-05 16:05:17 +0000
committermmentovai <mmentovai@4c0a9323-5329-0410-9bdc-e9ce6186880e>2011-04-05 16:05:17 +0000
commitfd557e4a97b328f95480309327a5d7ad4edf8363 (patch)
tree9d2b2be5faf386f316eddb0d3710797ac442262a /src/client/mac/handler
parentAnother attempt at signed / unsigned int resolution for linux minidump writer. (diff)
downloadbreakpad-fd557e4a97b328f95480309327a5d7ad4edf8363.tar.xz
Use task_info(..., TASK_DYLD_INFO, ...) on 10.6 and later in preference to
looking up the _dyld_all_image_infos symbol in /usr/lib/dyld. Review URL: http://breakpad.appspot.com/276001 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@786 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/client/mac/handler')
-rw-r--r--src/client/mac/handler/dynamic_images.cc62
1 files changed, 57 insertions, 5 deletions
diff --git a/src/client/mac/handler/dynamic_images.cc b/src/client/mac/handler/dynamic_images.cc
index 035afe7e..c6499e68 100644
--- a/src/client/mac/handler/dynamic_images.cc
+++ b/src/client/mac/handler/dynamic_images.cc
@@ -36,15 +36,37 @@ extern "C" { // needed to compile on Leopard
}
#include "breakpad_nlist_64.h"
+#include <AvailabilityMacros.h>
#include <assert.h>
+#include <CoreServices/CoreServices.h>
#include <dlfcn.h>
#include <mach/mach_vm.h>
+#include <mach/task_info.h>
#include <sys/sysctl.h>
#include <algorithm>
#include <string>
#include <vector>
+#ifndef MAC_OS_X_VERSION_10_6
+#define MAC_OS_X_VERSION_10_6 1060
+#endif
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
+
+// Fallback declarations for TASK_DYLD_INFO and friends, introduced in
+// <mach/task_info.h> in the Mac OS X 10.6 SDK.
+#define TASK_DYLD_INFO 17
+struct task_dyld_info {
+ mach_vm_address_t all_image_info_addr;
+ mach_vm_size_t all_image_info_size;
+};
+typedef struct task_dyld_info task_dyld_info_data_t;
+typedef struct task_dyld_info *task_dyld_info_t;
+#define TASK_DYLD_INFO_COUNT (sizeof(task_dyld_info_data_t) / sizeof(natural_t))
+
+#endif
+
namespace google_breakpad {
using std::string;
@@ -336,13 +358,43 @@ static uint64_t LookupSymbol(const char* symbol_name,
return list.n_value;
}
+static SInt32 GetOSVersionInternal() {
+ SInt32 os_version = 0;
+ Gestalt(gestaltSystemVersion, &os_version);
+ return os_version;
+}
+
+static SInt32 GetOSVersion() {
+ static SInt32 os_version = GetOSVersionInternal();
+ return os_version;
+}
+
+static bool IsSnowLeopardOrLater() {
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
+ return true;
+#else
+ return GetOSVersion() >= 0x1060;
+#endif
+}
+
uint64_t DynamicImages::GetDyldAllImageInfosPointer() {
- const char *imageSymbolName = "_dyld_all_image_infos";
- const char *dyldPath = "/usr/lib/dyld";
+ if (IsSnowLeopardOrLater()) {
+ task_dyld_info_data_t task_dyld_info;
+ mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
+ if (task_info(task_, TASK_DYLD_INFO, (task_info_t)&task_dyld_info,
+ &count) != KERN_SUCCESS) {
+ return NULL;
+ }
- if (Is64Bit())
- return LookupSymbol<MachO64>(imageSymbolName, dyldPath, cpu_type_);
- return LookupSymbol<MachO32>(imageSymbolName, dyldPath, cpu_type_);
+ return (uint64_t)task_dyld_info.all_image_info_addr;
+ } else {
+ const char *imageSymbolName = "_dyld_all_image_infos";
+ const char *dyldPath = "/usr/lib/dyld";
+
+ if (Is64Bit())
+ return LookupSymbol<MachO64>(imageSymbolName, dyldPath, cpu_type_);
+ return LookupSymbol<MachO32>(imageSymbolName, dyldPath, cpu_type_);
+ }
}
//==============================================================================