新用户有时会将设置条件事件命令(监视类型命令)与使用过滤器混淆。从概念上来说,“监视”会创建在执行每行代码前必须检查的前提条件(在监视的作用域内)。但即便是有条件触发的断点命令也可以连接过滤器。
假设有这样一个示例:
(dbx) stop access w &speed -if speed==fast_enough |
此命令指示 dbx 监视变量 speed;如果变量 speed 已写入(“监视”部分),则 -if 过滤器生效。dbx 检查 speed 的新值是否等于 fast_enough。如果不等,程序会继续执行,而“忽略”stop 命令。
在 dbx 语法中,过滤器以命令末尾处的 [-if condition] 形式表示。
stop in function [-if condition] |
如果在多线程程序中设置的断点中使用了包含多个函数调用的过滤器,dbx 将在到达断点时停止所有线程的执行,然后对条件求值。如果满足条件且调用了函数, dbx 便会恢复执行调用期间内的所有线程。
例如,可以在多线程应用程序中许多线程调用 lookup() 之处设置以下断点:
(dbx) stop in lookup -if strcmp(name, “troublesome”) == 0 |
dbx 会在线程 t@1 调用 lookup() 时停止,并对条件求值,然后调用恢复所有线程的 strcmp()。如果在函数调用期间 dbx 在另一个线程中遇到断点,便会发出警告,例如:
event infinite loop causes missed events in the following handlers: ... |
Event reentrancy first event BPT(VID 6m TID 6, PC echo+0x8) second event BPT*VID 10, TID 10, PC echo+0x8) the following handlers will miss events: ... |
在这种情况下,如果可以确定条件表达式中调用的函数不会抓取互斥锁,则可使用 -resumeone 事件规范修饰符强制 dbx 只恢复在其中遇到断点的第一个线程。例如,可设置以下断点:
(dbx) stop in lookup -resumeone -if strcmp(name, “troublesome”) == 0 |
在有些情况下,-resumeone 修饰符并不能防止出现问题。例如,它在下列情况下便无能为力:
由于条件以递归方式调用 lookup(),所以 lookup() 上的第二个断点与第一个断点出现在同一个线程中。
运行条件的线程放弃控制权,将其交给另一个线程。
有关事件修饰符的详细信息,请参见事件规范修饰符。