Linux: change how kernel threads are detected

Use the same method that ps and top use to determine if a
process is a kernel thread on Linux: check if cmdline is empty.

Thanks to @wangqr's investigation reported here:
https://github.com/hishamhm/htop/issues/761#issuecomment-375306069

Fixes #761.
This commit is contained in:
Hisham Muhammad 2018-03-25 15:26:05 -03:00
parent dc050e8088
commit 47cf1532b0
3 changed files with 8 additions and 6 deletions

View File

@ -93,6 +93,7 @@ typedef enum LinuxProcessFields {
typedef struct LinuxProcess_ { typedef struct LinuxProcess_ {
Process super; Process super;
bool isKernelThread;
IOPriority ioPriority; IOPriority ioPriority;
unsigned long int cminflt; unsigned long int cminflt;
unsigned long int cmajflt; unsigned long int cmajflt;
@ -142,7 +143,7 @@ typedef struct LinuxProcess_ {
} LinuxProcess; } LinuxProcess;
#ifndef Process_isKernelThread #ifndef Process_isKernelThread
#define Process_isKernelThread(_process) (_process->pgrp == 0) #define Process_isKernelThread(_process) ((LinuxProcess*)(_process)->isKernelThread)
#endif #endif
#ifndef Process_isUserlandThread #ifndef Process_isUserlandThread

View File

@ -85,6 +85,7 @@ typedef enum LinuxProcessFields {
typedef struct LinuxProcess_ { typedef struct LinuxProcess_ {
Process super; Process super;
bool isKernelThread;
IOPriority ioPriority; IOPriority ioPriority;
unsigned long int cminflt; unsigned long int cminflt;
unsigned long int cmajflt; unsigned long int cmajflt;
@ -134,7 +135,7 @@ typedef struct LinuxProcess_ {
} LinuxProcess; } LinuxProcess;
#ifndef Process_isKernelThread #ifndef Process_isKernelThread
#define Process_isKernelThread(_process) (_process->pgrp == 0) #define Process_isKernelThread(_process) (((LinuxProcess*)(_process))->isKernelThread)
#endif #endif
#ifndef Process_isUserlandThread #ifndef Process_isUserlandThread

View File

@ -677,9 +677,6 @@ static void setCommand(Process* process, const char* command, int len) {
} }
static bool LinuxProcessList_readCmdlineFile(Process* process, const char* dirname, const char* name) { static bool LinuxProcessList_readCmdlineFile(Process* process, const char* dirname, const char* name) {
if (Process_isKernelThread(process))
return true;
char filename[MAX_NAME+1]; char filename[MAX_NAME+1];
xSnprintf(filename, MAX_NAME, "%s/%s/cmdline", dirname, name); xSnprintf(filename, MAX_NAME, "%s/%s/cmdline", dirname, name);
int fd = open(filename, O_RDONLY); int fd = open(filename, O_RDONLY);
@ -691,7 +688,10 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, const char* dirna
close(fd); close(fd);
int tokenEnd = 0; int tokenEnd = 0;
int lastChar = 0; int lastChar = 0;
if (amtRead <= 0) { if (amtRead == 0) {
((LinuxProcess*)process)->isKernelThread = true;
return true;
} else if (amtRead < 0) {
return false; return false;
} }
for (int i = 0; i < amtRead; i++) { for (int i = 0; i < amtRead; i++) {