在linux系统下使用内存技术,检测堆越界错误
越界监测技术1
一般使用c或cpp编程时,堆栈越界访问(read/write)往往会引起很多意想不到的错误,比如延后的进程崩溃等。因此,如果有一种方法,可以让越界访问立即触发系统错误(让进程抛出异常而终止,再生成coredump文件),就可以立即检测出内存越界行为,并将对这种隐藏的错误,及时作出反应,以免在生产环境下造成更大的损失。
我们知道,在windows系统下面,我们可以使用VirtualAlloc系列函数,通过申请2页内存,并设置某页的保护参数(比如,可读,可写等),就可以实现类似的保护机制。这样,当我们对新增加的类(数据结构),就可以重载operator new/delete,将类的边界设置到一页的边缘,再将相邻页设置为不可读不可写。这样就能有效监测堆越界读写问题。而且可以,设置某个编译宏,比如PROTECT_CLASSX。演示代码如下:#define ONE_PAGE_SIZE (1024*4) class NewClassX { public: const static size_t One_Page = ONE_PAGE_SIZE; static void * operator new (size_t size) { void * pOrigin = VirtualAlloc(nullptr, One_Page * 2, MEM_RESERVE, PAGE_READWRITE); if(pOrigin == nullptr) return nullptr; void * p = VirtualAlloc((BYTE*)pOrigin+One_Page, One_Page, MEM_RESERVE, PAGE_NOACCESS); return (BYTE*)p - size; } static void operator delete(void * p) { NewClassX * obj = (NewClassX*)p; obj->~NewClassX(); void * pOrigin = (BYTE*)p - (One_Page - sizeof(NewClassX)); VirtualFree(pOrigin); } //... other operations private: // private states; }
在linux下,则需要借助mmap和mprotect来实现这个机制。具体步骤如下,首先用mmap使用PROT_NONE映射一个特殊文件,比如/dev/zero(或者使用MAP_ANONYMOUS),然后再用mprotect提交内存。上面的例子,可以继续使用,但是只列出来核心的代码,什么重载操作符就不写了,另外,内存映射文件j句柄最好用内存池来hold,最后在close掉。演示代码只说明大致用法,并不能直接拿来用。void * VirtualAllocInLinux(int fd, size_t size) { void * pMmstart = mmap(nullptr, 2* One_Page, PROT_READ|PROT_WRITE, fd, 0); void * p = mprotect((BYTE*)pMmstart+One_Page, One_Page, PROT_NONE); return (BYTE*)pMmstart + One_Page - size; } void VirtualFreeInLinux(void * p) { NewClassX * obj = (NewClassX*)p; obj->~NewClassX(); void * pOrigin = (BYTE*)p + sizeof(NewClassX) - One_Page; munmap(pOrigin, 2 * One_Page); }
下面补充mprotect的用法:#include #include #include #include #include #include #include #define handle_error(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0) char *buffer; static void handler(int sig, siginfo_t *si, void *unused) { printf("Got SIGSEGV at address: 0x%lx ", (long) si->si_addr); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { char *p; int pagesize; struct sigaction sa; sa.sa_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); sa.sa_sigaction = handler; if (sigaction(SIGSEGV, &sa, NULL) == -1) handle_error("sigaction"); pagesize = sysconf(_SC_PAGE_SIZE); if (pagesize == -1) handle_error("sysconf"); /* Allocate a buffer aligned on a page boundary; initial protection is PROT_READ | PROT_WRITE */ buffer = memalign(pagesize, 4 * pagesize); if (buffer == NULL) handle_error("memalign"); printf("Start of region: 0x%lx ", (long) buffer); if (mprotect(buffer + pagesize * 2, pagesize, PROT_READ) == -1) handle_error("mprotect"); for (p = buffer ; ; ) *(p++) = "a"; printf("Loop completed "); /* Should never happen */ exit(EXIT_SUCCESS); }
再把mmap函数的用法示例如下:#include #include #include #include #include #include #define handle_error(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0) int main(int argc, char *argv[]) { char *addr; int fd; struct stat sb; off_t offset, pa_offset; size_t length; ssize_t s; if (argc < 3 || argc > 4) { fprintf(stderr, "%s file offset [length] ", argv[0]); exit(EXIT_FAILURE); } fd = open(argv[1], O_RDONLY); if (fd == -1) handle_error("open"); if (fstat(fd, &sb) == -1) /* To obtain file size */ handle_error("fstat"); offset = atoi(argv[2]); pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1); /* offset for mmap() must be page aligned */ if (offset >= sb.st_size) { fprintf(stderr, "offset is past end of file "); exit(EXIT_FAILURE); } if (argc == 4) { length = atoi(argv[3]); if (offset + length > sb.st_size) length = sb.st_size - offset; /* Canaqt display bytes past end of file */ } else { /* No length arg ==> display to end of file */ length = sb.st_size - offset; } addr = mmap(NULL, length + offset - pa_offset, PROT_READ, MAP_PRIVATE, fd, pa_offset); if (addr == MAP_FAILED) handle_error("mmap"); s = write(STDOUT_FILENO, addr + offset - pa_offset, length); if (s != length) { if (s == -1) handle_error("write"); fprintf(stderr, "partial write"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
美团饿了么启动佣金改革近日,美团外卖饿了么开始推行一种新的费率模式。最大的调整是,商家每单的平台服务费(俗称佣金)被拆成了技术服务费和履约服务费两大块。其中,技术服务费(佣金)的构成,主要包括商家信息展
美团又提高佣金了,违反反垄断法可以分拆了它吗?最近几天,风传上海对美团开始反垄断调查,但我感觉它压根儿也不怕。美团的股价已经快跌了一半了,但还是高高在上,价值1万4千亿港币,可能美团的王兴压根儿就不担心。说到股价,我比起京东阿
央行批准支付宝牌照续展,支付宝将继续合规运营品玩5月13日讯,据央行官网5月13日公示的消息,支付宝支付牌照的续展申请获得通过,有效期延长至2026年5月。2011年5月,支付宝获得央行发布的中国第一批支付业务许可证,有效期
刚刚!央行公布首批27张支付牌照续展结果,24家通过续展今日,首批27张支付牌照迎来第二次续展,央行发布对27家非银行机构支付业务许可证的续展决定。27家支付机构续牌结果截图支付宝财付通银联商务拉卡拉通联支付快钱在内的首批获牌的第三方支
央行与马云的蚂蚁集团达成合作后,数字人民币对接支付宝马云是一个非常传奇性的人物,他开启了我国一个全新的行业发展,可以说是他的一些思想和坚持改变了我们国民的日常生活方式,现在大街小巷常见的扫码支付就是起源于他的想法。利用手机扫描二维码
特斯拉刹车失灵本来就是伪命题我一直关注特斯拉事件,一般都是只看不评价,各种说法都有,哪些是水军一目了然,我说一下自己的想法,说得不合意的,喷子手下留情。1关于刹车,正常情况下,特斯拉不会撞车,不会存在刹不住的
卫星互联网来了偏远地区上网将有新选择日前,中国卫星网络集团有限公司(简称星网)正式成立,此举标志我国的卫星互联网将进入加速发展阶段。根据日前国外网友的实际测试,卫星互联网(星联网)的下载速率在70M左右,等同于目前国
比特币如何获得?最常见的比特币获取方式有哪些?近一个星期来比特币却赚足了风头,经历过跳水后也在缓慢反弹。欧易OKEx平台的数据显示,5月12日,比特币价格达到57000美元枚。我们很容易就能看出,比特币在60000美元以下运行
浅谈央行的数字货币央行的数字货币很快就要落地了,很多读者对于这个不太熟悉,各种自媒体的解读也是五花八门,有人说是数字货币,要替代比特币,又有人说央行推出数字化货币目的是赶走微信支付宝这样的第三方机构
特斯拉维权女车主被起诉被要求道歉赔偿损失因站车顶维权而备受关注的河南张女士在5月6日将特斯拉和特斯拉副总裁陶琳告上了法庭,称陶琳胡乱表态影响其生活,要求全网道歉,张女士的丈夫回应起诉事件这才是第一集,要整就整连续剧。不过
我国到目前为止到底有没有能力自主研发制造芯片?负责任地说,我国有能力自主研发芯片制造芯片。但到目前为止,我国在高端芯片的设计与制造上困难很大,不过在中低端芯片的设计和制造上,基本上已经掌握了生产链所有环节的技术。目前,我国芯片