What does a C process status mean in htop?

22.6k views Asked by At

I am using htop on osx and I can't seem to find out what a 'C' status in the 'S' status column means for a process status.

What does a C process status mean in htop?

3

There are 3 answers

1
Hisham H M On BEST ANSWER

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).

0
Homer6 On

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:

0
Alexander Shtuchkin On

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!