监视点
监视点
监视点的功能是监视一个表达式的值何时发生变化. 如果你从来没有使用过监视点, 请在GDB中体验一下它的作用.
简易调试器允许用户同时设置多个监视点, 删除监视点, 因此我们最好使用链表将监视点的信息组织起来. 框架代码中已经定义好了监视点的结构体(在nemu/include/monitor/watchpoint.h
中):
但结构体中只定义了两个成员: NO
表示监视点的序号, next
就不用多说了吧. 为了实现监视点的功能, 你需要根据你对监视点工作原理的理解在结构体中增加必要的成员. 同时我们使用"池"的数据结构来管理监视点结构体, 框架代码中已经给出了一部分相关的代码(在nemu/src/monitor/debug/watchpoint.c
中):
代码中定义了监视点结构的池wp_pool
, 还有两个链表head
和free_
, 其中head
用于组织使用中的监视点结构, free_
用于组织空闲的监视点结构, init_wp_pool()
函数会对两个链表进行了初始化.
实现了监视点池的管理之后, 我们就可以考虑如何实现监视点的相关功能了. 具体的, 你需要实现以下功能:
当用户给出一个待监视表达式时, 你需要通过
new_wp()
申请一个空闲的监视点结构, 并将表达式记录下来.每当
cpu_exec()
执行完一条指令, 就对所有待监视的表达式进行求值(你之前已经实现了表达式求值的功能了),比较它们的值有没有发生变化, 若发生了变化, 程序就因触发了监视点而暂停下来,
你需要将
nemu_state
变量设置为NEMU_STOP
来达到暂停的效果.最后输出一句话提示用户触发了监视点, 并返回到
ui_mainloop()
循环中等待用户的命令.使用
info w
命令来打印使用中的监视点信息, 至于要打印什么, 你可以参考GDB中info watchpoints
的运行结果.使用
d
命令来删除监视点, 你只需要释放相应的监视点结构即可.
断点
断点的功能是让程序暂停下来, 从而方便查看程序某一时刻的状态. 事实上, 我们可以很容易地用监视点来模拟断点的功能:
其中ADDR
为设置断点的地址. 这样程序执行到ADDR
的位置时就会暂停下来.
Last updated
Was this helpful?