The Oracle Solaris operating system provides two tools, the Preflight Checker tool and the apptrace tool to verify that an application's use of Oracle Solaris interfaces conforms to the Oracle Solaris ABI. The ABI tools enable easy, rapid identification of binaries that might have binary compatibility problems with a given Oracle Solaris release.
You can use the Preflight Checker tool to check the readiness of an application on Oracle Solaris 10. The Preflight Checker tool checks the application source code and application process running on Oracle Solaris 10 to determine if the application can run unmodified on Oracle Solaris 11. This tool also statically examines the Oracle Solaris library interfaces used by ELF binaries for instances of private interface usage. The Preflight Checker tool produces summary and detailed reports of any potential binary stability problems it finds. It identifies which binaries use problematic interfaces and which do not. For more information about Preflight Checker Tool, see Oracle Solaris Preflight Applications Checker 11.3.
You can use the apptrace tool on the target Oracle Solaris release for verification. This verifies whether interface compatibility problems exist by enabling dynamic observation of those interfaces as they are used. The apptrace tool uses the link-auditing capability of the run-time linker to dynamically trace Oracle Solaris library routine calls as the application runs. This capability enables developers to examine an application's use of the Oracle Solaris system interfaces.
The apptrace utility is a C program which dynamically traces calls to Oracle 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. The apptrace only examines C language interfaces.
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 Oracle 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 the apptrace utility, 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 Oracle 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. The –f option directs apptrace to follow forked child processes. The –o option specifies an output file for apptrace results. For more information, see the truss(1) man page.
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.Example 51 Tracing in Default Mode
$ 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.Example 52 Tracing Selectively
$ 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.Example 53 Tracing in Verbose Mode
$ 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.