summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--vm_dump.c45
2 files changed, 46 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index ff785b9398..c201a3597e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2765,6 +2765,7 @@ AS_CASE(["$target_os"],
])
AS_CASE(["$target_cpu-$target_os"],
[*-darwin*], [
+ AC_CHECK_HEADERS([libproc.h])
AC_CHECK_HEADERS([execinfo.h])
AS_IF([test "x$ac_cv_header_execinfo_h" = xyes], [
AC_CHECK_LIB([execinfo], [backtrace])
diff --git a/vm_dump.c b/vm_dump.c
index 47e6776d8a..8ae55aa335 100644
--- a/vm_dump.c
+++ b/vm_dump.c
@@ -16,6 +16,16 @@
#ifdef HAVE_UCONTEXT_H
#include <ucontext.h>
#endif
+#ifdef __APPLE__
+#ifdef HAVE_LIBPROC_H
+#include <libproc.h>
+#endif
+#include <mach/vm_map.h>
+#include <mach/mach_init.h>
+#ifdef __LP64__
+#define vm_region_recurse vm_region_recurse_64
+#endif
+#endif
/* see vm_insnhelper.h for the values */
#ifndef VMDEBUG
@@ -984,6 +994,41 @@ rb_vm_bugreport(const void *ctx)
fprintf(stderr, "\n");
}
#endif /* __FreeBSD__ */
+#ifdef __APPLE__
+ vm_address_t addr = 0;
+ vm_size_t size = 0;
+ struct vm_region_submap_info map;
+ mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT;
+ natural_t depth = 0;
+
+ fprintf(stderr, "* Process memory map:\n\n");
+ while (1) {
+ if (vm_region_recurse(mach_task_self(), &addr, &size, &depth,
+ (vm_region_recurse_info_t)&map, &count) != KERN_SUCCESS) {
+ break;
+ }
+
+ if (map.is_submap) {
+ // We only look at main addresses
+ depth++;
+ } else {
+ fprintf(stderr, "%lx-%lx %s%s%s", addr, (addr+size),
+ ((map.protection & VM_PROT_READ) != 0 ? "r" : "-"),
+ ((map.protection & VM_PROT_WRITE) != 0 ? "w" : "-"),
+ ((map.protection & VM_PROT_EXECUTE) != 0 ? "x" : "-"));
+#ifdef HAVE_LIBPROC_H
+ char buff[PATH_MAX];
+ if (proc_regionfilename(getpid(), addr, buff, sizeof(buff)) > 0) {
+ fprintf(stderr, " %s", buff);
+ }
+#endif
+ fprintf(stderr, "\n");
+ }
+
+ addr += size;
+ size = 0;
+ }
+#endif
}
}