【问题标题】:gdb "watch" can not variable modified by glibc(read) function?gdb“watch”不能通过glibc(read)函数修改变量?
【发布时间】:2013-09-29 05:17:49
【问题描述】:

chmodified.I usedwatch chin gdb,我想打破它,它不起作用。

ch=1;这样的东西会坏掉。为什么read()不呢?

这样使用watch 命令是正确的。或者read()函数是特殊的?

对不起我的英语,代码说明一切。

文件 1.c:

#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <stdio.h> 
const char *const filename = "/etc/passwd"; 
int main(void) 
{ 
     int fd; 
     int ch; 
     fd = open(filename, O_RDONLY); 
     read(fd, &ch, sizeof(int));  
     printf ("%d\n", ch); 
     close (fd); 
     return 0; 
}

gcc -g 1.c

调试:

$ gdb a.out  
 GNU gdb (GDB) 7.4.1-debian 
 Copyright (C) 2012 Free Software Foundation, Inc. 
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
 This is free software: you are free to change and redistribute it. 
 There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
 and "show warranty" for details. 
 This GDB was configured as "i486-linux-gnu". 
 For bug reporting instructions, please see: 
 <http://www.gnu.org/software/gdb/bugs/>... 
 Reading symbols from /home/zodiac1111/tmp/a.out...done. 
 (gdb) b main 
 Breakpoint 1 at 0x80484b5: file 1.c, line 11. 
 (gdb) r 
 Starting program: /home/zodiac1111/tmp/a.out  

 Breakpoint 1, main () at 1.c:11 
 11        fd = open(filename, O_RDONLY); 
 (gdb) watch ch 
 Hardware watchpoint 2: ch 
 (gdb) c 
 Continuing. 
 1953460082 

 Watchpoint 2 deleted because the program has left the block in
 which its expression is valid. 
 __libc_start_main (main=0x80484ac <main>, argc=1, ubp_av=0xbffff4c4,  
     init=0x8048530 <__libc_csu_init>, fini=0x8048520 <__libc_csu_fini>,  
     rtld_fini=0xb7ff0590, stack_end=0xbffff4bc) at libc-start.c:260 
 260    libc-start.c: No such dir...
 (gdb) c 
 Continuing. 
 [Inferior 1 (process 9513) exited normally]

【问题讨论】:

  • ch 真的读了吗?检查读取结果。
  • int ch=42;if(read(fd, &amp;ch, sizeof(int))==-1) perror("read:"); 我确定 read() 成功了。而 ch 已更改。

标签: c linux gdb glibc


【解决方案1】:

对于read() 的正常实现,对内存的写入将由内核直接执行,而不是由任何用户空间代码执行。调试器没有在内核中放置断点的机制,即使有,它也无权这样做。

【讨论】:

  • 此外,内核(甚至硬件设备驱动程序本身,如果文件缓存被禁用)可能正在使用与用户空间 VA 不同的虚拟地址映射写入内存。 x86 调试寄存器只能监控虚拟地址,不能监控物理地址。
  • read()之类的其他函数不能是watch的地方。我想知道所有这种类型的函数。或者你能给我一些参考文档吗。
  • 没有官方文档。形式上,read 可以是一个库函数,它使用内核读入一个临时缓冲区,然后将memcpy 读入调用者的缓冲区。这将是低效但有效的。
  • 我猜定义应该是:查看你的 C 库以及它在哪里执行系统调用,以使内核直接将数据写入(或在使用 awatch 的情况下读取)到监视变量 this会发生的。
猜你喜欢
  • 2022-10-04
  • 1970-01-01
  • 2019-05-18
  • 2017-03-08
  • 2017-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-25
相关资源
最近更新 更多