6

我在gdb调试期间执行ni命令时遇到了这样的错误:

警告:
无法插入断点 0。
访问内存地址 0x3ac706a 时出错:输入/输出错误。

/lib/libc.so.6 中的 siglongjmp () 中的 0xf6fa4771

为了调查 gdb 遇到的问题,我 strace gdb 并获得这样的输出:

rt_sigprocmask(SIG_BLOCK,NULL,[RT_1],8)= 0
ptrace(PTRACE_PEEKTEXT,651,0xcc4fdf60,[0x1cc4fe470])= 0
ptrace(PTRACE_PEEKTEXT,651,0xcc4fe480,[0x3ac706a4506fa1d])= 0
rt_sigproc1(SIG ], 8) = 0
...<br> ...
rt_sigprocmask(SIG_BLOCK, NULL, [RT_1], 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [RT_1], 8) = 0
ptrace(PTRACE_GETREGS, 27781, 0, 0x7fff8990e8b0 ) = 0
ptrace(PTRACE_PEEKTEXT, 27781, 0x3ac7068, [0x28b]) = -1 EIO (输入/输出错误)
ptrace(PTRACE_PEEKTEXT, 27781, 0x3ac7068, [0x28b]) = -1 EIO (输入/输出错误)

这意味着 gdb 首先 ptrace 在内存地址0xcc4fe480并获取值0x3ac706a4506fa1d(实际上是一个 8 字节值0x03ac706a4506fa1d)。稍后它从该值的前 4 个字节中获取对齐的地址0x3ac7068,这是一个无效地址并导致 gdb 无法 ptrace。

/proc/[pid]/maps 的内容:

cbce2000-cc353000 R-XP 00000000 08:03 295479 xxx.so
cc353000-cc3f0000 - [R - P 00670000 08:03 295479 xxx.so
cc3f0000-cc3f6000 RW-P 0070d000 08:03 295479 xxx.so
cc3f6000-cc3fe000 RW-P cc3f6000 00:00 0
cc3fe000-cc3ff000 --- p cc3fe000 00:00 0
cc3ff000-cc4ff000 rwxp cc3ff000 00:00 0
cc4ff000-cc500000 --- p cc4ff000 00:00 0

cc500000-cc600000 rwxp cc500000 00:00 0
cc62d000-cc673000ř -xp 00000000 08:03 295545 yyy.so
cc673000-cc674000 ---p 00046000 08:03 295545 yyy.so
cc674000-cc675000 r--p 00046000 08:03 295545 yyy。
cc675000-cc676000 rw-p 00047000 08:03 295545 yyy.so

它表明地址0xcc4fe480来自上面的粗体部分。本节与任何 .so 或 bin 文件无关。

这个问题其实和另一个问题http://stackoverflow.com/questions/9564417/gdb-cant-insert-internal-breakpoint有关,这个问题还没有解决。我在调查上一期时发现了这些问题。

我在这里有 3 个问题:
1. 在这里查看 ptrace 的 strace 输出:
ptrace(PTRACE_PEEKTEXT, 651, 0xcc4fe480, [0x3ac706a4506fa1d]) = 0
为什么最后一个参数用方括号注释?这是否意味着它代表返回值?手册页说 ptrace 应该返回为 PTRACE_PEEKTEXT 读取的单词,但它看起来 strace 输出没有遵循,所以我怀疑它在最后一个参数中显示了返回值。
2. 两个.so 之间有一个节(who 用粗体字),但不与任何inode 关联。这样的部分代表什么?
3. Gdb 从该部分读取一个字并将该字用作地址,但实际上这是一个无效地址。这种错误的可能原因是什么?

谢谢!

4

2 回答 2

5
  1. 在此处查看 ptrace 的 strace 输出: ptrace(PTRACE_PEEKTEXT, 651, 0xcc4fe480, [0x3ac706a4506fa1d]) = 0 为什么最后一个参数用方括号注释?这是否意味着它代表返回值?

正确的。

  1. 两个 .so 之间有一个部分(使用粗体字的部分),但不与任何 inode 关联。这样的部分代表什么?

它是一个mmap带有MAP_ANONYMOUNS标志的内存区域(即它不对应于磁盘上的任何文件)。

由于该区域的大小正好是 1MB,并且它被映射为 的私有区域包围PROT_NONE,因此可以肯定的是,该区域代表一些线程堆栈,被堆栈保护区包围。

  1. Gdb 从该部分读取一个单词并将该单词用作地址,但实际上这是一个无效地址。这种错误的可能原因是什么?

出于某种原因,GDB 认为在 address 处应该有代码0x3ac7068,并希望在那里放置一个内部断点。GDB 使用内部断点来跟踪加载的共享库(除其他外)。

的输出maintenance info break应该揭示 GDB 认为哪些代码驻留在“坏”地址。

于 2012-03-11T23:06:31.947 回答
0

我的猜测是你的代码溢出并写入了一个有效的地址,而 gdb 正在访问该内存区域,需要一个地址,但得到的是垃圾数据。您要调试的代码部分是什么?它可能对我们有帮助。

于 2012-03-10T17:50:39.510 回答