简体   繁体   English

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

[英]GDB strace shows it tries to ptrace at an invalid address

I encountered such error when executing ni command during gdb debugging: 在gdb调试期间执行ni命令时遇到这样的错误:

Warning: 警告:
Cannot insert breakpoint 0. 无法插入断点0。
Error accessing memory address 0x3ac706a: Input/output error. 访问存储器地址0x3ac706a时出错:输入/输出错误。

0xf6fa4771 in siglongjmp () from /lib/libc.so.6 来自/lib/libc.so.6的siglongjmp()中的0xf6fa4771

To investigate what problem gdb meets with I strace gdb and get such output: 为了研究gdb遇到什么问题我使用strace gdb并得到这样的输出:

rt_sigprocmask(SIG_BLOCK, NULL, [RT_1], 8) = 0 rt_sigprocmask(SIG_BLOCK,NULL,[RT_1],8)= 0
ptrace(PTRACE_PEEKTEXT, 651, 0xcc4fdf60, [0x1cc4fe470]) = 0 ptrace(PTRACE_PEEKTEXT,651,0xcc4fdf60,[0x1cc4fe470])= 0
ptrace(PTRACE_PEEKTEXT, 651, 0xcc4fe480, [0x3ac706a4506fa1d]) = 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 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_GETREGS,27781,0,0x7fff8990e8b0)= 0
ptrace(PTRACE_PEEKTEXT, 27781, 0x3ac7068, [0x28b]) = -1 EIO (Input/output error) ptrace(PTRACE_PEEKTEXT,27781,0x3ac7068,[0x28b])= -1 EIO(输入/输出错误)
ptrace(PTRACE_PEEKTEXT, 27781, 0x3ac7068, [0x28b]) = -1 EIO (Input/output error) ptrace(PTRACE_PEEKTEXT,27781,0x3ac7068,[0x28b])= -1 EIO(输入/输出错误)

It implies that gdb first ptrace at memory address 0xcc4fe480 and gets value 0x3ac706a4506fa1d (actually a 8-byte value 0x03ac706a4506fa1d ). 这意味着gdb首先在内存地址0xcc4fe480进行 ptrace并获得值0x3ac706a4506fa1d (实际上是一个8字节值0x03ac706a4506fa1d )。 Later it gets an aligned address 0x3ac7068 from the first 4 bytes of that value, which is an invalid address and causes gdb fails to ptrace. 稍后它从该值的前4个字节获取对齐的地址0x3ac7068 ,这是一个无效的地址并导致gdb无法ptrace。

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

cbce2000-cc353000 r-xp 00000000 08:03 295479 xxx.so cbce2000-cc353000 r-xp 00000000 08:03 295479 xxx.so
cc353000-cc3f0000 r--p 00670000 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 cc3f0000-cc3f6000 rw-p 0070d000 08:03 295479 xxx.so
cc3f6000-cc3fe000 rw-p cc3f6000 00:00 0 cc3f6000-cc3fe000 rw-p cc3f6000 00:00 0
cc3fe000-cc3ff000 ---p cc3fe000 00:00 0 cc3fe000-cc3ff000 --- p cc3fe000 00:00 0
cc3ff000-cc4ff000 rwxp cc3ff000 00:00 0 cc3ff000-cc4ff000 rwxp cc3ff000 00:00 0
cc4ff000-cc500000 ---p cc4ff000 00:00 0 cc4ff000-cc500000 --- p cc4ff000 00:00 0

cc500000-cc600000 rwxp cc500000 00:00 0 cc500000-cc600000 rwxp cc500000 00:00 0
cc62d000-cc673000 r-xp 00000000 08:03 295545 yyy.so cc62d000-cc673000 r-xp 00000000 08:03 295545 yyy.so
cc673000-cc674000 ---p 00046000 08:03 295545 yyy.so cc673000-cc674000 --- p 00046000 08:03 295545 yyy.so
cc674000-cc675000 r--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 cc675000-cc676000 rw-p 00047000 08:03 295545 yyy.so

It shows that address 0xcc4fe480 is from the section with bold font above. 它显示地址0xcc4fe480来自上面带粗体字的部分。 This section is not related to any .so or bin file. 此部分与任何.so或bin文件无关。

