The apptrace utility is a C program which dynamically traces calls to Solaris library routines as an application runs. apptrace works on either SPARC or x86 platforms. apptrace can trace interface calls for both SPARC and x86 32-bit interfaces, as well as the 64-bit interfaces on SPARC. As with appcert, apptrace only examines C language interfaces.
After using appcert to determine an application is at risk of binary instability, apptrace helps assess the degree of risk in each case. To determine an application's binary compatibility with a given release, verify the successful use of each interface used by the application with apptrace.
The apptrace utility can verify that an application is using public interfaces correctly. For example, an application that is using the open() to open the administrative file /etc/passwd directly should instead use the appropriate programmatic interfaces. This ability to inspect the usage of the Solaris ABI enables easy and rapid identification of potential interface problems.
The apptrace utility does not require any modification of the application being traced. To use apptrace, type apptrace, followed by any desired options along with the command line used to run the application of interest. The apptrace utility works by using the link-auditing capability of the runtime linker to intercept the application's calls to Solaris library interfaces. The apptrace utility then traces the calls by printing the names and values of the call's arguments and return value. The tracing output can be on a single line or arranged across multiple lines for readability. Public interfaces are printed in human-readable form. Private interfaces are printed in hexadecimal.
The apptrace utility enables selective tracing of calls, both at the level of individual interfaces and the level of libraries. For example, apptrace can trace calls to printf() coming from libnsl, or a range of calls within a specific library. The apptrace utility can also verbosely trace user-specified calls. The specifications that dictate apptrace behavior are governed by a syntax that is consistent with the usage of truss(1). The -f option directs apptrace to follow forked child processes. The -o option specifies an output file for apptrace results.
The apptrace utility traces only library-level calls and is loaded into the running application process, gaining a performance increase over truss. With the exception of printf, apptrace cannot trace calls to functions that accept variable argument lists or examine the stack or other caller information, for example, setcontext, getcontext, setjmp, longjmp, and vfork.
The following examples contain sample apptrace output from tracing a simple one-binary application, ls.
% apptrace ls /etc/passwd ls -> libc.so.1:atexit(func = 0xff3cb8f0) = 0x0 ls -> libc.so.1:atexit(func = 0x129a4) = 0x0 ls -> libc.so.1:getuid() = 0x32c3 ls -> libc.so.1:time(tloc = 0x23918) = 0x3b2fe4ef ls -> libc.so.1:isatty(fildes = 0x1) = 0x1 ls -> libc.so.1:ioctl(0x1, 0x540d, 0xffbff7ac) ls -> libc.so.1:ioctl(0x1, 0x5468, 0x23908) ls -> libc.so.1:setlocale(category = 0x6, locale = "") = "C" ls -> libc.so.1:calloc(nelem = 0x1, elsize = 0x40) = 0x23cd0 ls -> libc.so.1:lstat64(path = "/etc/passwd", buf = 0xffbff6b0) = 0x0 ls -> libc.so.1:acl(pathp = "/etc/passwd", cmd = 0x3, nentries = 0x0, aclbufp = 0x0) = 0x4 ls -> libc.so.1:qsort(base = 0x23cd0, nel = 0x1, width = 0x40, compar = 0x12038) ls -> libc.so.1:sprintf(buf = 0x233d0, format = 0x12af8, ...) = 0 ls -> libc.so.1:strlen(s = "") = 0x0 ls -> libc.so.1:strlen(s = "/etc/passwd") = 0xb ls -> libc.so.1:sprintf(buf = 0x233d0, format = 0x12af8, ...) = 0 ls -> libc.so.1:strlen(s = "") = 0x0 ls -> libc.so.1:printf(format = 0x12ab8, ...) = 11 ls -> libc.so.1:printf(/etc/passwd format = 0x12abc, ...) = 1 ls -> libc.so.1:exit(status = 0)
The previous example shows the default tracing behavior, tracing every library call on the command ls /etc/passwd. The apptrace utility prints a line of output for every system call, indicating:
The name of the call
The library the call is in
The arguments and return values of the call
The output from ls is mixed in with the apptrace output.
% apptrace -t \*printf ls /etc/passwd ls -> libc.so.1:sprintf(buf = 0x233d0, format = 0x12af8, ...) = 0 ls -> libc.so.1:sprintf(buf = 0x233d0, format = 0x12af8, ...) = 0 ls -> libc.so.1:printf(format = 0x12ab8, ...) = 11 ls -> libc.so.1:printf(/etc/passwd format = 0x12abc, ...) = 1
The previous example shows how apptrace can selectively trace calls with regular-expression syntax. In the example, calls to interfaces ending in printf, which include sprintf, are traced in the same ls command as before. Consequently, apptrace only traces the printf and sprintf calls.
% apptrace -v sprintf ls /etc/passwd ls -> libc.so.1:sprintf(buf = 0x233d0, format = 0x12af8, ...) = 0 buf = (char *) 0x233d0 "" format = (char *) 0x12af8 "%s%s%s" ls -> libc.so.1:sprintf(buf = 0x233d0, format = 0x12af8, ...) = 0 buf = (char *) 0x233d0 "" format = (char *) 0x12af8 "%s%s%s" /etc/passwd
The previous example shows the verbose tracing mode, where the arguments to sprintf are printed on multiple output lines for readability. At the end, apptrace displays the output of the ls command.