trc_find_first, trc_find_next, or trc_compare Subroutine

Purpose

Finds the first, or next, occurrence of the argument, or compares the current entry with the argument.

Library

libtrace.a

Syntax

#include <sys/libtrace.h>

int trc_find_first (handle, argp, ret)
trc_log_handle_t handle;
trc_logsearch_t *argp;
trc_read_t *ret;

int trc_find_next (handle, argp, ret)
trc_log_handle_t handle;
trc_logsearch_t *argp;
trc_read_t *ret;
int trc_compare (handle, argp)
trc_log_handle_t handle;
trc_logsearch_t *argp;

Description

The trc_find_first subroutine finds the first occurrence of the trace log entry matching the argument pointed to by the argp parameter. The trc_find_next subroutine finds the next occurrence of the argument starting from the current position in the log object. If the search argument pointer, argp, is NULL, the argument from the previous search is used. Both the trc_find_first and trc_find_next subroutines return the item found. If the flag field of the handle contains both TRC_MULTI_MERGE and TRC_REMOVE_DUPS, trc_find_first and trc_find_next will consume any duplicate entries of the current event that exist from other trace sources. The number of entries consumed will be returned in the trchi_dupcount or trcri_dupcount variable (depending on whether processed or raw data items, respectively, are requested).

The trc_compare subroutine is used to check the current entry against the argument. No data is read. It is useful when implementing exit criteria, where you need to find entries according to some criteria, but then check for an exit criteria which is not part of the normal search.

Parameters

Item Description
handle Contains the handle returned from a successful call to the trc_open subroutine.
argp Points to the argument list as defined in the /usr/include/sys/libtrace.a file. Arguments may be chained together to perform complex searches.
ret Points to the trc_read_t structure to be returned. The trc_free subroutine should be used to free data referenced from the trc_read_t data type, unless TRC_LOGLIVE was specified at open time.

The search argument consists of three parts, the operator, tls_op, and the left and right sides.

The operator values can be easily identified, because they have the form TLS_OP_.... Operators are split into two categories, leaf and compound operators. Leaf operators are operators that compare the field on the left with the value on the right. Compound operators are used to compare two expressions, (for example) to combined expressions.

