目前我手动查看
info proc mappings
中的内存映射列表,看看地址属于什么范围。有没有更简单的方法?
(gdb) i proc map
process 23912
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x601000 0x6ce000 0xcd000 0x0 [heap]
0x7fffe6d65000 0x7fffe6d67000 0x2000 0x0 /usr/lib64/libXau.so.6.0.0
0x7fffe6d67000 0x7fffe6f67000 0x200000 0x2000 /usr/lib64/libXau.so.6.0.0
0x7fffe6f67000 0x7fffe6f68000 0x1000 0x2000 /usr/lib64/libXau.so.6.0.0
0x7fffe6f68000 0x7fffe6f69000 0x1000 0x3000 /usr/lib64/libXau.so.6.0.0
0x7fffe6f69000 0x7fffe6f89000 0x20000 0x0 /usr/lib64/libxcb.so.1.1.0
0x7fffe6f89000 0x7fffe7188000 0x1ff000 0x20000 /usr/lib64/libxcb.so.1.1.0
0x7fffe7188000 0x7fffe7189000 0x1000 0x1f000 /usr/lib64/libxcb.so.1.1.0
0x7fffe7189000 0x7fffe718a000 0x1000 0x20000 /usr/lib64/libxcb.so.1.1.0
0x7fffe718a000 0x7fffe718c000 0x2000 0x0 /usr/lib64/libXss.so.1.0.0
0x7fffe718c000 0x7fffe738c000 0x200000 0x2000 /usr/lib64/libXss.so.1.0.0
0x7fffe738c000 0x7fffe738d000 0x1000 0x2000 /usr/lib64/libXss.so.1.0.0
0x7fffe738d000 0x7fffe738e000 0x1000 0x3000 /usr/lib64/libXss.so.1.0.0
...
你想要
info sym
。 这是来自一个简单程序堆栈中的不同帧:
(gdb) info sym $pc
_fxstat + 20 in section .text of /lib64/libc.so.6
或
(gdb) info sym $pc
std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) + 422 in section .text of /lib64/libstdc++.so.6
或
(gdb) info sym $pc
main + 25 in section .text of /tmp/q
这可以使用Python扩展来完成,这种方法的优点是不需要调试符号,并且它支持任何类型的内存映射,如memfd等。
class FindMap(gdb.Command):
"""Find memory mapping, source file and offset corresponding to address"""
def __init__(self):
super(FindMap, self).__init__("findmap", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION)
def invoke(self, arg, from_tty):
arg = int(gdb.parse_and_eval('(uintptr_t)('+arg+')'))
lines = gdb.execute("info proc mappings", from_tty, True).split('\n')
header = ''
foundStart = False
for line in lines:
if foundStart and '0x' in line:
fields = line.split()
start = int(fields[0], 16)
end = int(fields[1], 16)
if start <= arg and arg < end:
map_offset = int(fields[3], 16)
ptr_offset = arg - start
file = fields[5] if len(fields) > 5 else "<anonymous>"
print("Mapping:")
print(header)
print(line)
print("Origin:", file, "+", hex(ptr_offset+map_offset))
elif 'Start Addr' in line and 'End Addr' in line:
foundStart = True
header = line
FindMap()
在 GDB 中使用:
>>> source gdb-findmap.py
>>> findmap 0x7ffff7e94123
Mapping:
Start Addr End Addr Size Offset Perms objfile
0x7ffff7e94000 0x7ffff7e97000 0x3000 0x4d000 r--p /usr/lib/libreadline.so.8.2
Origin: /usr/lib/libreadline.so.8.2 + 0x4d123