What does a C process status mean in htop?

I've got the same question recently. We can try to look it up in the htop sources:

process->state =
    ProcessList_decodeState( p->p_stat == SZOMB ? SZOMB : ki->state );

static int
ProcessList_decodeState( int st ) {
  switch ( st ) {
  case SIDL:
    return 'C';
  case SRUN:
    return 'R';
  case SSLEEP:
    return 'S';
  case SSTOP:
    return 'T';
  case SZOMB:
    return 'Z';
  default:
    return '?';
  }
}

So we go to Unix definition of process states at /usr/include/sys/proc.h:

/* Status values. */
#define SIDL    1       /* Process being created by fork. */
#define SRUN    2       /* Currently runnable. */
#define SSLEEP  3       /* Sleeping on an address. */
#define SSTOP   4       /* Process debugging or suspension. */
#define SZOMB   5       /* Awaiting collection by parent. */

So, 'C' status is meant to be 'Process being created by fork'. What is it? According to old unix sources, it's a transient state that happens when there's not enough memory when forking a process and the parent needs to be swapped out.

What??

Back to htop source. Where do we get the ki->state?

// For all threads in process:
error = thread_info( ki->thread_list[j], THREAD_BASIC_INFO,
                     ( thread_info_t ) & ki->thval[j].tb,
                     &thread_info_count );

tstate = ProcessList_machStateOrder( ki->thval[j].tb.run_state,
                                     ki->thval[j].tb.sleep_time );
if ( tstate < ki->state )
  ki->state = tstate;

// Below...
static int
ProcessList_machStateOrder( int s, long sleep_time ) {
  switch ( s ) {
  case TH_STATE_RUNNING:
    return 1;
  case TH_STATE_UNINTERRUPTIBLE:
    return 2;
  case TH_STATE_WAITING:
    return ( sleep_time > 20 ) ? 4 : 3;
  case TH_STATE_STOPPED:
    return 5;
  case TH_STATE_HALTED:
    return 6;
  default:
    return 7;
  }
}

// In mach/thread_info.h: 
#define TH_STATE_RUNNING  1 /* thread is running normally */
#define TH_STATE_STOPPED  2 /* thread is stopped */
#define TH_STATE_WAITING  3 /* thread is waiting normally */
#define TH_STATE_UNINTERRUPTIBLE 4  /* thread is in an uninterruptible wait */
#define TH_STATE_HALTED   5 /* thread is halted at a clean point */

We have the following (messed up) mapping:

Thread state             | Mapped to | htop state| 'top' state | 'ps' state
---------------------------------------------------------------------------- 
TH_STATE_RUNNING         | SIDL(1)   |       'C' | running     | 'R'
TH_STATE_UNINTERRUPTIBLE | SRUN(2)   |       'R' | stuck       | 'U'
TH_STATE_WAITING (short) | SSLEEP(3) |       'S' | sleeping    | 'S'
TH_STATE_WAITING (long)  | SSTOP(4)  |       'T' | idle        | 'I'
TH_STATE_STOPPED         | SZOMB(5)  |       'Z' | stopped     | 'T'

So, the real answer is: 'C' means that the process is currently running.

How did it happen? Seems that the ki->state handling was borrowed from ps source and wasn't adjusted for Unix process codes.

Update: this bug is fixed. Yay open source!


Here are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe the state of a process:

  • D Uninterruptible sleep (usually IO)
  • R Running or runnable (on run queue)
  • S Interruptible sleep (waiting for an event to complete)
  • T Stopped, either by a job control signal or because it is being traced.
  • W Paging (not valid since the 2.6.xx kernel)
  • X Dead (should never be seen)
  • Z Defunct ("zombie") process, terminated but not reaped by its parent.

Source: man ps

I recently came across a second list:

  • R Running
  • S Sleeping in an interruptible wait
  • D Waiting in uninterruptible disk sleep
  • Z Zombie
  • T Stopped (on a signal) or (before Linux 2.6.33) trace stopped
  • t Tracing stop (Linux 2.6.33 onward)
  • W Paging (only before Linux 2.6.0)
  • X Dead (from Linux 2.6.0 onward)
  • x Dead (Linux 2.6.33 to 3.13 only)
  • K Wakekill (Linux 2.6.33 to 3.13 only)
  • W Waking (Linux 2.6.33 to 3.13 only)
  • P Parked (Linux 3.9 to 3.13 only)

http://man7.org/linux/man-pages/man5/proc.5.html in the "/proc/[pid]/stat" section:


htop author here. I am not aware of such status code in the htop codebase. Keep in mind that htop is written for Linux only, so there is no support for macOS/OSX. When I hear of people running it on OSX they are often using an outdated, unsupported fork (the latest version of htop is 2.0.1, including macOS support).

Tags:

Macos

Htop