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

 

发表回复