GDB strace显示它试图在无效地址处进行ptrace

Ma *_*ent 6 c++ linux ptrace gdb strace

在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_sigprocmask(SIG_BLOCK,NULL,[RT_1 ],8)= 0
...
...
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首先在内存地址0xcc4fe480进行 ptrace 并获得值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 r -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.so
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之间有一个部分(粗体字体),但与任何inode无关.这部分代表什么?
3. Gdb从该部分读取一个单词并将该单词用作地址,但实际上这是一个无效的地址.导致此类错误的可能原因是什么?

谢谢!

Emp*_*ian 5

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

正确.

  1. 两个.so之间有一个部分(粗体字体)但与任何inode无关.这部分代表什么?

它是一个mmapMAP_ANONYMOUNS标志编写的内存区域(即它不对应于磁盘上的任何文件).

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

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

出于某种原因,GDB认为应该在地址处有代码0x3ac7068,并且希望在那里放置内部断点.GDB使用内部断点来跟踪加载的共享库(以及其他内容).

输出maintenance info break应该显示GDB认为驻留在"坏"地址的代码.