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从该部分读取一个单词并将该单词用作地址,但实际上这是一个无效的地址.导致此类错误的可能原因是什么?
谢谢!
- 在这里看看ptrace的strace输出:ptrace(PTRACE_PEEKTEXT,651,0xcc4fe480,[0x3ac706a4506fa1d])= 0为什么最后一个参数用方括号注释?这是否意味着它代表了回报价值?
正确.
- 两个.so之间有一个部分(粗体字体)但与任何inode无关.这部分代表什么?
它是一个mmap用MAP_ANONYMOUNS标志编写的内存区域(即它不对应于磁盘上的任何文件).
由于该区域的大小正好是1MB,并且由于它被映射的私有区域包围PROT_NONE,因此可以肯定的是,该区域代表一些线程堆栈,由堆栈保护区域包围.
- Gdb从该部分读取一个单词并将该单词用作地址,但实际上这是一个无效的地址.导致此类错误的可能原因是什么?
出于某种原因,GDB认为应该在地址处有代码0x3ac7068,并且希望在那里放置内部断点.GDB使用内部断点来跟踪加载的共享库(以及其他内容).
输出maintenance info break应该显示GDB认为驻留在"坏"地址的代码.
| 归档时间: |
|
| 查看次数: |
1851 次 |
| 最近记录: |