James Hunt: Procenv and the Process Environment

Quiz

How many attributes of a processes "environment" can you think of besides its environment variables? I'm using the term "environment" in a very loose sense here to mean "any system or process level attribute that can be queried via system calls or library calls (or "/proc-picking") that affects a running process". I'm also including details of the process itself and details of the program that came to be a running process.

We're not talking about installed packages or application configuration files in /etc here, but purely low-level program, process and system meta-data.

I've got over 20 items in my list excluding environment variables.

Whilst you're pondering on that...

Compare and Contrast

If you've been involved with computers for any appreciable length of time, chances are you have come across the scenario where some program fails to run in a particular environment, but works "perfectly" in another (generally a developers cosy interactive shell environment).

Ignoring the fact that the development environment should always mirror the production environment as closely as possible, this problem tends to crop up in certain common scenarios. The two most common (from my observations) being:

system "services"

Such programs (often daemons of course) run -- and indeed should run -- in an exceedingly sparse environment: they get given just enough of an environment to do their job safely and efficiently.

And yes, I get asked quite a lot why some new Upstart job won't start, but runs in a desktop session environment "perfectly" :-)

build systems

Sometimes, the environment of such systems is quite different to what the developer expected. Maybe the build system is a virtualised or chrooted system, or it might be running on a host which has a different architecture to the expected one.

Environment

Back to the poser. How many have you got? Here's my list of "groups":

pid details.

session details.

credentials information.

password database details for user running the program.

groups user running application belongs to.

SELinux details.

CPU details.

scheduler details.

capabilities.

oom details.

cgroups.

stat details for the binary that is being run.

details of libraries that said binary has loaded.

compiler details for the binary being run.

uname details.

open file descriptors.

process limits.

system limits.

configuration-dependent limits.

timezone details.

clock details.

time details.

terminal details.

signal dispositions.

mount details.

networking details.

sizeof details.

ranges of standard system data types.

Procenv

The answer to the two posers above is procenv. This is a simple utility, licensed under the GPL, that essentially dumps every conceivable aspect of a processes environment (*) that it can (without needing super-user privs). It unashamedly emulates a number of existing system utilities as it is attempting to be all-encompassing: I wrote it with the aim of being able to dump "everything" that a process may care about by simply running a single program (by default). Also, the line of demarcation between "process", "program" and "system" is slightly blurry in some aspects (for example sysconf(3) variables could arguably be considered system attributes, but procenv shows these too since they are obviously meant to be querable by applications.

(*) - well, it doesn't currently query the network environment and I may have overlooked something, so patches are of course welcome!

Rationale

"But wait!" I hear you cry, "this procenv is redundant: I can get all the information I need from /proc!"

Well, that's half correct - you can get a lot of information out of /proc, but there are some caveats with that approach:

/proc might not be mounted.

/proc might not be readable (it could legitimately have permissions 0000).

the format and location of files in /proc may change in the future.

the format of certain files in /proc is sometimes extremely terse and cryptic.

As such, where possible, procenv uses system and library calls rather than grubbing around in /proc for the answers it needs since system calls and library calls don't generally change :-)

"Well, I could just write a shell script to massage the data in /proc into a consistent format, or just make use of other system utilities to produce an aggregated report" you say. Yes, you could do that, but procenv is striving to be cross-platform and additional to the /proc concerns, writing such a tool in shell comes with a bag of gotchas if it's going to work on anything but GNU Linux:

which shell are you going to support?

which version of standard utilities like (awk (or gawk or even nawk) are you going to support?

If you did write such a shell script, it could end up being somewhat of a monster if it was to work on all platforms and massage utility output to be consistent across these platforms.

Possible Uses

There are quite a few I suspect. Here are a few thoughts on some of the environments it could be run in to give a better understanding of what that enviroment is:

See what nohup(1) does to your process:

$ nohup procenv

See what shell back-grounding using does to your process:

$ procenv &

Exploring the environment available to you when you login to a system with restricted access (what has been restricted?)

Seeing the environment the kernel gives to the initramfs.Boot with options including something like:

rdinit=/usr/bin/procenv PROCENV_FILE=/dev/ttyS0 PROCENV_EXEC="/init"

Exploring the environment the initramfs gives to PID 1 aka "init"(aka Upstart for the majority of folks I hope ;-)

Copyright 2003-2015 GNOME-Look.org Team All rights reserved. GNOME-Look.org is not liable for any content or goods on this site.All contributors are responsible for the lawfulness of their uploads.GNOME and the foot logo are trademarks of the GNOME Foundation.