Linux: use proper way to detect kernel threads

Use PF_KTHREAD flag in /proc/[pid]/stat to detect kernel threads.
This fixed an issue when a process's cmdline is empty, htop think
it is a kernel thread.
This commit is contained in:
Rin Cat (鈴猫) 2021-11-08 09:42:12 -05:00 committed by BenBE
parent e7a8d14cbd
commit 07496eafb0
2 changed files with 23 additions and 15 deletions

View File

@ -48,6 +48,9 @@ typedef struct LinuxProcess_ {
long m_drs; long m_drs;
long m_lrs; long m_lrs;
/* Process flags */
unsigned long int flags;
/* Data read (in bytes) */ /* Data read (in bytes) */
unsigned long long io_rchar; unsigned long long io_rchar;

View File

@ -62,6 +62,10 @@ in the source distribution for its full text.
#define O_PATH 010000000 // declare for ancient glibc versions #define O_PATH 010000000 // declare for ancient glibc versions
#endif #endif
/* Not exposed yet. Defined at include/linux/sched.h */
#ifndef PF_KTHREAD
#define PF_KTHREAD 0x00200000
#endif
static long long btime = -1; static long long btime = -1;
@ -374,8 +378,9 @@ static bool LinuxProcessList_readStatFile(Process* process, openat_arg_t procFd,
process->tpgid = strtol(location, &location, 10); process->tpgid = strtol(location, &location, 10);
location += 1; location += 1;
/* Skip (9) flags - %u */ /* (9) flags - %u */
location = strchr(location, ' ') + 1; lp->flags = strtoul(location, &location, 10);
location += 1;
/* (10) minflt - %lu */ /* (10) minflt - %lu */
process->minflt = strtoull(location, &location, 10); process->minflt = strtoull(location, &location, 10);
@ -1110,17 +1115,9 @@ delayacct_failure:
static bool LinuxProcessList_readCmdlineFile(Process* process, openat_arg_t procFd) { static bool LinuxProcessList_readCmdlineFile(Process* process, openat_arg_t procFd) {
char command[4096 + 1]; // max cmdline length on Linux char command[4096 + 1]; // max cmdline length on Linux
ssize_t amtRead = xReadfileat(procFd, "cmdline", command, sizeof(command)); ssize_t amtRead = xReadfileat(procFd, "cmdline", command, sizeof(command));
if (amtRead < 0) if (amtRead <= 0)
return false; return false;
if (amtRead == 0) {
if (process->state != ZOMBIE) {
process->isKernelThread = true;
}
Process_updateCmdline(process, NULL, 0, 0);
return true;
}
int tokenEnd = 0; int tokenEnd = 0;
int tokenStart = 0; int tokenStart = 0;
int lastChar = 0; int lastChar = 0;
@ -1488,6 +1485,10 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
if (! LinuxProcessList_readStatFile(proc, procFd, statCommand, sizeof(statCommand))) if (! LinuxProcessList_readStatFile(proc, procFd, statCommand, sizeof(statCommand)))
goto errorReadingProcess; goto errorReadingProcess;
if (lp->flags & PF_KTHREAD) {
proc->isKernelThread = true;
}
if (tty_nr != proc->tty_nr && this->ttyDrivers) { if (tty_nr != proc->tty_nr && this->ttyDrivers) {
free(proc->tty_name); free(proc->tty_name);
proc->tty_name = LinuxProcessList_updateTtyDevice(this->ttyDrivers, proc->tty_nr); proc->tty_name = LinuxProcessList_updateTtyDevice(this->ttyDrivers, proc->tty_nr);
@ -1519,8 +1520,10 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
} }
#endif #endif
if (! LinuxProcessList_readCmdlineFile(proc, procFd)) { if (proc->isKernelThread) {
goto errorReadingProcess; Process_updateCmdline(proc, NULL, 0, 0);
} else if (!LinuxProcessList_readCmdlineFile(proc, procFd)) {
Process_updateCmdline(proc, statCommand, 0, strlen(statCommand));
} }
Process_fillStarttimeBuffer(proc); Process_fillStarttimeBuffer(proc);
@ -1528,8 +1531,10 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
ProcessList_add(pl, proc); ProcessList_add(pl, proc);
} else { } else {
if (settings->updateProcessNames && proc->state != ZOMBIE) { if (settings->updateProcessNames && proc->state != ZOMBIE) {
if (! LinuxProcessList_readCmdlineFile(proc, procFd)) { if (proc->isKernelThread) {
goto errorReadingProcess; Process_updateCmdline(proc, NULL, 0, 0);
} else if (!LinuxProcessList_readCmdlineFile(proc, procFd)) {
Process_updateCmdline(proc, statCommand, 0, strlen(statCommand));
} }
} }
} }