TODO需要在ARM下验证

1. 前言

watchpoint,顾名思义,其一般用来观察某个变量/内存地址的状态(也可以是表达式),如可以监控该变量/内存值是否被程序读/写情况。

在gdb中可通过下面的几种方法来设置watchpoint:

    (gdb) watch
在指定变量/内存地址(表达式)expr设置一个watchpoint。
一但expr值有变化时,将停住程序。
(gdb) rwatch
当expr被读时,停住程序。
(gdb) awatch
当expr被读或被写时,停住程序。
(gdb) info watchpoints
列出当前所设置了的所有观察点。(info break也可查看)

2. gdb watchpoint实践

GDB十分钟快速入门教程的gdb-sample.c为例,
在gdb-sample.c中, 变量n总共被改变了3次,如果我们下个watchpoint在n变量处,因为n变量改变了3次而响应3次watchpoint,因而程序会将被调试器暂停运行3次:

编译gdb-sample.c,并使用gdb 加载gdb-sample:

$ gcc gdb-sample.c -o gdb-sample -g 
$ gdb ./gdb-sample 
GNU gdb (GDB) 7.0.50.20090928-cvs 
Copyright (C) 2009 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later 
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 “i686-pc-linux-gnu”. 
For bug reporting instructions, please see: 
… 
Reading symbols from /home/ddd/gdb-sample…done. 
(gdb) 

watchpoint只能在程序启动后设置,先在main那下个断点,让程序启动后暂停在main函数处:

(gdb) b main 
Breakpoint 1 at 0x80483ad: file gdb-sample.c, line 19. 
(gdb) r 
Starting program: /home/ddd/gdb-sample

Breakpoint 1, main () at gdb-sample.c:19 
19 n = 1; 
(gdb)

给n变量下个watchpoint:

(gdb) watch n 
Hardware watchpoint 2: n 
(gdb) 

敲入”c”命令让程序恢复运行,这时候程序会停止在第一次n变量改变处

20 n++; 

并提示即将运行的下一条的语句:

23 n--;
(gdb) c 
Continuing. 
Hardware watchpoint 2: n

Old value = -1208017424 
New value = 2 
main () at gdb-sample.c:23 
23 n--; 
(gdb)

重复如上操作,程序还会停止两次,所有gdb输出如下:

(gdb) c 
Continuing. 
Hardware watchpoint 2: n

Old value = 2 
New value = 1 
main () at gdb-sample.c:25 
25 nGlobalVar += 100; 
(gdb) —-> 这次停止是由 ”23 n–; “改变变量n的值引起的

(gdb) c 
Continuing. 
n = 1, nGlobalVar = 88 
tempFunction is called, a = 1, b = 2 
Hardware watchpoint 2: n

Old value = 1 
New value = 3 
main () at gdb-sample.c:31 
31 printf(“n = %d”, n); 
(gdb) —-> 这次停止是由 ” 30 n = tempFunction(1, 2); “改变变量n的值引起的

(gdb) c 
Continuing.

Watchpoint 2 deleted because the program has left the block in 
which its expression is valid. 
0xb7e91450 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 
(gdb)

2: watchpoint在gdb中的实现原理

watchpoint可以看成是一种特殊的”断点”, 其实现一般需要CPU支持硬件断点,如果纯软件实现watchpoint,那好像会很耗CPU.(我没
去看gdb的软0watchpoint的实现,有时间得去研究下,不过如果让我来实现这个功能(和同事讨论过),应该是设置watchpoint所在的
那个页表为不可读/访问,然后在缺页处理那检测当前的页和地址是否是软设置watchpoint所在的页和watchpoint的地址,如果是,则
说明可以假设该watchpoint发生了)

目前支持watchpoint硬件断点的arch有x86,ppc和mips。

如果支持硬件断点,那么可以将监控的操作交给硬件来完成,而gdb这边只要做个简单的逻辑处理就行.
还是以上面的gdb-sample.c为例:

当gdb执行watch n命令后,gdb会在n变量所在的内存地址上下个硬件写断点

(gdb) watch n 
Hardware watchpoint 2: n 

(如果是 rwatch n命令,gdb会在n变量所在的内存地址上下个硬件读断点)
(tips: gdb 通过系统调用ptrace()去修改调试寄存器值,从而达到实现硬件断点的目的)

这样只要系统操作了n变量(内存地址),就会触发一个硬件断点中断。
gdb捕获到这个断点中断后,就会将新的n变量值和改变前的值做比较,
1)如果n变量的值改变了,则将程序停止。
2)如果n变量的值没有改变了,则程序继续运行。

关于硬件断点,可以参考x86 调试寄存器 一文。

3: 远程gdb server的watchpoint 实现

如果调试本地应用程序,gdb可以直接通过ptrace发出的信号得到watchpoint信息。

如果远程调试程序,gdb怎么从远程gdb server那得到watchpoint信息呢?

说到这里,又不得不搬出 GDB远程串行协议了..
在GDB远程串行协议里定义了gdb server和gdb所有的通信规则,所以要告诉gdb,远程gdb server那边踩中watchpoint了,还得通过那个协议来传达。

在GDB远程串行协议的Stop-Reply-Packets里定义了如何传达watchpoint信息:

? TEXT

 
`T AA n1:r1;n2:r2;...'
The program received signal number AA (a two-digit hexadecimal number).
This is equivalent to an `S' response, except that the `n:r' pairs can
carry values of important registers and other information directly in
the stop reply packet, reducing round-trip latency. Single-step and
breakpoint traps are reported this way. Each `n:r' pair is interpreted
as follows:
* If n is a recognized stop reason, it describes a more specific
event that stopped the target. The currently defined stop reasons are
listed below. aa should be `05', the trap signal. At most one stop
reason should be present.
 
The currently defined stop reasons are:
`watch'
`rwatch'
`awatch'
The packet indicates a watchpoint hit, and r is the data address, in hex.

所以只要在Stop-Reply-Packets里添加 watch+断点地址格式的数据,gdb就知道那边踩中watchpoint了.

3. 参考文档

本文地址:
http://www.kgdb.info/gdb_watchpoint/
版权所有 © 转载时必须以链接形式注明作者和原始出处!

[转]GDB-----2.watchpoint的更多相关文章

  1. gdb调试4--回退

    加入你正在使用GDB7.0以上版本的调试器并且运行在支持反向调试的平台,你就可以用以下几条命令来调试程序: reverse-continue 反向运行程序知道遇到一个能使程序中断的事件(比如断点,观察 ...

  2. gdb高级技巧

    注意: 这里是讲gdb的高级技巧.如果没有接触过gdb,请看这篇:点这里. gdb是一个功能极其强大的命令行调试器.其实,除了我们常用的 file b s n q disp p 等命令,也有很多高级技 ...

  3. GDB的Breakpoint, Watchpoint和Catchpoint

    Breakpoint : 设置断点比较直接,在某处停止 Watchpoint : 观察点,即某个变量/表达式发生变化时,停止.可扩展为变量被读/被写/被读or写时都停止 Catchpoint : 在发 ...

  4. gdb 基本知识

    一 单步执行和跟踪函数调用 先给出一段代码,可以用下面介绍的例子. #include <stdio.h> int add_range(int low, int high) { int i, ...

  5. 手把手教你玩GDB

    第一部分牛刀小试:启动GDB开始调试 1.       编译带调试信息的可执行程序:用gcc(g++)编译的时候带上-g选项即可 2.       启动GDB开始调试 (1)gdb program   ...

  6. 调试多线程 & 查死锁的bug & gcore命令 & gdb对多线程的调试 & gcore & pstack & 调试常用命令

    gdb thread apply all bt 如果你发现有那么几个栈停在 pthread_wait 或者类似调用上,大致就可以得出结论:就是它们几个儿女情长,耽误了整个进程. 注意gdb的版本要高于 ...

  7. GDB教程详解

    GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较喜欢那种图形界面方式的,像VC.BCB等IDE的调试,但如果你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC ...

  8. GDB中文手册

    用GDB调试程序GDB概述 2使用GDB 5GDB中运行UNIX的shell程序 8在GDB中运行程序 8调试已运行的程序 两种方法: 9暂停 / 恢复程序运行 9一.设置断点(BreakPoint) ...

  9. Linux高级编程--04.GDB调试程序(设置断点)

    调试已运行的程序 在UNIX下用ps查看正在运行的程序的PID(进程ID),然后用gdb PID格式挂接正在运行的程序. 先用gdb 关联上源代码,并进行gdb,在gdb中用attach命令来挂接进程 ...

随机推荐

  1. poco

    源码安装: 1, ./configure --omit=Data/MySQL,Data/ODBC,Zip,Crypto,NetSSL_OpenSSL     --no-samples  --no-te ...

  2. eclipse启动速度优化

    1. 在eclipse.ini文件中添加如下参数(红色部分) -startup plugins/org.eclipse.equinox.launcher_1.3.0.v20140415-2008.ja ...

  3. A1001. A+B Format

    Calculate a + b and output the sum in standard format -- that is, the digits must be separated into ...

  4. Hessian使用

    ps:以前在项目中用过hessian,但我仅停留在知道这个层面,后面也没有详细了解其中的原理.现在要写简历都不知道怎么写,自己挖的坑,跪着也要填平. Hessian的使用 这里先写下工程中的使用,有个 ...

  5. react中实现点击跳转到新页面方法

    实现点击跳转到新页面,可以有两种形式,一个是本地页面打开,一个是本地页面不变跳转到新的页面. (一)页面点击本地页面打开新页面 引入ant的Button组件 <Button style={{ba ...

  6. MATLAB:图像的与、或、非、异或逻辑运算(&、|、~、xor)

    图像的与.或.非.异或逻辑运算涉及到了&.|.~和xor符号 close all;%关闭当前所有图形窗口,清空工作空间变量,清除工作空间所有变量 clc; clear all; I=imrea ...

  7. 关于setvbuf()函数的详解

    为什么要使用setvbuf函数 如果你的内存足够大,可以把文件IO的BUF设置大一些,这样每次你用fopen/fread/fwrite/fscanf/fprintf语句的时候,都会在内存里操作,减少内 ...

  8. 基于Spring Cloud的微服务入门教程

    (本教程的原地址发布在本人的简书上:http://www.jianshu.com/p/947d57d042e7,若各位看官有什么问题或不同看法请在这里或简书留言,谢谢!) 本人也是前段时间才开始接触S ...

  9. poj 1236(强连通分量分解模板题)

    传送门 题意: N(2<N<100)个学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输. 问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都 ...

  10. curl命令的基本使用

    curl命令的基本使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. curl是基于URL语法在命令行方式下工作的文件传输工具,它支持FTP,FTPS,HTTP,HTTPS,GOP ...