当前位置:编程学习 > C/C++ >>

[C++]运行时,如何确保一个对象是只读的

 

相信很多人碰到过一个问题,就是代码太多了,不知道在哪里把这个对象给修改掉了.这个其实有两种办法的.

 

1. 在调试的时候,可以下数据断点.

 

  gdb有watch断点.比如gdb>watch *(int*)0x12433,要记住,如果想要一只监视这个数据,就要用地址,否则过了这个scope,数据断点就无效了,还有就是,监视的值如果用内置数据类型可以表达的话,是有硬件断点的,否则效率茫茫低.....

 

2. 运行的时候,本文主要讲这个.

 

  先来回顾一下,我们都知道一个exec,都有好几个段,比如代码段,数据段等.这些段是有读写属性的,例如代码段只可以读,栈段是可以读写~~.那么我们就想把一个对象塞到一个不可以写的段里面,比如.text段....(事实上,我塞进去过,只不过会有警告)

 

  这个异常暴力,而且预留余地太小,不太适合.

 

  现在操作系统都是段模式+分页模式来管理内存的.段模式走不通,换页模式,找个办法设置内存页的属性~~.

 

  非常幸运,Linux下面有mprotect系统调用,可以运行时设置内存页的读写属性,唯一的要求是内存需要4K对齐,浪费了一点.

 

  OK,让我们来看mprotect的man page:http://linux.die.net/man/2/mprotect

 

  签名很简答:int mprotect(const void *addr, size_t len, int prot);

 

  一个地址,一个内存的长度,另外就是读写属性,返回调用的结果,成功返回0,失败返回其他数字.

 

  顺便看看man page中的例子,里面有一个技巧,就是搞到一个4K对齐的内存~~ 通过( ptr + 4096 - 1 ) & ~(4096 - 1)搞到的

 

  

 

#include <stdio.h> 

 

#include <stdlib.h> 

 

#include <errno.h> 

 

#include <sys/mman.h> 

 

#include <limits.h>    /* for PAGESIZE */ 

 

#ifndef PAGESIZE 

 

#define PAGESIZE 4096 

 

#endif   www.zzzyk.com

 

int

 

main(void) 

 

 

    char *p; 

 

    char c; 

 

    /* Allocate a buffer; it will have the default 

 

       protection of PROT_READ|PROT_WRITE. */

 

    p = malloc(1024+PAGESIZE-1); 

 

    if (!p) { 

 

        perror("Couldn't malloc(1024)"); 

 

        exit(errno); 

 

    } 

 

    /* Align to a multiple of PAGESIZE, assumed to be a power of two */

 

    p = (char *)(((int) p + PAGESIZE-1) & ~(PAGESIZE-1)); 

 

    c = p[666];         /* Read; ok */

 

    p[666] = 42;        /* Write; ok */

 

    /* Mark the buffer read-only. */

 

    if (mprotect(p, 1024, PROT_READ)) { 

 

        perror("Couldn't mprotect"); 

 

        exit(errno); 

 

    } 

 

    c = p[666];         /* Read; ok */

 

    p[666] = 42;        /* Write; program dies on SIGSEGV */

 

    exit(0); 

 

}

 

至此,我们就可以运行时,保证一个对象不可以写,写的话,core掉:-D

 

PS:

 

希望windows下也有类似的系统调用,Windows下有VirtualProtect,有兴趣的朋友研究一下

 

/**********************************************************************

 * 机械教条主义

 

 * Email:         egmkang [at] 163.com

 * QQ Group:  20240291(慎入,可能没人打理)

 * Weibo:        http://weibo.com/egmkang

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,