IsBadReadPtr 在 macOS 下的实现
#ifdef _WIN32 bool __isBadReadPtr(const void *p, int count) { return !!::IsBadReadPtr(p, count); } #elif __APPLE__ // From:http://compgroups.net/comp.mac.codewarrior/porting-to-macosx-questions/2934235 #include <stdio.h> #include <sys/cdefs.h> #include <mach/mach_vm.h> #include <mach/mach_port.h> bool __isBadReadPtr(const void *ptr, int size) { int nullfd = open("/dev/random", O_WRONLY); if (write(nullfd, ptr, size) < 0) { return true; } close(nullfd); return false; /* mach_vm_size_t vmsize; mach_port_t objectName = MACH_PORT_NULL; mach_vm_address_t address = (vm_address_t) ptr; mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT; struct vm_region_basic_info info; kern_return_t result = mach_vm_region(mach_task_self(), &address, &vmsize, VM_REGION_BASIC_INFO, (vm_region_info_t) &info, &count, &objectName); if (objectName != MACH_PORT_NULL) { mach_port_deallocate(mach_task_self(), objectName); } if (result != KERN_SUCCESS || address > (vm_address_t) ptr || info.protection == VM_PROT_NONE) { return false; } return true; */ } #else // For reference:http://fixunix.com/linux/337646-isbadreadptr-linux.html // 需要在mac上测试 #include <setjmp.h> #include <signal.h> static jmp_buf g_jmpbuf; static QMutex g_Mutex; void sigsegv(int sign) { longjmp(g_jmpbuf, 1); } #pragma optimize( "", off ) bool __isBadReadPtr(const void *p, int count) { int v; g_Mutex.lock(); signal(SIGSEGV, sigsegv); v = setjmp(g_jmpbuf); if (v == 0) { volatile int sum = 0; for (int i = 0; i < count; i++) sum += ((char*)p)[i]; } signal(SIGSEGV, SIG_DFL); g_Mutex.unlock(); return v==0; } #pragma optimize( "", on ) #endif