OpenSolaris

You are not signed in. Sign in or register.

libproc

The libproc library was created back in 1997 to address the fact that we had far too many tools (truss, gcore, as well as the ptools ) implementing the same functionality on top of procfs. For all its power, /proc can be incredibly complicated to use (just take a look at Psyscall() to see how tricky the agent LWP can be). On top of that, understanding process layout (symbol tables, memory mappings, etc) requires semantic knowledge of ELF files that doesn't exist within /proc. libproc also allows transparent access to both live processes and core files through the same interfaces, although there are obviously some things you cannot do with corefiles.

To that end, libproc has grown organically over the years, as we continually add common functionality into the library. The upside of this is that we have a single repository where every process-related behavior takes place. The downside is that some of the interfaces are esoteric at best, and incredibly difficult to understand. Because of this, the interfaces are currently consolidation-private, which means that no tools outside of ON can make use of them (there are actually a few that have a contract interface, but it's effectively private). We would really like to release the API as a public interface, but everyone acknowledges that the current interface is so horrendous it could never be shipped.

With that said, this page will serve as a libproc tutorial for those looking to build more interesting tools on top of the base functionality. Before proceeding further, I'll say it again:

If your application consumes libproc interfaces, it may break at any point

If you're still interested in using libproc, then please read on. If you're interested in helping create a usable libproc interface, please contact one of the community leaders or post a message in the discussion forum. On our list of things to do is razing libproc to the ground and rebuilding it anew, but we simply don't have the resources at the moment.

Finding the Source

The source for libproc can be found in usr/src/lib/libproc. As with most Solaris libraries, you'll find the bulk of the source in the 'common' directory, with 'Pisadep.c' living in the appropriate ISA-specific directory. The files beginning with 'P' implement target-specific functions. Those beginning with 'pr_' are convenience wrappers around Psyscall(). Finally, those that begin with 'proc_*' are utility routines that do not require a specific target.

Note that libproc.h is not currently shipped with Solaris. We install it as part of the build process, but do not ship it to customers. This was done to discourage people from depending on these interfaces, but during the course of Solaris 10 we've shipped a number of otherwise private interfaces (i.e. libctf.h) as header files. The reasoning behind this is that the proper way to designate stability is through the use of manpages and attributes(5). Unless we document something as stable, then you have no right to complain when it breaks unexpectedly.

Grabbing a process

Before you can use the majority of libproc interfaces, you must obtain a ps_prochandle reference to the process, core, or executable. Before we get too much further, we should point out the process states documented in libproc.h:

/* State values returned by Pstate() */
#define PSRUN          1       /* process is running */
#define PSSTOP         2       /* process is stopped */
#define PSLOST         3       /* process is lost to control (EAGAIN) */
#define PSUNDEAD       4       /* process is terminated (zombie) */
#define PSDEAD         5       /* process is terminated (core file) */
#define PSIDLE         6       /* process has not been run */

You will note that we can grab both live processes (PSRUN, PSSTOP, PSUNDEAD), core files (PSDEAD) and processes executables (PS_IDLE). Each of these has their appropriate related function:

TargetFunction
live processPgrab
core filePfgrab_core
executablePgrab_file

If you are developing an application that works on multiple file types, you should use the procarggrab() interface.

Controlling processes

XXX

Examining process state

XXX

Using the Agent LWP

XXX