summaryrefslogtreecommitdiffstats
path: root/linux/LinuxProcessList.c
diff options
context:
space:
mode:
authorChristian Göttsche <cgzones@googlemail.com>2021-04-04 18:07:26 +0200
committercgzones <cgzones@googlemail.com>2021-06-09 14:40:04 +0200
commit8154125d4bf26fff20241eebe17954254409a522 (patch)
treecebf390fc17b80cd4774a0309b72ba874a977599 /linux/LinuxProcessList.c
parent94d37989b409abc6f1cae8028a9435eb5b04f66a (diff)
Check processes for using deleted shared libraries
Shared libraries can be replaced by an upgrade, highlight processes using deleted shared libraries. Link with highlightDeletedExe setting, enabled by default. Currently only checked on Linux.
Diffstat (limited to 'linux/LinuxProcessList.c')
-rw-r--r--linux/LinuxProcessList.c102
1 files changed, 66 insertions, 36 deletions
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

© 2014-2024 Faster IT GmbH | imprint | privacy policy