summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Process.c11
-rw-r--r--Process.h3
-rw-r--r--linux/LinuxProcessList.c102
3 files changed, 77 insertions, 39 deletions
diff --git a/Process.c b/Process.c
index e30c6808..4223adc1 100644
--- a/Process.c
+++ b/Process.c
@@ -472,7 +472,8 @@ void Process_makeCommandStr(Process *this) {
const int baseAttr = Process_isThread(this) ? CRT_colors[PROCESS_THREAD_BASENAME] : CRT_colors[PROCESS_BASENAME];
const int commAttr = Process_isThread(this) ? CRT_colors[PROCESS_THREAD_COMM] : CRT_colors[PROCESS_COMM];
- const int delAttr = CRT_colors[FAILED_READ];
+ const int delExeAttr = CRT_colors[FAILED_READ];
+ const int delLibAttr = CRT_colors[PROCESS_TAG];
/* Establish some shortcuts to data we need */
const char *cmdline = this->cmdline;
@@ -529,14 +530,18 @@ void Process_makeCommandStr(Process *this) {
WRITE_HIGHLIGHT(exeBasenameOffset, exeBasenameLen, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM);
WRITE_HIGHLIGHT(exeBasenameOffset, exeBasenameLen, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME);
if (this->procExeDeleted)
- WRITE_HIGHLIGHT(exeBasenameOffset, exeBasenameLen, delAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED);
+ WRITE_HIGHLIGHT(exeBasenameOffset, exeBasenameLen, delExeAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED);
+ else if (this->usesDeletedLib)
+ WRITE_HIGHLIGHT(exeBasenameOffset, exeBasenameLen, delLibAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED);
str = stpcpy(str, procExe);
} else {
if (haveCommInExe)
WRITE_HIGHLIGHT(0, exeBasenameLen, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM);
WRITE_HIGHLIGHT(0, exeBasenameLen, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME);
if (this->procExeDeleted)
- WRITE_HIGHLIGHT(0, exeBasenameLen, delAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED);
+ WRITE_HIGHLIGHT(0, exeBasenameLen, delExeAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED);
+ else if (this->usesDeletedLib)
+ WRITE_HIGHLIGHT(0, exeBasenameLen, delLibAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED);
str = stpcpy(str, procExe + exeBasenameOffset);
}
diff --git a/Process.h b/Process.h
index 2ff1aa09..f4daac06 100644
--- a/Process.h
+++ b/Process.h
@@ -163,6 +163,9 @@ typedef struct Process_ {
/* Tells if the executable has been replaced in the filesystem since start */
bool procExeDeleted;
+ /* Tells if the process uses replaced shared libraries since start */
+ bool usesDeletedLib;
+
/* CPU number last executed on */
int processor;
diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c
index 79706c04..1c5359fc 100644
--- a/linux/LinuxProcessList.c
+++ b/linux/LinuxProcessList.c
@@ -517,18 +517,24 @@ static void LinuxProcessList_calcLibSize_helper(ATTR_UNUSED ht_key_t key, void*
*d += v->size;
}
-static uint64_t LinuxProcessList_calcLibSize(openat_arg_t procFd) {
+static void LinuxProcessList_readMaps(LinuxProcess* process, openat_arg_t procFd, bool calcSize, bool checkDeletedLib) {
+ Process* proc = (Process*)process;
+
+ proc->usesDeletedLib = false;
+
FILE* mapsfile = fopenat(procFd, "maps", "r");
if (!mapsfile)
- return 0;
+ return;
- Hashtable* ht = Hashtable_new(64, true);
+ Hashtable* ht = NULL;
+ if (calcSize)
+ ht = Hashtable_new(64, true);
char buffer[1024];
while (fgets(buffer, sizeof(buffer), mapsfile)) {
uint64_t map_start;
uint64_t map_end;
- char map_perm[5];
+ bool map_execute;
unsigned int map_devmaj;
unsigned int map_devmin;
uint64_t map_inode;
@@ -548,8 +554,7 @@ static uint64_t LinuxProcessList_calcLibSize(openat_arg_t procFd) {
if (' ' != *readptr++)
continue;
- memcpy(map_perm, readptr, 4);
- map_perm[4] = '\0';
+ map_execute = (readptr[2] == 'x');
readptr += 4;
if (' ' != *readptr++)
continue;
@@ -575,38 +580,58 @@ static uint64_t LinuxProcessList_calcLibSize(openat_arg_t procFd) {
if (!map_inode)
continue;
- LibraryData* libdata = Hashtable_get(ht, map_inode);
- if (!libdata) {
- libdata = xCalloc(1, sizeof(LibraryData));
- Hashtable_put(ht, map_inode, libdata);
+ if (calcSize) {
+ LibraryData* libdata = Hashtable_get(ht, map_inode);
+ if (!libdata) {
+ libdata = xCalloc(1, sizeof(LibraryData));
+ Hashtable_put(ht, map_inode, libdata);
+ }
+
+ libdata->size += map_end - map_start;
+ libdata->exec |= map_execute;
}
- libdata->size += map_end - map_start;
- libdata->exec |= 'x' == map_perm[2];
+ if (checkDeletedLib && map_execute && !proc->usesDeletedLib) {
+ while (*readptr == ' ')
+ readptr++;
+
+ if (*readptr != '/')
+ continue;
+
+ if (String_startsWith(readptr, "/memfd:"))
+ continue;
+
+ if (strstr(readptr, " (deleted)\n")) {
+ proc->usesDeletedLib = true;
+ if (!calcSize)
+ break;
+ }
+ }
}
fclose(mapsfile);
- uint64_t total_size = 0;
- Hashtable_foreach(ht, LinuxProcessList_calcLibSize_helper, &total_size);
+ if (calcSize) {
+ uint64_t total_size = 0;
+ Hashtable_foreach(ht, LinuxProcessList_calcLibSize_helper, &total_size);
- Hashtable_delete(ht);
+ Hashtable_delete(ht);
- return total_size / pageSize;
+ process->m_lrs = total_size / pageSize;
+ }
}
-static bool LinuxProcessList_readStatmFile(LinuxProcess* process, openat_arg_t procFd, bool performLookup, unsigned long long realtimeMs) {
+static bool LinuxProcessList_readStatmFile(LinuxProcess* process, openat_arg_t procFd) {
FILE* statmfile = fopenat(procFd, "statm", "r");
if (!statmfile)
return false;
- long tmp_m_lrs = 0;
int r = fscanf(statmfile, "%ld %ld %ld %ld %ld %ld %ld",
&process->super.m_virt,
&process->super.m_resident,
&process->m_share,
&process->m_trs,
- &tmp_m_lrs,
+ &process->m_lrs,
&process->m_drs,
&process->m_dt);
fclose(statmfile);
@@ -614,22 +639,6 @@ static bool LinuxProcessList_readStatmFile(LinuxProcess* process, openat_arg_t p
if (r == 7) {
process->super.m_virt *= pageSizeKB;
process->super.m_resident *= pageSizeKB;
-
- if (tmp_m_lrs) {
- process->m_lrs = tmp_m_lrs;
- } else if (performLookup) {
- // Check if we really should recalculate the M_LRS value for this process
- uint64_t passedTimeInMs = realtimeMs - process->last_mlrs_calctime;
-
- uint64_t recheck = ((uint64_t)rand()) % 2048;
-
- if(passedTimeInMs > 2000 || passedTimeInMs > recheck) {
- process->last_mlrs_calctime = realtimeMs;
- process->m_lrs = LinuxProcessList_calcLibSize(procFd);
- }
- } else {
- // Keep previous value
- }
}
return r == 7;
@@ -1340,9 +1349,30 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
if (settings->flags & PROCESS_FLAG_IO)
LinuxProcessList_readIoFile(lp, procFd, pl->realtimeMs);
- if (!LinuxProcessList_readStatmFile(lp, procFd, !!(settings->flags & PROCESS_FLAG_LINUX_LRS_FIX), pl->realtimeMs))
+ if (!LinuxProcessList_readStatmFile(lp, procFd))
goto errorReadingProcess;
+ {
+ bool prev = proc->usesDeletedLib;
+
+ if ((lp->m_lrs == 0 && (settings->flags & PROCESS_FLAG_LINUX_LRS_FIX)) || settings->highlightDeletedExe) {
+ // Check if we really should recalculate the M_LRS value for this process
+ uint64_t passedTimeInMs = pl->realtimeMs - lp->last_mlrs_calctime;
+
+ uint64_t recheck = ((uint64_t)rand()) % 2048;
+
+ if (passedTimeInMs > 2000 || passedTimeInMs > recheck) {
+ lp->last_mlrs_calctime = pl->realtimeMs;
+ LinuxProcessList_readMaps(lp, procFd, settings->flags & PROCESS_FLAG_LINUX_LRS_FIX, settings->highlightDeletedExe);
+ }
+ } else {
+ /* reset if setting got disabled */
+ proc->usesDeletedLib = false;
+ }
+
+ proc->mergedCommand.exeChanged |= prev ^ proc->usesDeletedLib;
+ }
+
if ((settings->flags & PROCESS_FLAG_LINUX_SMAPS) && !Process_isKernelThread(proc)) {
if (!parent) {
// Read smaps file of each process only every second pass to improve performance