Leaf operations may be performed using numeric or string data. If performed on string data, the strcmp libc string compare function is used to do the comparison for all operators except TLS_OP_SUBSTR. The valid leaf operators are:
Item Description
TLS_OP_EQUAL Exactly equal
TLS_OP_NE Not equal
TLS_OP_LT Less than
TLS_OP_LE Less than or equal
TLS_OP_GT Greater than
TLS_OP_GE Greater than or equal
TLS_OP_SUBSTR The string on the left contains the string on the right.
The compound operators are:
Item Description
TLS_OP_AND The logical AND of the results of the left and right expressions.
TLS_OP_OR The logical OR of the results of the left and right expressions.
TLS_OP_XOR The exclusive or of the results of the left and right expressions.
TLS_OP_NOT The negation of the argument referenced by tls_left.
The left and right sides of the expression are defined as follows:
Item Description
tls_left and tls_right These are used when the operator requires the left and right sides to be an expression, (for example) when it is a compound operator. tls_left and tls_right point to other trc_logsearch_t structures.
tls_field and corresponding values For a leaf operation, tls_field, on the left, specifies the field to be compared. The field names can be identified easily, because they all have the form TLS_MATCH_.... The righthand side is a value specified according to the data type of the field on the left.
The following table shows the lefthand field values and their corresponding righthand side data values:
Field Value Description
TLS_MATCH_HOOKID tls_ushortvalue Compare the hook ID with a ushort data item. Only a 3-digit hook ID can be used. Beginning with AIX® 6.1 where 4-digit hook IDs are available, arguments are left-shifted by 4 to create a 4-digit hook ID. For example, to specify the hook ID 0x1000, specify 0x100. To specify the hook ID 0x00F0, specify 0x00F. Thus, only 4-digit hook IDs in the form of 0xhhh0 can be specified where h is a hexadecimal digit. To specify any 4-digit hook ID, use TLS_MATCH_HOOKID64.
TLS_MATCH_HOOKID64 tls_ushortvalue Valid beginning with AIX 6.1. Compare the hook ID with a ushort data item. All hook IDs are assumed to be 4-digit hook IDs.
TLS_MATCH_HOOK_AND_SUBHOOK tls_uintvalue Compare the hook and subhook. Use 32 bits with the specified integer. The field is in the form of 0xhhhhssss, where hhhh is the hook ID (and can optionally be hhh0), and ssss is the subhook.
TLS_MATCH_HOOKSET tls_hooksetvalue The bitmap specifies the hooks to be tested for. You can test for multiple hooks with one search argument. The bit map is manipulated with the trc_hkemptyset, trc_hkfillset, trc_hkaddset, and trc_hkdelset subroutines. Beginning with AIX 6.1, 16-bit hook IDs are available. However, trc_hookset_t can only specify 12-bit hook IDs. By specifying hook 0xhhh, the trc_find_first and trc_find_next subroutines search for 0xhhh0 because the two values are equivalent beginning with AIX 6.1. To specify hooks in the form of 0xhhhh, use TLS_MATCH_HOOKSET64.
TLS_MATCH_HOOKSET64 tls_hooksetvalue Valid beginning with AIX 6.1. The bitmap specifies the hook IDs to be tested for. You can test for multiple 16-bit hooks with one search argument. The bit map is manipulated with the trc_hkemptyset64, trc_hkfillset64, trc_hkaddset64, and trc_hkdelset64 subroutines.
TLS_MATCH_TIME tls_ulongvalue Compare the time value in nanoseconds from the start of the trace.
TLS_MATCH_TID tls_ulongvalue Thread ID
TLS_MATCH_PID tls_ulongvalue Process ID
TLS_MATCH_RAWOFST tls_ulongvalue Raw file offset
TLS_MATCH_CPUID tls_uintvalue Processor ID
TLS_MATCH_RCPU tls_uintvalue Remaining processors in the trace
TLS_MATCH_FLAGS tls_uintvalue Compare with trcr_flags.
TLS_MATCH_TICKS tls_ulongvalue Match with the number of timer register ticks since the start of the trace.
TLS_MATCH_TRCONTIME tls_ulongvalue Compare with trchi_trcontime.
TLS_MATCH_TRCOFFTIME tls_ulongvalue Compare with trchi_trcofftime.
TLS_MATCH_COMPONENT tls_strvalue Match a specific component name.

Return Values

Upon successful completion, the trc_find_first, trc_find_next, and trc_compare subroutines return 0.

Error Codes

Upon error, the errno global variable is set to a value from the errno.h file. The trc_find_first, trc_find_next, and trc_compare subroutines return either a value from the errno.h file, or an error value from the libtrace.h file.
Item Description
EINVAL The handle is invalid, or the search argument is invalid.
TRCE_EOF No matching item was found, or no more matching items exist. The errno global variable is set to 0.
TRCE_BADFORMAT The log object contains badly formatted data. The errno global variable is set to EINVAL.