This question is actually related to another question http://stackoverflow.com/questions/9564417/gdb-cant-insert-internal-breakpoint , which has not been resolved yet. 这个问题实际上与另一个问题http://stackoverflow.com/questions/9564417/gdb-cant-insert-internal-breakpoint有关 ,尚未解决。 I found these problems during the investigation of previous issue. 我在上一期调查中发现了这些问题。

I have 3 questions here: 我在这里有3个问题:
1. Take a look at strace output for ptrace here: 1.在这里查看ptrace的strace输出:
ptrace(PTRACE_PEEKTEXT, 651, 0xcc4fe480, [0x3ac706a4506fa1d]) = 0 ptrace(PTRACE_PEEKTEXT,651,0xcc4fe480,[0x3ac706a4506fa1d])= 0
Why is the last parameter annotated by square brackets? 为什么最后一个参数用方括号注释? Does it mean it represent the return value? 这是否意味着它代表了回报价值? Manual page says ptrace should return the word read for PTRACE_PEEKTEXT, but it looks strace output does not follow that, so I suspect it shows return value in the last parameter. 手册页说ptrace应该为PTRACE_PEEKTEXT返回读取的单词,但看起来strace输出不遵循,所以我怀疑它在最后一个参数中显示返回值。
2. There's a section (who with bold font) between two .so but not associated with any inode. 2.两个.so之间有一个部分(粗体字体),但与任何inode无关。 What does such section represent? 这部分代表什么?
3. Gdb reads one word from that section and uses that word as an address, but actually that's an invalid address. 3. Gdb从该部分读取一个单词并将该单词用作地址,但实际上这是一个无效的地址。 What are the possible causes of such error? 导致此类错误的可能原因是什么?

Thanks! 谢谢!

  1. Take a look at strace output for ptrace here: ptrace(PTRACE_PEEKTEXT, 651, 0xcc4fe480, [0x3ac706a4506fa1d]) = 0 Why is the last parameter annotated by square brackets? 在这里看看ptrace的strace输出:ptrace(PTRACE_PEEKTEXT,651,0xcc4fe480,[0x3ac706a4506fa1d])= 0为什么最后一个参数用方括号注释? Does it mean it represent the return value? 这是否意味着它代表了回报价值?

Correct. 正确。

  1. There's a section (who with bold font) between two .so but not associated with any inode. 两个.so之间有一个部分(粗体字体)但与任何inode无关。 What does such section represent? 这部分代表什么?

It is a region of memory that has been mmap ed with MAP_ANONYMOUNS flag (ie it doesn't correspond to any file on disk). 它是已存储的区域mmap与编MAP_ANONYMOUNS标志(即,它不对应于在磁盘上的任何文件)。

Since the size of that region is exactly 1MB, and since it is surrounded by private regions mapped with PROT_NONE , it is a safe bet that this region represents some thread stack, surrounded by stack guard zones. 由于该区域的大小正好是1MB,并且由于它被用PROT_NONE映射的私有区域PROT_NONE ,因此可以肯定的是,该区域代表一些线程堆栈,由堆栈保护区域包围。

  1. Gdb reads one word from that section and uses that word as an address, but actually that's an invalid address. Gdb从该部分读取一个单词并将该单词用作地址,但实际上这是一个无效的地址。 What are the possible causes of such error? 导致此类错误的可能原因是什么?

For some reason GDB believes that there should be code at address 0x3ac7068 , and wants to place an internal breakpoint there. 出于某种原因,GDB认为应该在地址0x3ac7068处有代码,并且希望在那里放置一个内部断点。 GDB uses internal breakpoints to keep track of loaded shared libraries (among other things). GDB使用内部断点来跟踪加载的共享库(以及其他内容)。

Output from maintenance info break should reveal what code GDB believes is residing at the "bad" address. maintenance info break输出应该揭示GDB认为驻留在“坏”地址的代码。

My guess is that your code is overflowing and writing over a valid address, and gdb is accessing that area of memory expecting an address but getting junk data. 我的猜测是你的代码溢出并写入一个有效的地址,而gdb正在访问那个期望一个地址但却得到垃圾数据的内存区域。 What is the section of code you're trying to debug? 您尝试调试的代码部分是什么? It might help us. 它可能会帮助我们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM