From 00d1fb019a1905dd8d29210e7598c41af7399f88 Mon Sep 17 00:00:00 2001 From: Hisham Muhammad Date: Sun, 25 Mar 2018 15:26:05 -0300 Subject: [PATCH] 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. --- linux/LinuxProcess.c | 3 ++- linux/LinuxProcess.h | 3 ++- linux/LinuxProcessList.c | 8 ++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/linux/LinuxProcess.c b/linux/LinuxProcess.c index c70efbbf..b2c4838f 100644 --- a/linux/LinuxProcess.c +++ b/linux/LinuxProcess.c @@ -117,6 +117,7 @@ typedef enum LinuxProcessFields { typedef struct LinuxProcess_ { Process super; + bool isKernelThread; IOPriority ioPriority; unsigned long int cminflt; unsigned long int cmajflt; @@ -185,7 +186,7 @@ typedef struct LinuxProcess_ { } LinuxProcess; #ifndef Process_isKernelThread -#define Process_isKernelThread(_process) (_process->pgrp == 0) +#define Process_isKernelThread(_process) ((LinuxProcess*)(_process)->isKernelThread) #endif #ifndef Process_isUserlandThread diff --git a/linux/LinuxProcess.h b/linux/LinuxProcess.h index 6abcb127..bf6ff422 100644 --- a/linux/LinuxProcess.h +++ b/linux/LinuxProcess.h @@ -109,6 +109,7 @@ typedef enum LinuxProcessFields { typedef struct LinuxProcess_ { Process super; + bool isKernelThread; IOPriority ioPriority; unsigned long int cminflt; unsigned long int cmajflt; @@ -177,7 +178,7 @@ typedef struct LinuxProcess_ { } LinuxProcess; #ifndef Process_isKernelThread -#define Process_isKernelThread(_process) (_process->pgrp == 0) +#define Process_isKernelThread(_process) (((LinuxProcess*)(_process))->isKernelThread) #endif #ifndef Process_isUserlandThread diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index b89477eb..29ad4b7b 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -748,9 +748,6 @@ static void setCommand(Process* process, const char* command, int len) { } static bool LinuxProcessList_readCmdlineFile(Process* process, const char* dirname, const char* name) { - if (Process_isKernelThread(process)) - return true; - char filename[MAX_NAME+1]; xSnprintf(filename, MAX_NAME, "%s/%s/cmdline", dirname, name); int fd = open(filename, O_RDONLY); @@ -762,7 +759,10 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, const char* dirna close(fd); int tokenEnd = 0; int lastChar = 0; - if (amtRead <= 0) { + if (amtRead == 0) { + ((LinuxProcess*)process)->isKernelThread = true; + return true; + } else if (amtRead < 0) { return false; } for (int i = 0; i < amtRead; i++) {