This example demonstrates the "umbrella" feature of Aprobe. Umbrellas are used for making conditional probes. You simply nest one probe inside of another.
We call the parent probe an "umbrella". Nested probes are inactive until the parent probe activates them (automatically). The nested probes have the same life span as the entity to which their parent (umbrella) probe is applied, just like any variables that may be declared inside of a probe.
Sometimes umbrellas are required. For instance, all subprogram probes must be nested "under the umbrella" of either another subprogram probe or a thread probe.
Nested probes are discussed in Chapter 3, "Nesting of Probes". See also the Advanced\Fault_Injection and Advanced\Disable_Probe examples.
Suppose we want to probe some calls to printf(), but we are only interested in those calls to printf() that occur while the target program's execution is nested somewhere inside of any call to subprogram SayHello(). In other words, we don't want to probe any calls to printf() from elsewhere in the program. Here is how we do that:
Hello.apc
probe thread // probe thread doesn't have to be nested
{
probe "SayHello" // all subprogram probes must be nested
{
probe extern:"printf()"
{
on_entry
ap_LogTraceback(99);
}
}
}
The probe on SayHello() is active for the entire duration of each thread (including the main program thread).
The probe on printf() is active only during any call to SayHello(), whether or not printf() was called by SayHello() itself. The important point is that SayHello() must be somewhere in the call stack when printf() was called. Calls to printf() that are made from outside of calls to SayHello() will not be patched by this probe. It's as if the probe on printf() doesn't exist until SayHello() was called.
Effective use of "umbrella" probes helps to filter out unwanted data and reduce the amount of data collected.
Traceback:
---------------------------------------------------------
extern:"printf()"
==> "hello.c":"SayHello()" at line 9 (hello.c)
==> extern:"main()" at line 23 (hello.c)
==> extern:"mainCRTStartup()" + 0x00b4
---------------------------------------------------------
Note that even though printf() was called multiple times in our program, the probe only logged one traceback. This was the call made from SayHello(), due to the "umbrella" probe.