haypo / python-ptrace

python-ptrace is a debugger using ptrace (Linux, BSD and Darwin system call to trace processes) written in Python. python-ptrace is an opensource project (contribute!) written in Python under GNU GPLv2 license.

Clone this repository (size: 221.4 KB): HTTPS / SSH
$ hg clone http://bitbucket.org/haypo/python-ptrace/
commit 100: 8eb4b12d1fd9
parent 99: 553f2655e3dc
branch: default
MemoryMapping.search(): * reuse process.readBytes() which is fast and portable * convert function to a generator
Victor Stinner / haypo
11 months ago

Changed (Δ125 bytes):

raw changeset »

ptrace/debugger/memory_mapping.py (13 lines added, 19 lines removed)

Up to file-list ptrace/debugger/memory_mapping.py:

@@ -4,6 +4,7 @@ if HAS_PROC:
4
4
from ptrace.debugger.process_error import ProcessError
5
5
from ptrace.ctypes_tools import formatAddress
6
6
import re
7
from weakref import ref
7
8
8
9
PROC_MAP_REGEX = re.compile(
9
10
    # Address range: '08048000-080b0000 '
@@ -31,7 +32,7 @@ class MemoryMapping:
31
32
     - major_device / minor_device (int): major / minor device number
32
33
     - inode (int)
33
34
     - pathname (str)
34
     - pid (int)
35
     - _process: weak reference to the process
35
36
36
37
    Operations:
37
38
     - "address in mapping" checks the address is in the mapping.
@@ -40,7 +41,8 @@ class MemoryMapping:
40
41
     - "repr(mapping)" create a string representation of the mapping,
41
42
       useful in list contexts
42
43
    """
43
    def __init__(self, start, end, permissions, offset, major_device, minor_device, inode, pathname, pid):
44
    def __init__(self, process, start, end, permissions, offset, major_device, minor_device, inode, pathname):
45
        self._process = ref(process)
44
46
        self.start = start
45
47
        self.end = end
46
48
        self.permissions = permissions
@@ -49,7 +51,6 @@ class MemoryMapping:
49
51
        self.minor_device = minor_device
50
52
        self.inode = inode
51
53
        self.pathname = pathname
52
        self.pid = pid
53
54
54
55
    def __contains__(self, address):
55
56
        return self.start <= address < self.end
@@ -60,28 +61,20 @@ class MemoryMapping:
60
61
            text += " => %s" % self.pathname
61
62
        text += " (%s)" % self.permissions
62
63
        return text
63
    
64
    __repr__ = __str__
65
64
66
    def search(self, bytestr):
65
        retlist = []
67
        process = self._process()
66
68
        bytestr_len = len(bytestr)
67
        proc_mem = open("/proc/%i/mem" % self.pid, "r")
68
        proc_mem.seek(self.start)
69
69
        covered = self.start
70
        data = proc_mem.read(self.end - self.start)
70
        data = process.readBytes(self.start, self.end - self.start)
71
71
        while (data != ""):
72
72
            offset = data.find(bytestr)
73
73
            if (offset == -1):
74
74
                break
75
            else:
76
                retlist.append(offset + covered)
77
                covered += offset + bytestr_len
78
                proc_mem.seek(covered)
79
                data = proc_mem.read(self.end - covered)
80
        proc_mem.close()
81
        return retlist
82
83
    def __repr__(self):
84
        return self.__str__()
75
            yield (offset + covered)
76
            covered += offset + bytestr_len
77
            data = process.readBytes(covered, self.end - covered)
85
78
86
79
def readProcessMappings(process):
87
80
    """
@@ -106,6 +99,7 @@ def readProcessMappings(process):
106
99
            if not match:
107
100
                raise ProcessError(process, "Unable to parse memoy mapping: %r" % line)
108
101
            map = MemoryMapping(
102
                process,
109
103
                int(match.group(1), 16),
110
104
                int(match.group(2), 16),
111
105
                match.group(3),
@@ -113,7 +107,7 @@ def readProcessMappings(process):
113
107
                int(match.group(5), 16),
114
108
                int(match.group(6), 16),
115
109
                int(match.group(7)),
116
                match.group(8), process.pid)
110
                match.group(8))
117
111
            maps.append(map)
118
112
    finally:
119
113
        mapsfile.close()