Careful with PIDs

Quick question, what is the lowest Process ID you will find?  Most people (myself included until recently) would be able to say that the lowest number is 1 for the init process.  Plenty of programs including ps and pstree have this assumption.

This assumption bit me this week with Debian Bug 687829 where pstree on a kFreeBSD would not return and used 100% CPU.  What was happening? Well it seems that kFreeBSD has a process ID of 0 and pstree used 0 for a fake root to the tree.  So with a real and fake process #0 hanging around in pstree there was a strange parent-child circle (I’m my own grandad!) between init and process 0 meaning when the tree was walked things go around in circles.

The fix is basically to assume the tree starts at 0 and not 1 and that keeps things into perspective. So if you are wondering how inconsistent this goes, here is the list.

 

  • Linux has init  with PID 1 and PPID  0. There is no process 0
  • FreeBSD has init with PID 1 and PPID 0. Process 0 is kernel and exists and has PPID 0
  • Hurd has init at 1 with PPID 1. Process 0 is proc and has PPID 1

So Linux the root is init PID 1, FreeBSD it is kernel PID 0 and Hurd its init PID 1 with a child with PID 0.

 

Nothing like consistency! I do like the crazyness of Hurd where a child is created before a parent; nothing is normal in Hurd-land.

I have some temporary code going proving the problem with psmisc and FreeBSD, the tree now looks like what you can see below.  This fix will also show up processes “hidden” under init that were previously hiding.

?()-+-acpi_cooling0(16)
    |-acpi_thermal(15)
    |-audit(10)
    |-bufdaemon(18)
    |-flowcleaner(22)
    |-g_down(4)
    |-g_event(2)
    |-g_up(3)
    |-hald-runner(547)---hald-addon-storag(569)
    |-hald(546)-+-hald(548)---hald(549)
    |           `-hald-runner(547)---hald-addon-storag(569)
    |-hald(548)---hald(549)
    |-idle(11)
    |-init(1)-+-etc....

 

Enhanced by Zemanta

5 thoughts on “Careful with PIDs

  1. I remember back in the late ninties debugging the RedHat 5.2 root/boot discs, and finding that pid 0 (swapper) did exist. I needed to fake the parent task comm name to get the installer to work when not run as init (and did this by running from a fake “swapper”, IIRC). Modern procps appears to filter out pid 0. I’m not sure of the rationale behind hiding it.

    include/linux/init_task.h (INIT_TASK)
    init/init_task.c (init_task)

    Regards,
    Roger

    1. It seems there is a PID 0 in Linux, sort-of then. The point is procfs (not procps but the proc filesystem) doesn’t expose this process. I do recall seeing Linux crashing in the boot sequence in some horrible way mentioning it couldn’t find or start swapper but never connected it to PID 0.

  2. IIRC, the Hurd starts proc directly from Grub; init comes after.

Comments are closed.