尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Linux 命令行入门学习资料 day_6

Linux 命令行入门学习资料 day_6
📅 发布时间:2026/7/19 22:03:20

GDB 监视点watch


一、什么是 watch?—— 变量的“监控摄像头”

之前学过的break是按位置暂停(比如某一行代码),而watch是按数据变化暂停。

watch的作用:
告诉 GDB 持续监视某个变量(或表达式),只要它的值发生变化,就立刻中断程序执行,并显示旧值和新值。

典型场景:

  • 某个变量的值莫名其妙被修改,不知道在哪改的
  • 想要知道一个全局变量或关键局部变量何时被赋予新值
  • 代替在大量地方手动加printf来追踪变量变化

二、监视点的三种类型

GDB 根据监视的触发条件,将监视点分为三类:

类型命令触发条件
写监视点(watchpoint)watch 表达式当被监视的表达式的值被写入(修改)时触发
读监视点(read watchpoint)rwatch 表达式当被监视的表达式的值被读取时触发
读写监视点(access watchpoint)awatch 表达式当被监视的表达式的值被读取或写入时触发

最常用的是watch,也就是写监视点。今天重点掌握它。


三、如何使用 watch —— 完整流程演示

准备工作:写一个简单的测试程序

创建文件watch_demo.c:

#include<stdio.h>intsum=0;// 全局变量,方便全程监视voidadd(intn){sum+=n;// 这里会修改 sum}intmain(){inti;for(i=1;i<=3;i++){add(i);printf("After adding %d, sum = %d\n",i,sum);}return0;}

编译(必须加-g,建议不要优化):

gcc-g-O0watch_demo.c-owatch_demo

进入 GDB 并设置监视点

gdb ./watch_demo

1. 先给 main 函数设一个断点,确保程序跑起来后再设 watch
(因为 watch 要监视的变量必须存在于当前作用域)

(gdb) break main Breakpoint 1 at 0x...: file watch_demo.c, line ... (gdb) run Starting program: ./watch_demo Breakpoint 1, main () at watch_demo.c:12 12 for (i = 1; i <= 3; i++) {

2. 设置监视点:监视全局变量sum

(gdb) watch sum Hardware watchpoint 2: sum

“Hardware watchpoint” 表示系统使用硬件寄存器来监视,速度很快。

3. 继续运行程序

(gdb) continue Continuing.

程序会一直运行,直到sum的值发生变化。

4. 触发监视点
当第一次执行sum += n后,GDB 会突然暂停:

Hardware watchpoint 2: sum Old value = 0 New value = 1 add (n=1) at watch_demo.c:7 7 }

它告诉我们:

  • 监视点编号 2
  • sum的旧值是 0,新值变成了 1
  • 程序停在修改sum的那一行(实际上是add函数的第 7 行,即修改sum语句的结束)

此时你可以用print n查看参数,用backtrace查看调用栈。

5. 继续运行,观察每次变化

(gdb) continue Continuing. After adding 1, sum = 1 Hardware watchpoint 2: sum Old value = 1 New value = 3 add (n=2) at watch_demo.c:7 7 }

重复操作,每次sum被修改都会暂停,直到程序结束。


四、监视局部变量

如果监视的是局部变量,必须在它的作用域内设置 watch,并且一旦离开作用域,监视点会自动删除。

例子:监视main中的循环变量i。

(gdb) break main (gdb) run (gdb) watch i Hardware watchpoint 3: i (gdb) continue

但需要注意:当i在循环内频繁被修改,每次都会触发,可能过于频繁。如果只想在某个特定条件下暂停,可以用条件监视点(见后文)。


五、监视表达式

watch不仅可以监视单个变量,还可以监视任何合法的表达式。只要表达式的值发生变化,就会触发。

示例:监视sum + i(虽然这不太常用,但展示灵活性)

(gdb) watch sum + i

当sum或i任何一个变化导致sum + i的结果改变时,都会触发。

注意:复杂表达式可能无法使用硬件监视点,此时 GDB 会自动降级为软件监视点,软件监视点会让程序单步执行,非常慢,应尽量避免。


六、条件监视点

就像断点可以加条件一样,watch也可以加条件,只关心特定情况。

格式:

watch 变量 condition 监视点编号 条件

或者一步到位:

watch 变量 if 条件

示例:只监视sum被修改且新值大于 2 时才暂停。

(gdb) watch sum (gdb) condition 2 sum > 2

或者:

(gdb) watch sum if sum > 2

这样,当sum从 1 变到 3 时会触发(新值 3 > 2),但之前sum从 0 变到 1 时不会触发。


七、管理监视点

监视点和断点共用相同的编号体系,所以可以用管理断点的命令来管理监视点。

命令作用
info watchpoints或info breakpoints查看所有监视点和断点
delete 编号删除指定监视点/断点
disable 编号暂时禁用监视点
enable 编号启用监视点
ignore 编号 count忽略监视点触发 count 次(针对软件监视点)

示例:

(gdb) info breakpoints Num Type Disp Enb Address What 1 breakpoint keep y 0x... in main at watch_demo.c:12 2 hw watchpoint keep y sum (gdb) delete 2

就会删除对sum的监视。


八、硬件监视点 vs 软件监视点

  • 硬件监视点 (hw watchpoint)
    依赖处理器提供的调试寄存器,数量有限(一般 x86 有 4 个),但对程序运行速度几乎无影响。
  • 软件监视点 (sw watchpoint)
    当硬件监视点不够用或表达式复杂无法用硬件实现时,GDB 会使用软件监视点。其原理是每执行一条指令后都检查变量是否变化,导致程序运行极慢。如果看到Software watchpoint提示,要尽量简化监视表达式。

查看监视点类型:info breakpoints中 Type 列会显示hw watchpoint或watchpoint(软件)。


九、实战综合示例:追踪一个神秘错误

假设有一个程序,某个变量counter莫名被清零,我们可以这样调试:

(gdb) watch counter Hardware watchpoint 1: counter (gdb) run ... Hardware watchpoint 1: counter Old value = 100 New value = 0 0x... in some_function () at buggy.c:42

立刻就找到了清零的代码位置。


十、✅ watch 命令速查卡

命令简写作用示例
watch 变量wa 变量当变量被写入时暂停watch sum
rwatch 变量rw 变量当变量被读取时暂停rwatch flag
awatch 变量aw 变量当变量被读或写时暂停awatch status
watch 变量 if 条件-条件监视watch x if x > 10
info breakpointsi b列出所有监视点和断点i b
delete 编号d 编号删除监视点/断点d 2
disable 编号-禁用监视点disable 3
enable 编号-启用监视点enable 3

十一、练习(由易到难)

基础篇

  1. 使用上面的watch_demo.c程序,在 GDB 中对sum设置写监视点,运行并记录每次触发时的新值。
  2. 在同一个程序中,尝试对main中的局部变量i设置watch i,观察触发频率。然后删除该监视点。
  3. 使用awatch sum,观察程序是否在读取sum时也会暂停(如在printf中)。

进阶篇

  1. 编写一个小程序swap_test.c,内容如下:

    #include<stdio.h>voidswap(int*a,int*b){inttemp=*a;*a=*b;*b=temp;}intmain(){intx=5,y=10;printf("Before: x=%d, y=%d\n",x,y);swap(&x,&y);printf("After: x=%d, y=%d\n",x,y);return0;}

    在 GDB 中:

    • 对x设置写监视点(注意:x是main中的局部变量,需在进入main后设置)。
    • 运行程序,观察x是否在swap中被修改,GDB 会停在哪里?
    • 用backtrace查看调用栈。
  2. 对指针变量设置监视点:在swap函数内,对*a设置watch *a,观察它何时变化。

提高篇

  1. 编写一个程序,包含一个全局数组int data[10]。在循环中修改data[3]的值。在 GDB 中对data[3]设置写监视点(直接watch data[3])。注意观察,硬件监视点可能支持,但若提示软件监视点,解释原因并记录运行速度。
  2. 尝试条件监视:监视sum只在变为偶数时暂停(watch sum if sum % 2 == 0)。用之前的watch_demo.c验证。

十二、答案与关键点解析

基础篇

  1. 每次暂停输出新旧值,依次为 0→1, 1→3, 3→6。
  2. i每次循环变化都会触发,非常频繁。
  3. awatch sum会在printf读取sum时也触发(如果监视成功),通常硬件支持读写监视。

进阶篇

  1. 编译加-g -O0。watch x必须在main断点后设置。当执行swap(&x,&y)时,*a的修改会改变x,GDB 会停在*a = *b;或下一行。backtrace显示swap和main。
  2. 在swap函数内watch *a,会在*a = *b时触发,旧值 5,新值 10。

提高篇

  1. 对数组元素data[3]设置监视点通常可以用硬件监视点(如果支持)。若是软件监视点,运行会明显变慢。
  2. 条件监视:watch sum if sum % 2 == 0。当sum从 0 变 1(不触发),1 变 3(不触发),3 变 6(触发,因为新值 6 是偶数)。

十三、学习检查清单

  1. watch和break的根本区别是什么?
  2. 设置watch x后,什么时候程序会暂停?
  3. 如果监视的局部变量离开了作用域,会发生什么?
  4. 如何查看当前设置的所有监视点?如何删除一个监视点?
  5. 硬件监视点和软件监视点有什么区别?哪种更快?
  6. 怎样设置“只在新值为负数时才暂停”的监视点?

如果这些问题都能流畅回答,说明你已经把watch命令的核心用法完全吸收。现在,你可以用这把“变量监控刀”去精准地剖析任何程序中的数据变化。实际编程中,结合break、print和watch,你将拥有非常强大的调试能力。继续加油!

相关新闻

  • 2026年泉州民宿口碑榜:这5家山居度假首选,藏着最闽南的清凉夏天 - 热点速览
  • 2026甄选:重庆婚姻家事领域专业律师李西昀——专注离婚财产分割、子女抚养权与追回小三赠与款项 - 甄选服务推荐
  • 2026年上海及昆山地区叉车锂电池回收行情深度解析:价格区间与鉴别指南 - 生态测评师

最新新闻

  • 真力时官方售后服务中心电话和详细维修地址实地考察报告_多信源验证(2026年7月更新) - 亨得利官方服务中心
  • 2026 年7款标杆 CRM 拆解:产品亮点、落地场景与行业发展走向 - 企服数字化见闻
  • 5步掌握国家中小学智慧教育平台电子课本下载:教师必备的终极PDF获取指南
  • 【Pika视频生成实战指南】:零基础到日更爆款,2024最新V2.5模型参数调优全披露
  • RustDesk远程桌面解决方案:告别TeamViewer限制,打造完全自主可控的远程协作平台
  • 微信聊天记录导出终极指南:三步永久保存珍贵对话,打造专属AI数据库

日新闻

  • 百达翡丽官方服务项目及价格查询|维修地址与电话权威信息通告(2026年7月最新) - 百达翡丽服务中心
  • 2026年药食同源冲泡饮品哪家好:衡身堂三伏天内调外养 - 晚香时候
  • 芝柏官方更换原装表带价格查询|详细地址与24小时客服电话权威信息公告(2026年7月最新) - 亨得利官方服务中心

周新闻

  • SaaS软件行业GEO实践:AI搜索时代的品牌可见性与获客新路径
  • 什么是PCTFE?医药高端包装的“防潮王牌“材料
  • 【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号