Examples

  1. Find the SVC hooks, 101 and 104, for program mypgm.
    {
                      int rv;
                      trc_loghandle_t h;
                      trc_read_t r;
                      trc_logsearch_t t1, t2, t3, t4, t5;
    
                      /* Setup the leaf search arguments. */
                      t1.tls_op = TLS_OP_EQUAL;
                      t1.tls_field = TLS_MATCH_HOOKID;
                      t1.tls_ushortvalue = 0x101;
                      t2.tls_op = TLS_OP_EQUAL;
                      t2.tls_field = TLS_MATCH_HOOKID;
                      t2.tls_ushortvalue = 0x104;
                      t3.tls_op = TLS_OP_EQUAL;
                      t3.tls_field = TLS_MATCH_PROCNAME;
                      t3.tls_strvalue = "mypgm";
                      /* Join the items and form a single search tree. */
                      t4.tls_op = TLS_OP_AND;
                      t4.tls_left = &t1
                      t4.tls_right = &t2
                      t5.tls_op = TLS_OP_AND;
                      t5.tls_left = &t4
                      t5.tls_right = &t3
                      /* Open the default trace log object. */
                      rv = trc_open("", "", TRC_LOGREAD|TRC_LOGPROC, >h);
                      if (rv) {
                              trc_perror(h, rv, "open");
                              return(rv);
                      }
                      /* Do the search. */
                      rv = trc_find_first(h, &t5, &r);
                      if (rv) {
                              trc_perror(h, rv, "find test");
                              return(rv);
                      }
    
                      ...
              }
    Note that subsequent entries matching this search could be returned with the following:
    rv = trc_find_next(h, NULL, &r);

    After a find, trc_find_next can be used to change the search argument without starting the search over. In other words, trc_find_first always starts from the beginning of the file, while trc_find_next starts from the current position in the file, but either one can change the search argument.

  2. Find the SVC hooks, 101 and 104, for program mypgm. Use a single argument to search for both hook ids.
    {
                      int rv;
                      trc_loghandle_t h;
                      trc_read_t r;
                      trc_logsearch_t t1, t2, t3;
                      trc_hookset_t hs;
    
                      /* Setup the hook set. */
                      trc_hkemptyset(hs);
                      (void)trc_hkaddset(hs, 0x101);
                      (void)trc_hkaddset(hs, 0x104);
                      /* Setup the leaf search arguments. */
                      t1.tls_op = TLS_OP_EQUAL;
                      t1.tls_field = TLS_MATCH_HOOKSET;
                      t1.tls_hooksetvalue = hs;
                      t2.tls_op = TLS_OP_EQUAL;
                      t2.tls_field = TLS_MATCH_PROCNAME;
                      t2.tls_strvalue = "mypgm";
                      /* Join the items and form a single search tree. */
                      t3.tls_op = TLS_OP_AND;
                      t3.tls_left = &t1
                      t3.tls_right = &t2
                      /* Open the default trace log object. */
                      rv = trc_open("", "", TRC_LOGREAD|TRC_LOGPROC, &h);
                      if (rv) {
                              trc_perror(h, rv, "open");
                              return(rv);
                      }
                      /* Do the search. */
                      rv = trc_find_first(h, &t3, &r);
                      if (rv) {
                              trc_perror(h, rv, "find test");
                              return(rv);
                      }
    
                      ...
              }
  3. You can find hooks 101, 104 and 1AB1 for program mypgm using the trc_hookset64_t type. Hooks 101 and 104 are equal to 0x1010 and 0x1040.
    {
                      int rv;
                      trc_loghandle_t h;
                      trc_read_t r;
                      trc_logsearch_t t1, t2, t3;
                      trc_hookset64_t hs;
    
                      /* Setup the hook set. */
                      trc_hkemptyset64(hs);
                      (void)trc_hkaddset64(hs, 0x1010);
                      (void)trc_hkaddset64(hs, 0x1040);
                      (void)trc_hkaddset64(hs, 0x1AB1);
    
                      /* Setup the leaf search arguments. */
                      t1.tls_op = TLS_OP_EQUAL;
                      t1.tls_field = TLS_MATCH_HOOKSET64;
                      t1.tls_hooksetvalue = hs;
                      t2.tls_op = TLS_OP_EQUAL;
                      t2.tls_field = TLS_MATCH_PROCNAME;
                      t2.tls_strvalue = "mypgm";
                      /* Join the items and form a single search tree. */
                      t3.tls_op = TLS_OP_AND;
                      t3.tls_left = &t1
                      t3.tls_right = &t2
                      /* Open the default trace log object. */
                      rv = trc_open("", "", TRC_LOGREAD|TRC_LOGPROC, &h);
                      if (rv) {
                              trc_perror(h, rv, "open");
                              return(rv);
                      }
                      /* Do the search. */
                      rv = trc_find_first(h, &t3, &r);
                      if (rv) {
                              trc_perror(h, rv, "find test");
                              return(rv);
                      }
    
                      . . .
              }