ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Control
CxxUtils
Root
PageAccessControl.cxx
Go to the documentation of this file.
1
/*
2
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3
*/
4
5
#define DEBUG 1
6
#include <algorithm>
/* sort etc */
7
#include <sys/mman.h>
/* mprotect */
8
#include "
CxxUtils/PageAccessControl.h
"
9
#include "
CxxUtils/page_access.h
"
10
#include "
CxxUtils/checker_macros.h
"
11
#include <iostream>
12
using
athena::page_address
;
13
using
athena::next_page_address
;
14
15
PageAccessControl::Entry::Entry
(
const
void
*
a
,
size_t
l,
int
p,
void
* pl):
16
addr
(
page_address
(
a
)),
lenProt
(l),
prot
(p),
leak
(pl),
restored
(0) {}
17
18
19
void
20
PageAccessControl::sort
() {
21
if
(!
m_protectedIsSorted
) {
22
std::sort
(
m_protected
.begin(),
m_protected
.end());
23
m_protectedIsSorted
=
true
;
24
}
25
}
26
bool
27
PageAccessControl::restorePageProt
(
const
void
* addr) {
28
int
rc
(-1);
29
sort
();
30
Entry
ea(addr,0,0,0);
31
protected_t::iterator entry=
32
std::lower_bound(
m_protected
.begin(),
m_protected
.end(), ea);
33
if
(entry !=
m_protected
.end() &&
34
entry->addr == ea.
addr
) {
35
//found it. Restore page prot
36
const
void
* pageAddr =
page_address
(entry->addr);
37
void
* pageAddr_nc
ATLAS_THREAD_SAFE
=
const_cast<
void
*
>
(pageAddr);
38
rc
=mprotect( pageAddr_nc, entry->lenProt, entry->prot);
39
if
(
rc
==0) {
40
#ifdef DEBUG
41
printf(
"PageAccessControl::restorePageProt DEBUG: restored protection %i for page %p containing address %p \n"
,
42
entry->prot,
43
page_address
(entry->addr),
44
entry->addr);
45
printf(
" FIXME NOT Freeing memory at %p \n"
, entry->leak );
46
#endif
47
// free(entry->leak);
48
entry->leak=0;
49
++(entry->restored);
50
}
51
}
else
printf(
"WARNING no entry in procmap for addr=%p, page protection not restored \n"
,addr);
52
return
(
rc
== 0);
53
}
54
55
bool
56
PageAccessControl::protectPage
(
const
void
* addr,
size_t
objSize,
int
prot) {
57
int
rc
(-1);
58
const
procmaps::Entry
*e=
m_pmaps
.getEntry(addr,
true
);
59
//this is the length of the range we are going to protect
60
if
(0 != e) {
61
const
void
*pageAddr =
page_address
(addr);
62
size_t
lenProt = (size_t)addr - (
size_t
)(pageAddr) + objSize;
63
size_t
nextProt = (size_t)addr + objSize;
64
size_t
nextUnprot = (size_t)(
next_page_address
((
void
*)(nextProt-1)));
65
int
pageProt(PROT_NONE);
66
if
(e->readable) pageProt |= PROT_READ;
67
if
(e->writable) pageProt |= PROT_WRITE;
68
if
(e->executable) pageProt |= PROT_EXEC;
69
if
(pageProt != prot) {
70
//fill up the space from nextProt to nextUnprot to avoid allocations
71
//in the locked pages, and SEGVs...
72
// void *leak(0);
73
// if (0 == (prot & PROT_WRITE)) {
74
// size_t lenLeak(nextUnprot-nextProt-1);
75
// leak=malloc(lenLeak);
76
// if ((size_t)leak<nextUnprot && (size_t)leak + lenLeak>=nextUnprot) {
77
// //we do not want to allocate our buffer memory past the current
78
// //page, so trim it down
79
// free(leak);
80
// lenLeak=nextUnprot - (size_t)leak -1;
81
// leak=malloc(lenLeak);
82
// }
83
// if (leak < pageAddr ||
84
// (size_t)leak >= nextUnprot) {
85
// //leak has been allocated into previous/next page
86
// //better get rid of it as it will likely
87
// //be locked by another protectPage
88
// free(leak);
89
// leak=0;
90
// } else {
91
// #ifdef DEBUG
92
// printf("PageAccessControl::protectPage DEBUG: fill up space from %p to 0x%x to avoid allocations in locked pages\n",
93
// leak, (int)leak+lenLeak);
94
// #endif
95
// }
96
// }
97
98
void
* pageAddr_nc
ATLAS_THREAD_SAFE
=
const_cast<
void
*
>
(pageAddr);
99
if
(0 == (
rc
= mprotect( pageAddr_nc,
100
lenProt,
101
prot))) {
102
m_protected
.push_back(
Entry
(pageAddr,lenProt, pageProt, 0));
103
m_protectedIsSorted
=
false
;
//FIXME we should use a mapvector
104
#ifdef DEBUG
105
printf(
"PageAccessControl::protectPage DEBUG: set protection %i for page range %p - 0x%lx containing address range=%p - 0x%lx\n"
,
106
prot,
107
pageAddr,
108
(
long
unsigned
int
)(nextUnprot - 1),
109
addr,
110
(
long
unsigned
int
)(nextProt -1) );
111
#endif
112
}
113
}
else
rc
=0;
114
}
else
printf(
"PageAccessControl::protectPage WARNING: no entry in procmap for addr=%p, page protection not restored \n"
,addr);
115
return
(
rc
== 0);
116
}
117
118
bool
PageAccessControl::accessed
(
const
void
* address)
const
{
119
bool
acc(
false
);
120
//fixme: poor man implementation
121
Entry
eaxx(address,0,0,0);
122
PageAccessControl::const_iterator
ia(
beginProtectedPtrs
()),
123
ea(
endProtectedPtrs
());
124
while
(!acc && ia != ea) {
125
// std::cout << address << "page addr " << eaxx.addr << " ia " << ia->addr << " res " << ia->restored << std::endl;
126
acc = (eaxx.
addr
== ia->addr && 0 != ia->restored);
127
++ia;
128
}
129
return
acc;
130
}
a
static Double_t a
Definition
LArPhysWaveHECTool.cxx:38
rc
static Double_t rc
Definition
LArPhysWaveHECTool.cxx:37
page_address
const void * page_address(const void *addr)
Definition
page_access.cxx:11
next_page_address
void * next_page_address(void *addr)
Definition
page_access.cxx:17
PageAccessControl.h
checker_macros.h
Define macros for attributes used to control the static checker.
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition
checker_macros.h:211
PageAccessControl::sort
void sort()
Definition
PageAccessControl.cxx:20
PageAccessControl::m_pmaps
procmaps m_pmaps
the content of /proc/self/maps
Definition
PageAccessControl.h:104
PageAccessControl::accessed
bool accessed(const void *address) const
was the page containing address accessed?
Definition
PageAccessControl.cxx:118
PageAccessControl::m_protected
protected_t m_protected
Definition
PageAccessControl.h:109
PageAccessControl::restorePageProt
bool restorePageProt(const void *addr)
Definition
PageAccessControl.cxx:27
PageAccessControl::beginProtectedPtrs
const_iterator beginProtectedPtrs() const
Definition
PageAccessControl.h:94
PageAccessControl::m_protectedIsSorted
bool m_protectedIsSorted
Definition
PageAccessControl.h:110
PageAccessControl::protectPage
bool protectPage(T *addr, int prot)
protect the page containing addr, record the amount of memory we protected NOTE To avoid SEGV,...
Definition
PageAccessControl.h:49
PageAccessControl::const_iterator
protected_t::const_iterator const_iterator
Definition
PageAccessControl.h:92
PageAccessControl::endProtectedPtrs
const_iterator endProtectedPtrs() const
Definition
PageAccessControl.h:95
athena::page_address
const void * page_address(const void *addr)
Definition
page_access.cxx:11
athena::next_page_address
void * next_page_address(void *addr)
Definition
page_access.cxx:17
std::sort
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
Definition
DVL_algorithms.h:554
page_access.h
PageAccessControl::Entry
protection of a memory region (see mprotect(2))
Definition
PageAccessControl.h:76
PageAccessControl::Entry::leak
void * leak
pointer to the heap fragment we leaked before protecting the page
Definition
PageAccessControl.h:84
PageAccessControl::Entry::lenProt
size_t lenProt
length of the protected region, from page addr to end of protected obj
Definition
PageAccessControl.h:81
PageAccessControl::Entry::prot
int prot
Definition
PageAccessControl.h:82
PageAccessControl::Entry::addr
const void * addr
address of page for which protection was requested. Used as key
Definition
PageAccessControl.h:79
PageAccessControl::Entry::restored
int restored
Definition
PageAccessControl.h:87
PageAccessControl::Entry::Entry
Entry(const void *a, size_t l, int p, void *pl)
Definition
PageAccessControl.cxx:15
procmaps::Entry
Definition
procmaps.h:20
Generated on
for ATLAS Offline Software by
1.17.0