GDB:列出崩溃进程的所有映射内存区域

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

我从 x86 Linux 机器(内核 2.6.35-22,如果重要的话)上的死进程中获得了全堆核心转储,我正在尝试在 GDB 中进行调试。

是否有一个我可以使用的 GDB 命令,意思是“显示该进程分配的所有内存地址区域的列表?”换句话说,我可以找出可以在此转储中检查的所有可能的有效内存地址吗?

我问的原因是我需要在整个进程堆中搜索某个二进制字符串,并且为了使用

find
命令,我需要有一个开始和结束地址。简单地从 0x00 到 0xff 进行搜索是行不通的,因为
find
一旦遇到无法访问的地址就会停止:

(gdb) 查找 /w 0x10000000, 0xff000000, 0x12345678

警告:无法访问 0x105ef883 处的目标内存,正在停止 搜索。

所以我需要获取内存中所有可读地址区域的列表,以便我可以一次搜索一个。

(我需要做that的原因是我需要找到内存中指向at某个地址的所有结构。)

show mem
show proc
info mem
info proc
似乎都不能满足我的需要。

linux gdb
7个回答
120
投票

在 GDB 7.2 中:

(gdb) help info proc
Show /proc process information about any running process.
Specify any process id, or use the program being debugged by default.
Specify any of the following keywords for detailed info:
  mappings -- list of mapped memory regions.
  stat     -- list a bunch of random process info.
  status   -- list a different bunch of random process info.
  all      -- list all available /proc info.

您需要

info proc mappings
,但在没有
/proc
时(例如在事后调试期间)它不起作用。

尝试使用

maintenance info sections


23
投票

如果您有程序和核心文件,则可以执行以下步骤。

1)在程序上运行 gdb 以及核心文件

 $gdb ./test core

2) 输入 info 文件并查看核心文件中有哪些不同的段。

    (gdb)info files

示例输出:

    (gdb)info files 

    Symbols from "/home/emntech/debugging/test".
    Local core dump file:
`/home/emntech/debugging/core', file type elf32-i386.
  0x0055f000 - 0x0055f000 is load1
  0x0057b000 - 0x0057c000 is load2
  0x0057c000 - 0x0057d000 is load3
  0x00746000 - 0x00747000 is load4
  0x00c86000 - 0x00c86000 is load5
  0x00de0000 - 0x00de0000 is load6
  0x00de1000 - 0x00de3000 is load7
  0x00de3000 - 0x00de4000 is load8
  0x00de4000 - 0x00de7000 is load9
  0x08048000 - 0x08048000 is load10
  0x08049000 - 0x0804a000 is load11
  0x0804a000 - 0x0804b000 is load12
  0xb77b9000 - 0xb77ba000 is load13
  0xb77cc000 - 0xb77ce000 is load14
  0xbf91d000 - 0xbf93f000 is load15

就我而言,我有 15 个段。每个段都有地址的开始和地址的结束。选择要搜索数据的任何段。例如,让我们选择 load11 并搜索模式。 Load11 的起始地址为 0x08049000,结束地址为 0x804a000。

3) 在片段中搜索模式。

(gdb) find /w 0x08049000 0x0804a000 0x8048034
 0x804903c
 0x8049040
 2 patterns found

如果您没有可执行文件,您需要使用一个打印核心文件所有段数据的程序。然后您可以在某个地址搜索特定数据。我没有找到任何这样的程序,您可以使用以下链接中的程序来打印核心或可执行文件的所有段的数据。

 http://emntech.com/programs/printseg.c

11
投票
(gdb) maintenance info sections 
Exec file:
    `/path/to/app.out', file type elf32-littlearm.
    0x0000->0x0360 at 0x00008000: .intvecs ALLOC LOAD READONLY DATA HAS_CONTENTS

这是来自上面 phihag 的评论,值得单独回答。这可以工作,但

info proc
不适用于 gcc-arm-none-eabi Ubuntu 软件包中的 arm-none-eabi-gdb v7.4.1.20130913-cvs。


7
投票

您还可以使用

info files
列出进程二进制文件中加载的所有二进制文件的所有部分。


5
投票

我刚刚看到以下内容:

set mem inaccessible-by-default [on|off]

这里

它可能允许您进行搜索,而无需考虑内存是否可访问。


0
投票

maintenance info sections
的问题是该命令尝试从二进制文件的节头中提取信息。如果二进制文件被触发(例如通过
sstrip
),或者当加载程序可能在加载后更改内存权限时给出错误信息(例如
RELRO
的情况),则它不起作用。


0
投票

请注意,如果您想确定进程的共享内存段、

mmap()
区域等映射到其地址空间的位置,这些都不会帮助您。

此信息似乎未包含在核心中。

maintenance info target-sections
maintenance info target
都没有显示出来。

(所以它可能根本不存在,或者充其量是在 gdb 不使用的核心部分中。也许可以从内部 libc 簿记状态中找出一些信息,但不是以通用方式)。

© www.soinside.com 2019 - 2024. All rights reserved.