class
MapsItem:
def
__init__(
self
, startAddr, endAddr, fOffset, path):
self
.startAddr
=
int
(startAddr,
16
)
self
.endAddr
=
int
(endAddr,
16
)
self
.fileOffset
=
int
(fOffset,
16
)
self
.path
=
path
def
update(
self
, startAddr
=
None
, endAddr
=
None
, path
=
None
):
if
startAddr
is
not
None
:
self
.startAddr
=
startAddr
if
endAddr
is
not
None
:
self
.endAddr
=
endAddr
if
path
is
not
None
:
self
.path
=
path
def
__str__(
self
):
return
"MapsItem{%s-%s %s %s}"
%
(
hex
(
self
.startAddr),
hex
(
self
.endAddr),
hex
(
self
.fileOffset),
self
.path)
class
PidItem(
object
):
pid
=
0
lst_segments
=
[]
def
__init__(
self
, pid):
self
.pid
=
pid
def
printLst(
self
):
for
item
in
self
.lst_segments:
print
(
"%s"
%
(item))
class
KKStackCache:
pidmap
=
{}
def
__init__(
self
, pid):
if
pid
in
KKStackCache.pidmap:
pass
else
:
KKStackCache.parserMaps(pid)
@staticmethod
def
parserMaps(pid):
try
:
fname
=
"/proc/%d/maps"
%
(pid)
f
=
open
(fname)
pattern
=
re.
compile
(r
'([\w]+)-([\w]+)\s+([\w\-]+)\s+([\w\-]+)\s+([\w\:]+)\s+([\d]+)\s+(\S+(?:\s+\S+)*?)*\s*$'
)
KKStackCache.pidmap[pid]
=
PidItem(pid)
mapsdata
=
[]
lines
=
f.readlines()
for
line
in
lines:
match
=
re.match(pattern, line)
if
match:
mapsItem
=
MapsItem(match.group(
1
), match.group(
2
), match.group(
4
), match.group(
7
))
mapsdata.append(mapsItem)
else
:
print
(
"No match:"
+
line)
KKStackCache.pidmap[pid].lst_segments
=
sorted
(mapsdata, key
=
lambda
x: x.startAddr)
f.close()
except
:
pass
print
(
"parser %d over."
%
pid)
@staticmethod
def
addrInfo(pid, addr):
pidmap
=
KKStackCache.pidmap.get(pid)
if
pidmap
is
not
None
:
lst
=
pidmap.lst_segments
bg
=
0
;
end
=
len
(lst)
-
1
while
bg <
=
end:
mid
=
int
((bg
+
end
+
1
)
/
2
)
if
addr < lst[mid].startAddr:
end
=
mid
-
1
elif
addr >
=
lst[mid].endAddr:
bg
=
mid
+
1
else
:
itm
=
lst[mid]
path
=
itm.path
offset
=
itm.fileOffset
+
(addr
-
itm.startAddr)
return
True
, addr, offset, path
return
False
,
None
,
None
,
None
@staticmethod
def
printLst(pid):
pidmap
=
KKStackCache.pidmap.get(pid)
if
pidmap
is
not
None
:
pidmap.printLst()
if
pid >
0
:
name, offset, module
=
BPF._sym_cache(tgid).resolve(addr,
False
)
if
name
is
None
:
KKStackCache(pid)
isExist, baseAddr, offset, path
=
KKStackCache.addrInfo(pid, addr)
if
not
isExist:
KKStackCache.parserMaps(pid)
isExist, baseAddr, offset, path
=
KKStackCache.addrInfo(pid, addr)
if
isExist:
if
path
is
not
None
:
symstr
=
"%s %s"
%
(
hex
(offset), path)