diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d34596b..be83ba16 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,6 +99,10 @@ if(UNIX AND NOT APPLE) endif() endif() +if(APPLE) + check_support(HAS_MACH_VM has_mach_vm.cpp "" "" "") +endif() + # =============================================== Autoconfig unwinding =============================================== # Unwind back-ends if( @@ -340,6 +344,10 @@ if(HAS_DLADDR1) target_compile_definitions(${target_name} PUBLIC CPPTRACE_HAS_DLADDR1) endif() +if(HAS_MACH_VM) + target_compile_definitions(${target_name} PUBLIC HAS_MACH_VM) +endif() + # Symbols if(CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE) if(NOT HAS_BACKTRACE) diff --git a/cmake/has_mach_vm.cpp b/cmake/has_mach_vm.cpp new file mode 100644 index 00000000..9361e676 --- /dev/null +++ b/cmake/has_mach_vm.cpp @@ -0,0 +1,23 @@ +#include +#include +#include + +int main() { + mach_vm_size_t vmsize; + uintptr_t addr = reinterpret_cast(&vmsize); + uintptr_t page_addr = addr & ~(4096 - 1); + mach_vm_address_t address = (mach_vm_address_t)page_addr; + vm_region_basic_info_data_t info; + mach_msg_type_number_t info_count = + sizeof(size_t) == 8 ? VM_REGION_BASIC_INFO_COUNT_64 : VM_REGION_BASIC_INFO_COUNT; + memory_object_name_t object; + mach_vm_region( + mach_task_self(), + &address, + &vmsize, + VM_REGION_BASIC_INFO, + (vm_region_info_t)&info, + &info_count, + &object + ); +} diff --git a/src/from_current.cpp b/src/from_current.cpp index 87a5bb24..308735f7 100644 --- a/src/from_current.cpp +++ b/src/from_current.cpp @@ -20,7 +20,9 @@ #include #if IS_APPLE #include - #include + #ifdef HAS_MACH_VM + #include + #endif #else #include #include @@ -112,13 +114,24 @@ namespace cpptrace { #if IS_APPLE int get_page_protections(void* page) { // https://stackoverflow.com/a/12627784/15675011 + #ifdef HAS_MACH_VM mach_vm_size_t vmsize; mach_vm_address_t address = (mach_vm_address_t)page; + #else + vm_size_t vmsize; + vm_address_t address = (vm_address_t)page; + #endif vm_region_basic_info_data_t info; mach_msg_type_number_t info_count = sizeof(size_t) == 8 ? VM_REGION_BASIC_INFO_COUNT_64 : VM_REGION_BASIC_INFO_COUNT; memory_object_name_t object; - kern_return_t status = mach_vm_region( + kern_return_t status = + #ifdef HAS_MACH_VM + mach_vm_region + #else + vm_region_64 + #endif + ( mach_task_self(), &address, &vmsize,