[C++]実行時に、オブジェクトが読み取り専用であることを確認する方法

2303 ワード

多くの人が1つの問題に出会ったことがあると信じて、コードが多すぎて、どこでこのオブジェクトを修正したのか分かりません.これは実は2つの方法がある.
1.デバッグ時にデータのブレークポイントを下げることができる.
gdbにはwatchブレークポイントがある.例えばgdb>watch*(int*)0 x 12433、このデータを監視するにはアドレスを使います.そうしないと、このscopeを過ぎると、データのブレークポイントが無効になります.また、監視の値は内蔵データ型で表現できれば、ハードウェアブレークポイントがあります.そうしないと効率が低下します.
2.運行する時、本文は主にこれについて述べる.
まず振り返ってみると、execにはコードセグメント、データセグメントなど、いくつかのセグメントがあることがわかります.これらのセグメントは読み書き属性がある、例えばコードセグメントは読み書きのみ可能であり、スタックセグメントは読み書き可能である~.では、私たちは書くことができないセグメントにオブジェクトを詰めたいと思っています.例えば.textセグメント....(実は、詰め込んだことがありますが、警告があるだけです)
この異常な暴力は、しかも予備の余地が小さすぎて、あまり適切ではない.
現在、オペレーティングシステムはセグメントモード+ページングモードでメモリを管理する.セグメントモードが通じなくて、ページモードを変えて、方法を探してメモリページの属性~~.
幸いなことに、Linuxの下にmprotectシステムの呼び出しがあり、実行時にメモリページの読み書き属性を設定することができ、唯一の要求はメモリが4 K整列する必要があり、少し浪費した.
はい、mprotectのman page:http://linux.die.net/man/2/mprotectを見てみましょう.
署名は簡単です:int mprotect(const void*addr,size_t len,int prot);
1つのアドレス、1つのメモリの長さ、および読み書き属性は、呼び出しの結果を返し、0を返すことに成功し、他の数字を返すことに失敗する.
ちなみにman pageの例を見ると、4 Kで揃えたメモリを作るテクニックがあります~(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

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);

}


これで、私たちは実行することができて、1つのオブジェクトが書くことができないことを保証して、書くならば、coreは落ちます:-D
PS:
Windowsの下で同様なシステムの呼び出しがあることを望んで、Windowsの下でVirtualProtectがあって、興味のある友达は少し研究します