0

I am trying to create a program to track memory of a process.. What I have is at a certain point trying to protect all memory using my protect function:

static void Protect(void* ptr, size_t size)
{
MemoryMgr& mgr = MemoryMgr::instance();
assert(!(size%s_pageAlign));
assert(ptr == (void*)((unsigned long long)(ptr)&0xfffffffffffff000));

printf("Protecting: 0x%x - 0x%x\n" ,(unsigned long long)(ptr), (unsigned long long)(ptr) + size);
assert(mgr.m_protected.insert(MemoryMgr::Protected_t::value_type(ptr, size)).second);
int r = mprotect(ptr, size, PROT_READ);
if (r) {
    perror("mprotect");
    cout << "Error: " << r << endl;
    cout.flush();
    exit(1);
}
s_allocCnt += size / s_pageAlign + ((size%s_pageAlign)? 1 : 0);

}

and then I have regisered an interuupt handler that does:

static void handler(int sig, siginfo_t *si, void *unused) {
    MemoryMgr::OnSegFault(si ->si_addr, sig);
}

int MemoryMgr::OnSegFault(void* addr, int serious) {
    MemoryMgr& mgr = instance();
    Protected_t::iterator ptr = std::find_if(begin(mgr.m_protected), end(mgr.m_protected), [addr](Protected_t::value_type& ptr) -> bool {
        return ((ptr.first <= addr) && (addr < (ptr.first + ptr.second)));
    });
    if (ptr == mgr.m_protected.end()) {
        cout << "Ignoring segfault at Addr: " << (unsigned long long)(addr) << endl;
        mprotect((void*)((unsigned long long)(addr)&0xfffffffffffff000), s_pageAlign, PROT_READ | PROT_WRITE);
        s_ignoredPageFaults++;
        return 1;
    }
    printf("Segaulting at Ptr : 0x%x - 0x%x\n", (unsigned long long)(ptr ->first), (unsigned long long)(ptr ->first) + ptr ->second);
    s_segFaultCnt += ptr ->second/s_pageAlign + ((ptr ->second%s_pageAlign)? 1 : 0);
    int r = mprotect(ptr ->first, ptr ->second, PROT_READ | PROT_WRITE);
    if (r) {
        cout << "Mprotect Failed" << endl;
        cout.flush();
        return 0;
    }
    return 1;
}

The process seems to be stuck at a certain fwrite... but I can see in logs that the memory the process is trying to access has long gone segaulted and returned to normal state.. I can also see that the process does not halt on the first memory read from that block but after quite a lot of pages... does anyone have any idea/clue ?

Thanks.

Alon
  • 1,776
  • 13
  • 31
  • 1
    You seem to be doing lots of stuff in your signal handle that is not allowed. using cout being one of them, mprotect another (according to POSIX.1-2008, but you might want to have a look what your implemetnation supports). – PlasmaHH Apr 09 '14 at 13:49
  • that is only after desperation.. it happens even without it.. – Alon Apr 09 '14 at 14:11
  • So without it, you mprotect some memory to not write to it, and then the program locks up trying to write to it since, well, the memory is write protected? Maybe you should try to write a minimal testcase that people can take, compile, and test for themselves. – PlasmaHH Apr 09 '14 at 14:14
  • yeah was trying to reproduce it in a shorter version but couldn't since it's locking on fwrite.. still trying.. and yes I want the program to let me know that it wrote there.. and then continue normally. as I am releasing it – Alon Apr 09 '14 at 14:19
  • What do you mean by "releasing it"? Call mprotect again? POSIX doesn't allow it. – PlasmaHH Apr 09 '14 at 14:20
  • I mean, if he segaulted since he tried to write a read protected only, I will mark it for myself and then change it to READ|WRITE and let him continue normally. – Alon Apr 09 '14 at 14:25

0 Answers0