查找 GDB 中地址映射位置的最快方法是什么?

问题描述 投票:0回答:2

目前我手动查看

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
...
gdb
2个回答
3
投票

你想要

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

0
投票

这可以使用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
© www.soinside.com 2019 - 2024. All rights reserved.