Go to main content
Oracle® Developer Studio 12.6: Debugging a Program with dbx

Exit Print View

Updated: June 2017
 
 

Setting Filters on Breakpoints

In dbx, most of the event management commands also support an optional event filter modifier. The simplest filter instructs dbx to test for a condition after the program arrives at a breakpoint or trace handler, or after a data change breakpoint occurs.

If this filter condition evaluates to true (non 0), the event command applies and program execution stops at the breakpoint. If the condition evaluates to false (0), dbx continues program execution as if the event had never happened.

To set a breakpoint that includes a filter , add an optional- if condition modifier statement to the end of a stop or trace command.

The condition can be any valid expression, including function calls, returning Boolean or integer in the language current at the time the command is entered.

With a location-based breakpoint like in or at, the scope for parsing the condition is that of the breakpoint location. Otherwise, the scope of the condition is the scope at the time of entry, not at the time of the event. You might have to use the backquote operator (see Backquote Operator) to specify the scope precisely.

The following two filters are not the same:

stop in foo -if a>5
stop cond a>5

The former breaks at foo and tests the condition. The latter automatically single steps and tests for the condition.

Qualifying Breakpoints With Conditional Filters

To set a breakpoint that includes a filter, add an optional -if condition modifier statement to the end of a stop or trace command. The condition can be any valid expression, including function calls, returning Boolean or integer in the language current at the time the command is entered.

You can use a function call as a breakpoint filter. In this example, if the value in the string str is abcde, then execution stops in function foo():

(dbx) stop in foo -if !strcmp(“abcde”,str)

You can use the –if option with function calls:

stop in lookup –if strcmp(name, "troublesome")==0

The following is an example of using a conditional filter with a watchpoint:

(dbx) stop access w &speed -if speed==fast_enough

Qualifying Breakpoints With Caller Filters

Inexperienced users sometimes confuse setting a conditional event command (a watch-type command) with using filters. Conceptually, “watching” creates a precondition that must be checked before each line of code executes (within the scope of the watch). But even a breakpoint command with a conditional trigger can also have a filter attached to it.

Consider this example:

(dbx) stop access w &speed -if speed==fast_enough

This command instructs dbx to monitor the variable, speed; if the variable speed is written to (the “watch” part), then the -if filter goes into effect. dbx checks whether the new value of speed is equal to fast_enough. If it is not, the program continues, “ignoring” the stop command.

In dbx syntax, the filter is represented in the form of an [-if condition] statement at the end of the command.

stop in function [-if condition]

Consider a simple example, in which you have code like the following:

44:     if(open(filename, ...) == -1)
45:          return "Error";

You can stop on a specific failure, for example ENOENT of open() with the following command:

(dbx) stop at 45 -if errno == 2

Filters can be convenient when you are placing a data change breakpoint on a local variable. In the following example, the current scope is in function foo(), while index, the variable of interest, is in function bar().

(dbx) stop access w &bar`index -in bar

bar`index ensures that the index variable in function bar() is picked up, instead of the index variable in function foo or a global variable named index.

    -in bar implies the following:

  • The breakpoint is automatically enabled when function bar() is entered.

  • The breakpoint remains enabled for the duration of bar() including any functions it calls.

  • The breakpoint is automatically disabled upon return from bar().

The stack location corresponding to index might be reused by some other local variable of some other function. -in ensures that the breakpoint is triggered only when bar`index is accessed.

Filters and Multithreading

If you set a breakpoint with a filter that contains function calls in a multithreaded program, dbx stops execution of all threads when it hits the breakpoint and then evaluates the condition. If the condition is met and the function is called, dbx resumes all threads for the duration of the call.

For example, you might set the following breakpoint in a multithreaded application where many threads call lookup():

(dbx) stop in lookup -if strcmp(name, “troublesome”) == 0

dbx stops when thread t@1 calls lookup(), evaluates the condition, and calls strcmp() resuming all threads. If dbx hits the breakpoint in another thread during the function call, it issues a warning such as one of the following:

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:
...

In such a case, if you can ascertain that the function called in the conditional expression will not grab a mutex, you can use the -resumeone event specification modifier to force dbx to resume only the first thread in which it hit the breakpoint. For example, you might set the following breakpoint:

(dbx) stop in lookup -resumeone -if strcmp(name, “troublesome”) == 0

    The -resumeone modifier does not prevent problems in all cases. For example, it would not help in the following circumstances:

  • The second breakpoint on lookup() occurs in the same thread as the first because the condition recursively calls lookup().

  • The thread on which the condition runs relinquishes control to another thread.

For more information, see Event Specification Modifiers.