From 223aa8a70497829b9b540adc00119f588b0d9a9e Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Sun, 2 Feb 2025 15:39:18 +0800 Subject: [PATCH 1/8] PCPProcessTable_updateCmdline() minor logic adjustment Reorder a conditional to prevent an unnecessary negative array offset access. The compiled behavior should be exactly the same. Signed-off-by: Kang-Che Sung --- pcp/PCPProcessTable.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pcp/PCPProcessTable.c b/pcp/PCPProcessTable.c index 4999bdc27..024bef55f 100644 --- a/pcp/PCPProcessTable.c +++ b/pcp/PCPProcessTable.c @@ -314,10 +314,10 @@ static void PCPProcessTable_updateCmdline(Process* process, int pid, int offset, if (command[0] != '(') { process->isKernelThread = false; } else { - ++command; - --length; if (command[length - 1] == ')') command[--length] = '\0'; + ++command; + --length; process->isKernelThread = true; } From b748ffa584376694825682864540375596d5c287 Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Mon, 3 Feb 2025 03:45:46 +0800 Subject: [PATCH 2/8] Correct code commment in matchCmdlinePrefixWithExeSuffix() No code changes. Fix an error by commit 94a52cb5c9274fe021b3fc114180294cadb598b4 that accidentally replaced a keyword in comment to "cmdlineBasenameEnd". According to the context it should refer to "cmdlineBasenameStart" instead. --- Process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Process.c b/Process.c index 2cca19dbb..eb93266bf 100644 --- a/Process.c +++ b/Process.c @@ -121,7 +121,7 @@ static int matchCmdlinePrefixWithExeSuffix(const char* cmdline, int cmdlineBaseO * that make htop's identification of the basename in cmdline unreliable. * For e.g. /usr/libexec/gdm-session-worker modifies its cmdline to * "gdm-session-worker [pam/gdm-autologin]" and htop ends up with - * proccmdlineBasenameEnd at "gdm-autologin]". This issue could arise with + * cmdlineBasenameStart at "gdm-autologin]". This issue could arise with * chrome as well as it stores in cmdline its concatenated argument vector, * without NUL delimiter between the arguments (which may contain a '/') * From d277f13932b4308a4e5baf6df30f5c92c7fb83cf Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Thu, 17 Apr 2025 01:17:44 +0800 Subject: [PATCH 3/8] Code style adjustment in matchCmdlinePrefixWithExeSuffix() * Improve readability of local variables. * Increment the loop counter values ("i" and "j") by 1 and adjust the loop termination conditions. This allow "i" and "j" to easily switch to an unsigned type in the future. Signed-off-by: Kang-Che Sung --- Process.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/Process.c b/Process.c index eb93266bf..781709105 100644 --- a/Process.c +++ b/Process.c @@ -100,14 +100,11 @@ static bool findCommInCmdline(const char* comm, const char* cmdline, int cmdline } static int matchCmdlinePrefixWithExeSuffix(const char* cmdline, int cmdlineBaseOffset, const char* exe, int exeBaseOffset, int exeBaseLen) { - int matchLen; /* matching length to be returned */ - char delim; /* delimiter following basename */ - /* cmdline prefix is an absolute path: it must match whole exe. */ if (cmdline[0] == '/') { - matchLen = exeBaseLen + exeBaseOffset; + int matchLen = exeBaseLen + exeBaseOffset; if (strncmp(cmdline, exe, matchLen) == 0) { - delim = cmdline[matchLen]; + char delim = cmdline[matchLen]; if (delim == 0 || delim == '\n' || delim == ' ') { return matchLen; } @@ -127,29 +124,31 @@ static int matchCmdlinePrefixWithExeSuffix(const char* cmdline, int cmdlineBaseO * * So if needed, we adjust cmdlineBaseOffset to the previous (if any) * component of the cmdline relative path, and retry the procedure. */ - bool delimFound; /* if valid basename delimiter found */ + bool delimFound = true; /* if valid basename delimiter found */ do { /* match basename */ - matchLen = exeBaseLen + cmdlineBaseOffset; + int matchLen = exeBaseLen + cmdlineBaseOffset; if (cmdlineBaseOffset < exeBaseOffset && strncmp(cmdline + cmdlineBaseOffset, exe + exeBaseOffset, exeBaseLen) == 0) { - delim = cmdline[matchLen]; + char delim = cmdline[matchLen]; if (delim == 0 || delim == '\n' || delim == ' ') { - int i, j; /* reverse match the cmdline prefix and exe suffix */ - for (i = cmdlineBaseOffset - 1, j = exeBaseOffset - 1; - i >= 0 && j >= 0 && cmdline[i] == exe[j]; --i, --j) - ; + int i = cmdlineBaseOffset; + int j = exeBaseOffset; + while (i >= 1 && j >= 1 && cmdline[i - 1] == exe[j - 1]) { + --i, --j; + } /* full match, with exe suffix being a valid relative path */ - if (i < 0 && j >= 0 && exe[j] == '/') + if (i < 1 && j >= 1 && exe[j - 1] == '/') return matchLen; } } /* Try to find the previous potential cmdlineBaseOffset - it would be * preceded by '/' or nothing, and delimited by ' ' or '\n' */ - for (delimFound = false, cmdlineBaseOffset -= 2; cmdlineBaseOffset > 0; --cmdlineBaseOffset) { + delimFound = false; + for (cmdlineBaseOffset -= 2; cmdlineBaseOffset > 0; --cmdlineBaseOffset) { if (delimFound) { if (cmdline[cmdlineBaseOffset - 1] == '/') { break; From 42ac7b8b988ccf3bb85f022bfcba45d157bb182c Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Thu, 17 Apr 2025 01:18:19 +0800 Subject: [PATCH 4/8] Code simplification in Process_makeCommandStr() Store the "cmdlineBasenameLen" and "commLen" local variables rather than "cmdlineBasenameEnd" and "commEnd". Signed-off-by: Kang-Che Sung --- Process.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/Process.c b/Process.c index 781709105..b29b6e6d8 100644 --- a/Process.c +++ b/Process.c @@ -64,7 +64,7 @@ void Process_fillStarttimeBuffer(Process* this) { */ #define TASK_COMM_LEN 16 -static bool findCommInCmdline(const char* comm, const char* cmdline, int cmdlineBasenameStart, int* pCommStart, int* pCommEnd) { +static bool findCommInCmdline(const char* comm, const char* cmdline, int cmdlineBasenameStart, int* pCommStart, int* pCommLen) { /* Try to find procComm in tokenized cmdline - this might in rare cases * mis-identify a string or fail, if comm or cmdline had been unsuitably * modified by the process */ @@ -86,7 +86,7 @@ static bool findCommInCmdline(const char* comm, const char* cmdline, int cmdline if ((tokenLen == commLen || (tokenLen > commLen && commLen == (TASK_COMM_LEN - 1))) && strncmp(tokenBase, comm, commLen) == 0) { *pCommStart = tokenBase - cmdline; - *pCommEnd = token - cmdline; + *pCommLen = tokenLen; return true; } @@ -309,11 +309,13 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { char* str = strStart; int cmdlineBasenameStart = this->cmdlineBasenameStart; - int cmdlineBasenameEnd = this->cmdlineBasenameEnd; + int cmdlineBasenameLen = 0; + if (this->cmdlineBasenameEnd > this->cmdlineBasenameStart) + cmdlineBasenameLen = this->cmdlineBasenameEnd - this->cmdlineBasenameStart; if (!cmdline) { cmdlineBasenameStart = 0; - cmdlineBasenameEnd = 0; + cmdlineBasenameLen = 0; cmdline = "(zombie)"; } @@ -336,13 +338,13 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { if (shadowDistPathPrefix && showProgramPath) CHECK_AND_MARK_DIST_PATH_PREFIXES(cmdline); - if (cmdlineBasenameEnd > cmdlineBasenameStart) - WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameEnd - cmdlineBasenameStart, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME); + if (cmdlineBasenameLen > 0) + WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameLen, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME); if (this->procExeDeleted) - WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameEnd - cmdlineBasenameStart, delExeAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED); + WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameLen, delExeAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED); else if (this->usesDeletedLib) - WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameEnd - cmdlineBasenameStart, delLibAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED); + WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameLen, delLibAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED); (void)stpcpyWithNewlineConversion(str, cmdline + (showProgramPath ? 0 : cmdlineBasenameStart)); @@ -386,12 +388,12 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { bool haveCommInCmdline = false; int commStart = 0; - int commEnd = 0; + int commLen = 0; /* Try to match procComm with procExe's basename: This is reliable (predictable) */ if (searchCommInCmdline) { - /* commStart/commEnd will be adjusted later along with cmdline */ - haveCommInCmdline = (!Process_isUserlandThread(this) || showThreadNames) && findCommInCmdline(procComm, cmdline, cmdlineBasenameStart, &commStart, &commEnd); + /* commStart/commLen will be adjusted later along with cmdline */ + haveCommInCmdline = (!Process_isUserlandThread(this) || showThreadNames) && findCommInCmdline(procComm, cmdline, cmdlineBasenameStart, &commStart, &commLen); } int matchLen = matchCmdlinePrefixWithExeSuffix(cmdline, cmdlineBasenameStart, procExe, exeBasenameOffset, exeBasenameLen); @@ -411,7 +413,6 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { cmdline += matchLen; commStart -= matchLen; - commEnd -= matchLen; } else { matchLen = 0; } @@ -426,7 +427,7 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { CHECK_AND_MARK_DIST_PATH_PREFIXES(cmdline); if (!haveCommInExe && haveCommInCmdline && !haveCommField && (!Process_isUserlandThread(this) || showThreadNames)) - WRITE_HIGHLIGHT(commStart, commEnd - commStart, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM); + WRITE_HIGHLIGHT(commStart, commLen, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM); /* Display cmdline if it hasn't been consumed by procExe */ if (*cmdline) From 5c55b803f91d47a48d3f553bb5262485c4626280 Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Thu, 17 Apr 2025 01:18:22 +0800 Subject: [PATCH 5/8] Don't make highlights of zero-length cmdline basename Adjust logic in Process_makeCommandStr() so that if the process "cmdline" basename has a length of zero, skip creating all of the highlights of that basename. Signed-off-by: Kang-Che Sung --- Process.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Process.c b/Process.c index b29b6e6d8..b622c1f52 100644 --- a/Process.c +++ b/Process.c @@ -338,13 +338,14 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { if (shadowDistPathPrefix && showProgramPath) CHECK_AND_MARK_DIST_PATH_PREFIXES(cmdline); - if (cmdlineBasenameLen > 0) + if (cmdlineBasenameLen > 0) { WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameLen, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME); - if (this->procExeDeleted) - WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameLen, delExeAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED); - else if (this->usesDeletedLib) - WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameLen, delLibAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED); + if (this->procExeDeleted) + WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameLen, delExeAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED); + else if (this->usesDeletedLib) + WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameLen, delLibAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED); + } (void)stpcpyWithNewlineConversion(str, cmdline + (showProgramPath ? 0 : cmdlineBasenameStart)); From 2bbd07cae835bc837bdc0f65315ece4e7f3236e4 Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Thu, 17 Apr 2025 01:18:26 +0800 Subject: [PATCH 6/8] Improve process cmdline basename matching with procExe path The matchCmdlinePrefixWithExeSuffix() internal function (in Process.c) can match basenames in multiple tries in case the "cmdlineBasenameStart" input value is unreliable. Take advantage of this and update "cmdlineBasenameStart" with the new offset detected by the function. Also make the matching behavior consistent regardless of "showMergedCommand" setting. Signed-off-by: Kang-Che Sung --- Process.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/Process.c b/Process.c index b622c1f52..32c509ea3 100644 --- a/Process.c +++ b/Process.c @@ -99,7 +99,7 @@ static bool findCommInCmdline(const char* comm, const char* cmdline, int cmdline return false; } -static int matchCmdlinePrefixWithExeSuffix(const char* cmdline, int cmdlineBaseOffset, const char* exe, int exeBaseOffset, int exeBaseLen) { +static int matchCmdlinePrefixWithExeSuffix(const char* cmdline, int* cmdlineBasenameStart, const char* exe, int exeBaseOffset, int exeBaseLen) { /* cmdline prefix is an absolute path: it must match whole exe. */ if (cmdline[0] == '/') { int matchLen = exeBaseLen + exeBaseOffset; @@ -124,6 +124,7 @@ static int matchCmdlinePrefixWithExeSuffix(const char* cmdline, int cmdlineBaseO * * So if needed, we adjust cmdlineBaseOffset to the previous (if any) * component of the cmdline relative path, and retry the procedure. */ + int cmdlineBaseOffset = *cmdlineBasenameStart; bool delimFound = true; /* if valid basename delimiter found */ do { /* match basename */ @@ -140,8 +141,10 @@ static int matchCmdlinePrefixWithExeSuffix(const char* cmdline, int cmdlineBaseO } /* full match, with exe suffix being a valid relative path */ - if (i < 1 && j >= 1 && exe[j - 1] == '/') + if (i < 1 && j >= 1 && exe[j - 1] == '/') { + *cmdlineBasenameStart = cmdlineBaseOffset; return matchLen; + } } } @@ -322,6 +325,26 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { assert(cmdlineBasenameStart >= 0); assert(cmdlineBasenameStart <= (int)strlen(cmdline)); + int exeLen = 0; + int exeBasenameOffset = 0; + int exeBasenameLen = 0; + int matchLen = 0; + if (procExe) { + exeLen = strlen(procExe); + exeBasenameOffset = this->procExeBasenameOffset; + exeBasenameLen = exeLen - exeBasenameOffset; + + assert(exeBasenameOffset >= 0); + assert(exeBasenameOffset <= (int)strlen(procExe)); + + if (this->cmdline) { + matchLen = matchCmdlinePrefixWithExeSuffix(this->cmdline, &cmdlineBasenameStart, procExe, exeBasenameOffset, exeBasenameLen); + } + if (matchLen) { + cmdlineBasenameLen = exeBasenameLen; + } + } + if (!showMergedCommand || !procExe || !procComm) { /* fall back to cmdline */ if ((showMergedCommand || (Process_isUserlandThread(this) && showThreadNames)) && procComm && strlen(procComm)) { /* set column to or prefix it with comm */ if (strncmp(cmdline + cmdlineBasenameStart, procComm, MINIMUM(TASK_COMM_LEN - 1, strlen(procComm))) != 0) { @@ -352,13 +375,6 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { return; } - int exeLen = strlen(this->procExe); - int exeBasenameOffset = this->procExeBasenameOffset; - int exeBasenameLen = exeLen - exeBasenameOffset; - - assert(exeBasenameOffset >= 0); - assert(exeBasenameOffset <= (int)strlen(procExe)); - bool haveCommInExe = false; if (procExe && procComm && (!Process_isUserlandThread(this) || showThreadNames)) { haveCommInExe = strncmp(procExe + exeBasenameOffset, procComm, TASK_COMM_LEN - 1) == 0; @@ -397,8 +413,6 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { haveCommInCmdline = (!Process_isUserlandThread(this) || showThreadNames) && findCommInCmdline(procComm, cmdline, cmdlineBasenameStart, &commStart, &commLen); } - int matchLen = matchCmdlinePrefixWithExeSuffix(cmdline, cmdlineBasenameStart, procExe, exeBasenameOffset, exeBasenameLen); - bool haveCommField = false; if (!haveCommInExe && !haveCommInCmdline && procComm && (!Process_isUserlandThread(this) || showThreadNames)) { From 637723f2b7ec492991e8db00f6a44af1472f215d Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Thu, 17 Apr 2025 01:18:30 +0800 Subject: [PATCH 7/8] Improve "comm" string highlighting in Process_makeCommandStr() Add a special case when the process "comm" string is found in "cmdline", but at the starting basename position that would be stripped by "stripExeFromCmdline" setting. This special case will now highlight the basename of "exe" string as well as the first token of "cmdline" (as the two strings are concatenated together when displaying). Signed-off-by: Kang-Che Sung --- Process.c | 56 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/Process.c b/Process.c index 32c509ea3..629030f57 100644 --- a/Process.c +++ b/Process.c @@ -375,17 +375,48 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { return; } + int commLen = 0; + bool haveCommInExe = false; if (procExe && procComm && (!Process_isUserlandThread(this) || showThreadNames)) { haveCommInExe = strncmp(procExe + exeBasenameOffset, procComm, TASK_COMM_LEN - 1) == 0; } + if (haveCommInExe) { + commLen = exeBasenameLen; + } + + bool haveCommInCmdline = false; + int commStart = 0; + + if (!haveCommInExe && this->cmdline && procComm && searchCommInCmdline && (!Process_isUserlandThread(this) || showThreadNames)) { + haveCommInCmdline = findCommInCmdline(procComm, cmdline, cmdlineBasenameStart, &commStart, &commLen); + } + + if (!stripExeFromCmdline) { + matchLen = 0; + } + if (matchLen) { + /* strip the matched exe prefix */ + cmdline += matchLen; + + if (haveCommInCmdline) { + if (commStart == cmdlineBasenameStart) { + haveCommInExe = true; + haveCommInCmdline = false; + commStart = 0; + } else { + assert(commStart >= matchLen); + commStart -= matchLen; + } + } + } /* Start with copying exe */ if (showProgramPath) { if (shadowDistPathPrefix) CHECK_AND_MARK_DIST_PATH_PREFIXES(procExe); if (haveCommInExe) - WRITE_HIGHLIGHT(exeBasenameOffset, exeBasenameLen, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM); + WRITE_HIGHLIGHT(exeBasenameOffset, commLen, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM); WRITE_HIGHLIGHT(exeBasenameOffset, exeBasenameLen, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME); if (this->procExeDeleted) WRITE_HIGHLIGHT(exeBasenameOffset, exeBasenameLen, delExeAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED); @@ -394,7 +425,7 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { str = stpcpy(str, procExe); } else { if (haveCommInExe) - WRITE_HIGHLIGHT(0, exeBasenameLen, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM); + WRITE_HIGHLIGHT(0, commLen, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM); WRITE_HIGHLIGHT(0, exeBasenameLen, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME); if (this->procExeDeleted) WRITE_HIGHLIGHT(0, exeBasenameLen, delExeAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED); @@ -403,16 +434,6 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { str = stpcpy(str, procExe + exeBasenameOffset); } - bool haveCommInCmdline = false; - int commStart = 0; - int commLen = 0; - - /* Try to match procComm with procExe's basename: This is reliable (predictable) */ - if (searchCommInCmdline) { - /* commStart/commLen will be adjusted later along with cmdline */ - haveCommInCmdline = (!Process_isUserlandThread(this) || showThreadNames) && findCommInCmdline(procComm, cmdline, cmdlineBasenameStart, &commStart, &commLen); - } - bool haveCommField = false; if (!haveCommInExe && !haveCommInCmdline && procComm && (!Process_isUserlandThread(this) || showThreadNames)) { @@ -422,17 +443,6 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { haveCommField = true; } - if (matchLen) { - if (stripExeFromCmdline) { - /* strip the matched exe prefix */ - cmdline += matchLen; - - commStart -= matchLen; - } else { - matchLen = 0; - } - } - if (!matchLen || (haveCommField && *cmdline)) { /* cmdline will be a separate field */ WRITE_SEPARATOR; From 656a2d2775084df2b70a71a732e83234bae578b8 Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Thu, 17 Apr 2025 01:18:33 +0800 Subject: [PATCH 8/8] Process: Use size_t for "cmdline" and "procExe" offsets Convert the members "cmdlineBasenameStart", "cmdlineBasenameEnd" and "procExeBasenameOffset" in "Process" to size_t type. Also upgrade many routines that search for "basenames", COMM, and PROC_EXE string to use size_t for iterators. The "cmdlineBasenameEnd" value is no longer allowed to negative. It is now set to 0 during Process_init(). Signed-off-by: Kang-Che Sung --- Process.c | 71 ++++++++++++------------- Process.h | 8 +-- darwin/DarwinProcess.c | 6 +-- dragonflybsd/DragonFlyBSDProcessTable.c | 8 +-- freebsd/FreeBSDProcessTable.c | 8 +-- linux/LinuxProcessTable.c | 50 ++++++++--------- netbsd/NetBSDProcessTable.c | 10 ++-- openbsd/OpenBSDProcessTable.c | 10 ++-- pcp/PCPProcessTable.c | 8 +-- 9 files changed, 88 insertions(+), 91 deletions(-) diff --git a/Process.c b/Process.c index 629030f57..39cb92c89 100644 --- a/Process.c +++ b/Process.c @@ -64,7 +64,7 @@ void Process_fillStarttimeBuffer(Process* this) { */ #define TASK_COMM_LEN 16 -static bool findCommInCmdline(const char* comm, const char* cmdline, int cmdlineBasenameStart, int* pCommStart, int* pCommLen) { +static bool findCommInCmdline(const char* comm, const char* cmdline, size_t cmdlineBasenameStart, size_t* pCommStart, size_t* pCommLen) { /* Try to find procComm in tokenized cmdline - this might in rare cases * mis-identify a string or fail, if comm or cmdline had been unsuitably * modified by the process */ @@ -72,20 +72,17 @@ static bool findCommInCmdline(const char* comm, const char* cmdline, int cmdline size_t tokenLen; const size_t commLen = strlen(comm); - if (cmdlineBasenameStart < 0) - return false; - for (const char* token = cmdline + cmdlineBasenameStart; *token;) { for (tokenBase = token; *token && *token != '\n'; ++token) { if (*token == '/') { tokenBase = token + 1; } } - tokenLen = token - tokenBase; + tokenLen = (size_t)(token - tokenBase); if ((tokenLen == commLen || (tokenLen > commLen && commLen == (TASK_COMM_LEN - 1))) && strncmp(tokenBase, comm, commLen) == 0) { - *pCommStart = tokenBase - cmdline; + *pCommStart = (size_t)(tokenBase - cmdline); *pCommLen = tokenLen; return true; } @@ -99,10 +96,10 @@ static bool findCommInCmdline(const char* comm, const char* cmdline, int cmdline return false; } -static int matchCmdlinePrefixWithExeSuffix(const char* cmdline, int* cmdlineBasenameStart, const char* exe, int exeBaseOffset, int exeBaseLen) { +static size_t matchCmdlinePrefixWithExeSuffix(const char* cmdline, size_t* cmdlineBasenameStart, const char* exe, size_t exeBaseOffset, size_t exeBaseLen) { /* cmdline prefix is an absolute path: it must match whole exe. */ if (cmdline[0] == '/') { - int matchLen = exeBaseLen + exeBaseOffset; + size_t matchLen = exeBaseLen + exeBaseOffset; if (strncmp(cmdline, exe, matchLen) == 0) { char delim = cmdline[matchLen]; if (delim == 0 || delim == '\n' || delim == ' ') { @@ -124,18 +121,18 @@ static int matchCmdlinePrefixWithExeSuffix(const char* cmdline, int* cmdlineBase * * So if needed, we adjust cmdlineBaseOffset to the previous (if any) * component of the cmdline relative path, and retry the procedure. */ - int cmdlineBaseOffset = *cmdlineBasenameStart; + size_t cmdlineBaseOffset = *cmdlineBasenameStart; bool delimFound = true; /* if valid basename delimiter found */ do { /* match basename */ - int matchLen = exeBaseLen + cmdlineBaseOffset; + size_t matchLen = exeBaseLen + cmdlineBaseOffset; if (cmdlineBaseOffset < exeBaseOffset && strncmp(cmdline + cmdlineBaseOffset, exe + exeBaseOffset, exeBaseLen) == 0) { char delim = cmdline[matchLen]; if (delim == 0 || delim == '\n' || delim == ' ') { /* reverse match the cmdline prefix and exe suffix */ - int i = cmdlineBaseOffset; - int j = exeBaseOffset; + size_t i = cmdlineBaseOffset; + size_t j = exeBaseOffset; while (i >= 1 && j >= 1 && cmdline[i - 1] == exe[j - 1]) { --i, --j; } @@ -151,6 +148,9 @@ static int matchCmdlinePrefixWithExeSuffix(const char* cmdline, int* cmdlineBase /* Try to find the previous potential cmdlineBaseOffset - it would be * preceded by '/' or nothing, and delimited by ' ' or '\n' */ delimFound = false; + if (cmdlineBaseOffset <= 2) { + return 0; + } for (cmdlineBaseOffset -= 2; cmdlineBaseOffset > 0; --cmdlineBaseOffset) { if (delimFound) { if (cmdline[cmdlineBaseOffset - 1] == '/') { @@ -311,8 +311,8 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { char* strStart = mc->str; char* str = strStart; - int cmdlineBasenameStart = this->cmdlineBasenameStart; - int cmdlineBasenameLen = 0; + size_t cmdlineBasenameStart = this->cmdlineBasenameStart; + size_t cmdlineBasenameLen = 0; if (this->cmdlineBasenameEnd > this->cmdlineBasenameStart) cmdlineBasenameLen = this->cmdlineBasenameEnd - this->cmdlineBasenameStart; @@ -322,20 +322,18 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { cmdline = "(zombie)"; } - assert(cmdlineBasenameStart >= 0); - assert(cmdlineBasenameStart <= (int)strlen(cmdline)); + assert(cmdlineBasenameStart <= strlen(cmdline)); - int exeLen = 0; - int exeBasenameOffset = 0; - int exeBasenameLen = 0; - int matchLen = 0; + size_t exeLen = 0; + size_t exeBasenameOffset = 0; + size_t exeBasenameLen = 0; + size_t matchLen = 0; if (procExe) { exeLen = strlen(procExe); exeBasenameOffset = this->procExeBasenameOffset; exeBasenameLen = exeLen - exeBasenameOffset; - assert(exeBasenameOffset >= 0); - assert(exeBasenameOffset <= (int)strlen(procExe)); + assert(exeBasenameOffset <= strlen(procExe)); if (this->cmdline) { matchLen = matchCmdlinePrefixWithExeSuffix(this->cmdline, &cmdlineBasenameStart, procExe, exeBasenameOffset, exeBasenameLen); @@ -375,7 +373,7 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { return; } - int commLen = 0; + size_t commLen = 0; bool haveCommInExe = false; if (procExe && procComm && (!Process_isUserlandThread(this) || showThreadNames)) { @@ -386,7 +384,7 @@ void Process_makeCommandStr(Process* this, const Settings* settings) { } bool haveCommInCmdline = false; - int commStart = 0; + size_t commStart = 0; if (!haveCommInExe && this->cmdline && procComm && searchCommInCmdline && (!Process_isUserlandThread(this) || showThreadNames)) { haveCommInCmdline = findCommInCmdline(procComm, cmdline, cmdlineBasenameStart, &commStart, &commLen); @@ -470,7 +468,7 @@ void Process_writeCommand(const Process* this, int attr, int baseAttr, RichStrin const ProcessMergedCommand* mc = &this->mergedCommand; const char* mergedCommand = mc->str; - int strStart = RichString_size(str); + size_t strStart = RichString_size(str); const Settings* settings = this->super.host->settings; const bool highlightBaseName = settings->highlightBaseName; @@ -478,12 +476,12 @@ void Process_writeCommand(const Process* this, int attr, int baseAttr, RichStrin const bool highlightDeleted = settings->highlightDeletedExe; if (!mergedCommand) { - int len = 0; + size_t len = 0; const char* cmdline = this->cmdline; if (highlightBaseName || !settings->showProgramPath) { - int basename = 0; - for (int i = 0; i < this->cmdlineBasenameEnd; i++) { + size_t basename = 0; + for (size_t i = 0; i < this->cmdlineBasenameEnd; i++) { if (cmdline[i] == '/') { basename = i + 1; } else if (cmdline[i] == ':') { @@ -874,7 +872,7 @@ bool Process_rowMatchesFilter(const Row* super, const Table* table) { void Process_init(Process* this, const Machine* host) { Row_init(&this->super, host); - this->cmdlineBasenameEnd = -1; + this->cmdlineBasenameEnd = 0; this->st_uid = (uid_t)-1; } @@ -1026,12 +1024,12 @@ void Process_updateComm(Process* this, const char* comm) { this->mergedCommand.lastUpdate = 0; } -static int skipPotentialPath(const char* cmdline, int end) { +static size_t skipPotentialPath(const char* cmdline, size_t end) { if (cmdline[0] != '/') return 0; - int slash = 0; - for (int i = 1; i < end; i++) { + size_t slash = 0; + for (size_t i = 1; i < end; i++) { if (cmdline[i] == '/' && cmdline[i + 1] != '\0') { slash = i + 1; continue; @@ -1047,11 +1045,10 @@ static int skipPotentialPath(const char* cmdline, int end) { return slash; } -void Process_updateCmdline(Process* this, const char* cmdline, int basenameStart, int basenameEnd) { - assert(basenameStart >= 0); - assert((cmdline && basenameStart < (int)strlen(cmdline)) || (!cmdline && basenameStart == 0)); +void Process_updateCmdline(Process* this, const char* cmdline, size_t basenameStart, size_t basenameEnd) { + assert((cmdline && basenameStart < strlen(cmdline)) || (!cmdline && basenameStart == 0)); assert((basenameEnd > basenameStart) || (basenameEnd == 0 && basenameStart == 0)); - assert((cmdline && basenameEnd <= (int)strlen(cmdline)) || (!cmdline && basenameEnd == 0)); + assert((cmdline && basenameEnd <= strlen(cmdline)) || (!cmdline && basenameEnd == 0)); if (!this->cmdline && !cmdline) return; @@ -1084,7 +1081,7 @@ void Process_updateExe(Process* this, const char* exe) { if (exe) { this->procExe = xStrdup(exe); const char* lastSlash = strrchr(exe, '/'); - this->procExeBasenameOffset = (lastSlash && *(lastSlash + 1) != '\0' && lastSlash != exe) ? (lastSlash - exe + 1) : 0; + this->procExeBasenameOffset = (lastSlash && *(lastSlash + 1) != '\0' && lastSlash != exe) ? (size_t)(lastSlash - exe + 1) : 0; } else { this->procExe = NULL; this->procExeBasenameOffset = 0; diff --git a/Process.h b/Process.h index b7b48cb1b..38e2711f6 100644 --- a/Process.h +++ b/Process.h @@ -129,10 +129,10 @@ typedef struct Process_ { char* cmdline; /* End Offset in cmdline of the process basename */ - int cmdlineBasenameEnd; + size_t cmdlineBasenameEnd; /* Start Offset in cmdline of the process basename */ - int cmdlineBasenameStart; + size_t cmdlineBasenameStart; /* The process' "command" name */ char* procComm; @@ -144,7 +144,7 @@ typedef struct Process_ { char* procCwd; /* Offset in procExe of the process basename */ - int procExeBasenameOffset; + size_t procExeBasenameOffset; /* Tells if the executable has been replaced in the filesystem since start */ bool procExeDeleted; @@ -326,7 +326,7 @@ int Process_compareByKey_Base(const Process* p1, const Process* p2, ProcessField const char* Process_getCommand(const Process* this); void Process_updateComm(Process* this, const char* comm); -void Process_updateCmdline(Process* this, const char* cmdline, int basenameStart, int basenameEnd); +void Process_updateCmdline(Process* this, const char* cmdline, size_t basenameStart, size_t basenameEnd); void Process_updateExe(Process* this, const char* exe); /* This function constructs the string that is displayed by diff --git a/darwin/DarwinProcess.c b/darwin/DarwinProcess.c index d28352831..587bd5101 100644 --- a/darwin/DarwinProcess.c +++ b/darwin/DarwinProcess.c @@ -235,7 +235,7 @@ static void DarwinProcess_updateCmdLine(const struct kinfo_proc* k, Process* pro /* Save where the argv[0] string starts. */ sp = cp; - int end = 0; + size_t end = 0; for ( np = NULL; c < nargs && cp < &procargs[size]; cp++ ) { if ( *cp == '\0' ) { c++; @@ -246,7 +246,7 @@ static void DarwinProcess_updateCmdLine(const struct kinfo_proc* k, Process* pro /* Note location of current '\0'. */ np = cp; if (end == 0) { - end = cp - sp; + end = (size_t)(cp - sp); } } } @@ -260,7 +260,7 @@ static void DarwinProcess_updateCmdLine(const struct kinfo_proc* k, Process* pro goto ERROR_B; } if (end == 0) { - end = np - sp; + end = (size_t)(np - sp); } Process_updateCmdline(proc, sp, 0, end); diff --git a/dragonflybsd/DragonFlyBSDProcessTable.c b/dragonflybsd/DragonFlyBSDProcessTable.c index b286219df..7d333862d 100644 --- a/dragonflybsd/DragonFlyBSDProcessTable.c +++ b/dragonflybsd/DragonFlyBSDProcessTable.c @@ -106,18 +106,18 @@ static void DragonFlyBSDProcessTable_updateProcessName(kvm_t* kd, const struct k } size_t len = 0; - for (int i = 0; argv[i]; i++) { + for (size_t i = 0; argv[i]; i++) { len += strlen(argv[i]) + 1; } char* cmdline = xMalloc(len); char* at = cmdline; - int end = 0; - for (int i = 0; argv[i]; i++) { + size_t end = 0; + for (size_t i = 0; argv[i]; i++) { at = stpcpy(at, argv[i]); if (end == 0) { - end = at - cmdline; + end = (size_t)(at - cmdline); } *at++ = ' '; } diff --git a/freebsd/FreeBSDProcessTable.c b/freebsd/FreeBSDProcessTable.c index ce8472594..67f8a445f 100644 --- a/freebsd/FreeBSDProcessTable.c +++ b/freebsd/FreeBSDProcessTable.c @@ -108,17 +108,17 @@ static void FreeBSDProcessTable_updateProcessName(kvm_t* kd, const struct kinfo_ } size_t len = 0; - for (int i = 0; argv[i]; i++) { + for (size_t i = 0; argv[i]; i++) { len += strlen(argv[i]) + 1; } char* cmdline = xMalloc(len); char* at = cmdline; - int end = 0; - for (int i = 0; argv[i]; i++) { + size_t end = 0; + for (size_t i = 0; argv[i]; i++) { at = stpcpy(at, argv[i]); if (end == 0) { - end = at - cmdline; + end = (size_t)(at - cmdline); } *at++ = ' '; } diff --git a/linux/LinuxProcessTable.c b/linux/LinuxProcessTable.c index 1fb3d8f6f..4d300ebe9 100644 --- a/linux/LinuxProcessTable.c +++ b/linux/LinuxProcessTable.c @@ -1273,15 +1273,15 @@ static bool LinuxProcessTable_readCmdlineFile(Process* process, openat_arg_t pro if (amtRead <= 0) return false; - int tokenEnd = -1; - int tokenStart = -1; - int lastChar = 0; + size_t tokenEnd = (size_t)-1; + size_t tokenStart = (size_t)-1; + size_t lastChar = 0; bool argSepNUL = false; bool argSepSpace = false; - for (int i = 0; i < amtRead; i++) { + for (size_t i = 0; i < (size_t)amtRead; i++) { // If this is true, there's a NUL byte in the middle of command - if (tokenEnd >= 0) { + if (tokenEnd != (size_t)-1) { argSepNUL = true; } @@ -1299,7 +1299,7 @@ static bool LinuxProcessTable_readCmdlineFile(Process* process, openat_arg_t pro command[i] = '\n'; // Set tokenEnd to the NUL byte - if (tokenEnd < 0) { + if (tokenEnd == (size_t)-1) { tokenEnd = i; } @@ -1313,7 +1313,7 @@ static bool LinuxProcessTable_readCmdlineFile(Process* process, openat_arg_t pro /* Detect the last / before the end of the token as * the start of the basename in cmdline, see Process_writeCommand */ - if (argChar == '/' && tokenEnd < 0) { + if (argChar == '/' && tokenEnd == (size_t)-1) { tokenStart = i + 1; } @@ -1336,13 +1336,13 @@ static bool LinuxProcessTable_readCmdlineFile(Process* process, openat_arg_t pro * As path names may contain we try to cross-validate if the path we got that way exists. */ - tokenStart = -1; - tokenEnd = -1; + tokenStart = (size_t)-1; + tokenEnd = (size_t)-1; size_t exeLen = process->procExe ? strlen(process->procExe) : 0; if (process->procExe && String_startsWith(command, process->procExe) && - exeLen < (size_t)lastChar && command[exeLen] <= ' ') { + exeLen < lastChar && command[exeLen] <= ' ') { tokenStart = process->procExeBasenameOffset; tokenEnd = exeLen; } @@ -1352,14 +1352,14 @@ static bool LinuxProcessTable_readCmdlineFile(Process* process, openat_arg_t pro else if (Compat_faccessat(AT_FDCWD, command, F_OK, AT_SYMLINK_NOFOLLOW) != 0) { // If we reach here the path does not exist. // Thus begin searching for the part of it that actually does. - int tokenArg0Start = -1; + size_t tokenArg0Start = (size_t)-1; - for (int i = 0; i <= lastChar; i++) { + for (size_t i = 0; i <= lastChar; i++) { const char cmdChar = command[i]; /* Any ASCII control or space used as delimiter */ if (cmdChar <= ' ') { - if (tokenEnd >= 0) { + if (tokenEnd != (size_t)-1) { // Split on every further separator, regardless of path correctness command[i] = '\n'; continue; @@ -1375,39 +1375,39 @@ static bool LinuxProcessTable_readCmdlineFile(Process* process, openat_arg_t pro if (found) tokenEnd = i; - if (tokenArg0Start < 0) - tokenArg0Start = tokenStart < 0 ? 0 : tokenStart; + if (tokenArg0Start == (size_t)-1) + tokenArg0Start = tokenStart == (size_t)-1 ? 0 : tokenStart; continue; } - if (tokenEnd >= 0) { + if (tokenEnd != (size_t)-1) { continue; } if (cmdChar == '/') { // Normal path separator tokenStart = i + 1; - } else if (cmdChar == '\\' && (tokenStart < 1 || command[tokenStart - 1] == '\\')) { + } else if (cmdChar == '\\' && (tokenStart == (size_t)-1 || tokenStart == 0 || command[tokenStart - 1] == '\\')) { // Windows Path separator (WINE) tokenStart = i + 1; } else if (cmdChar == ':' && (command[i + 1] != '/' && command[i + 1] != '\\')) { // Colon not part of a Windows Path tokenEnd = i; - } else if (tokenStart < 0) { + } else if (tokenStart == (size_t)-1) { // Relative path tokenStart = i; } } - if (tokenEnd < 0) { + if (tokenEnd == (size_t)-1) { tokenStart = tokenArg0Start; // No token delimiter found, forcibly split - for (int i = 0; i <= lastChar; i++) { + for (size_t i = 0; i <= lastChar; i++) { if (command[i] <= ' ') { command[i] = '\n'; - if (tokenEnd < 0) { + if (tokenEnd == (size_t)-1) { tokenEnd = i; } } @@ -1420,16 +1420,16 @@ static bool LinuxProcessTable_readCmdlineFile(Process* process, openat_arg_t pro * Reset if start is behind end. */ if (tokenStart >= tokenEnd) { - tokenStart = -1; - tokenEnd = -1; + tokenStart = (size_t)-1; + tokenEnd = (size_t)-1; } } - if (tokenStart < 0) { + if (tokenStart == (size_t)-1) { tokenStart = 0; } - if (tokenEnd < 0) { + if (tokenEnd == (size_t)-1) { tokenEnd = lastChar + 1; } diff --git a/netbsd/NetBSDProcessTable.c b/netbsd/NetBSDProcessTable.c index 71ae53e70..31c966cf9 100644 --- a/netbsd/NetBSDProcessTable.c +++ b/netbsd/NetBSDProcessTable.c @@ -105,7 +105,7 @@ static void NetBSDProcessTable_updateProcessName(kvm_t* kd, const struct kinfo_p } size_t len = 0; - for (int i = 0; arg[i] != NULL; i++) { + for (size_t i = 0; arg[i] != NULL; i++) { len += strlen(arg[i]) + 1; /* room for arg and trailing space or NUL */ } @@ -118,14 +118,14 @@ static void NetBSDProcessTable_updateProcessName(kvm_t* kd, const struct kinfo_p *s = '\0'; - int start = 0; - int end = 0; - for (int i = 0; arg[i] != NULL; i++) { + size_t start = 0; + size_t end = 0; + for (size_t i = 0; arg[i] != NULL; i++) { size_t n = strlcat(s, arg[i], len); if (i == 0) { end = MINIMUM(n, len - 1); /* check if cmdline ended earlier, e.g 'kdeinit5: Running...' */ - for (int j = end; j > 0; j--) { + for (size_t j = end; j > 0; j--) { if (arg[0][j] == ' ' && arg[0][j - 1] != '\\') { end = (arg[0][j - 1] == ':') ? (j - 1) : j; } diff --git a/openbsd/OpenBSDProcessTable.c b/openbsd/OpenBSDProcessTable.c index ded31e596..404701811 100644 --- a/openbsd/OpenBSDProcessTable.c +++ b/openbsd/OpenBSDProcessTable.c @@ -84,7 +84,7 @@ static void OpenBSDProcessTable_updateProcessName(kvm_t* kd, const struct kinfo_ } size_t len = 0; - for (int i = 0; arg[i] != NULL; i++) { + for (size_t i = 0; arg[i] != NULL; i++) { len += strlen(arg[i]) + 1; /* room for arg and trailing space or NUL */ } @@ -97,14 +97,14 @@ static void OpenBSDProcessTable_updateProcessName(kvm_t* kd, const struct kinfo_ *s = '\0'; - int start = 0; - int end = 0; - for (int i = 0; arg[i] != NULL; i++) { + size_t start = 0; + size_t end = 0; + for (size_t i = 0; arg[i] != NULL; i++) { size_t n = strlcat(s, arg[i], len); if (i == 0) { end = MINIMUM(n, len - 1); /* check if cmdline ended earlier, e.g 'kdeinit5: Running...' */ - for (int j = end; j > 0; j--) { + for (size_t j = end; j > 0; j--) { if (arg[0][j] == ' ' && arg[0][j - 1] != '\\') { end = (arg[0][j - 1] == ':') ? (j - 1) : j; } diff --git a/pcp/PCPProcessTable.c b/pcp/PCPProcessTable.c index 024bef55f..3563100eb 100644 --- a/pcp/PCPProcessTable.c +++ b/pcp/PCPProcessTable.c @@ -310,7 +310,7 @@ static void PCPProcessTable_updateCmdline(Process* process, int pid, int offset, } char* command = value.cp; - int length = strlen(command); + size_t length = strlen(command); if (command[0] != '(') { process->isKernelThread = false; } else { @@ -321,11 +321,11 @@ static void PCPProcessTable_updateCmdline(Process* process, int pid, int offset, process->isKernelThread = true; } - int tokenEnd = 0; - int tokenStart = 0; + size_t tokenEnd = 0; + size_t tokenStart = 0; bool argSepSpace = false; - for (int i = 0; i < length; i++) { + for (size_t i = 0; i < length; i++) { /* htop considers the next character after the last / that is before * basenameOffset, as the start of the basename in cmdline - see * Process_writeCommand */