Skip to content

Commit dbc3799

Browse files
committed
linux: support for monitoring syscall
Signed-off-by: Fredrik Anderson <sanpeqf@gmail.com>
1 parent 58efa4e commit dbc3799

File tree

5 files changed

+108
-0
lines changed

5 files changed

+108
-0
lines changed

configure.ac

+22
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,27 @@ case "$enable_capabilities" in
659659
esac
660660

661661

662+
AC_ARG_ENABLE([syscall],
663+
[AS_HELP_STRING([--enable-syscall],
664+
[enable 'syscall' monitoring. @<:@default=check@:>@])],
665+
[],
666+
[enable_syscall=check]
667+
)
668+
669+
if test "x$enable_syscall" = xcheck; then
670+
if "$cross_compiling" != no; then
671+
enable_syscall=yes
672+
elif test -f /proc/self/syscall && test -s /proc/self/syscall; then
673+
enable_syscall=yes
674+
else
675+
enable_syscall=no
676+
fi
677+
fi
678+
if test "x$enable_syscall" = xyes; then
679+
AC_DEFINE([HAVE_SYSCALL], [1], [Define if syscall monitoring enabled.])
680+
fi
681+
682+
662683
AC_ARG_ENABLE([delayacct],
663684
[AS_HELP_STRING([--enable-delayacct],
664685
[enable Linux delay accounting support; requires pkg-config, libnl-3 and libnl-genl-3 @<:@default=check@:>@])],
@@ -859,6 +880,7 @@ AC_MSG_RESULT([
859880
(Linux) delay accounting: $enable_delayacct
860881
(Linux) sensors: $enable_sensors
861882
(Linux) capabilities: $enable_capabilities
883+
(Linux) syscall: $enable_syscall
862884
unicode: $enable_unicode
863885
affinity: $enable_affinity
864886
unwind: $enable_unwind

linux/LinuxProcess.c

+32
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = {
112112
#endif
113113
[GPU_TIME] = { .name = "GPU_TIME", .title = "GPU_TIME ", .description = "Total GPU time", .flags = PROCESS_FLAG_LINUX_GPU, .defaultSortDesc = true, },
114114
[GPU_PERCENT] = { .name = "GPU_PERCENT", .title = " GPU% ", .description = "Percentage of the GPU time the process used in the last sampling", .flags = PROCESS_FLAG_LINUX_GPU, .defaultSortDesc = true, },
115+
#ifdef HAVE_SYSCALL
116+
[SYSCALL] = { .name = "SYSCALL", .title = "SYSCALL", .description = "Current syscall of the process", .flags = PROCESS_FLAG_LINUX_SYSCALL, .autoWidth = true, },
117+
#endif
115118
};
116119

117120
Process* LinuxProcess_new(const Machine* host) {
@@ -362,6 +365,26 @@ static void LinuxProcess_rowWriteField(const Row* super, RichString* str, Proces
362365
xSnprintf(buffer, n, "N/A ");
363366
}
364367
break;
368+
#ifdef HAVE_SYSCALL
369+
case SYSCALL: {
370+
char syscall[32];
371+
switch (lp->syscall_state) {
372+
case SYSCALL_STATE_CALLING:
373+
xSnprintf(syscall, sizeof(syscall), "%d", lp->syscall_num);
374+
break;
375+
case SYSCALL_STATE_RUNNING:
376+
attr = CRT_colors[PROCESS_RUN_STATE];
377+
xSnprintf(syscall, sizeof(syscall), "running");
378+
break;
379+
default:
380+
attr = CRT_colors[PROCESS_SHADOW];
381+
xSnprintf(syscall, sizeof(syscall), "N/A");
382+
}
383+
xSnprintf(buffer, n, "%-*s ", Row_fieldWidths[SYSCALL], syscall);
384+
RichString_appendWide(str, attr, buffer);
385+
return;
386+
}
387+
#endif
365388
default:
366389
Process_writeField(this, str, field);
367390
return;
@@ -466,6 +489,15 @@ static int LinuxProcess_compareByKey(const Process* v1, const Process* v2, Proce
466489
return SPACESHIP_NUMBER(p1->gpu_time, p2->gpu_time);
467490
case ISCONTAINER:
468491
return SPACESHIP_NUMBER(v1->isRunningInContainer, v2->isRunningInContainer);
492+
#ifdef HAVE_SYSCALL
493+
case SYSCALL: {
494+
int r = SPACESHIP_NUMBER(p1->syscall_state, p2->syscall_state);
495+
if (r)
496+
return r;
497+
498+
return SPACESHIP_NUMBER(p1->syscall_num, p2->syscall_num);
499+
}
500+
#endif
469501
default:
470502
return Process_compareByKey_Base(v1, v2, key);
471503
}

linux/LinuxProcess.h

+12
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ in the source distribution for its full text.
3131
#define PROCESS_FLAG_LINUX_AUTOGROUP 0x00080000
3232
#define PROCESS_FLAG_LINUX_GPU 0x00100000
3333
#define PROCESS_FLAG_LINUX_CONTAINER 0x00200000
34+
#define PROCESS_FLAG_LINUX_SYSCALL 0x00400000
35+
36+
typedef enum SyscallState_ {
37+
SYSCALL_STATE_RUNNING,
38+
SYSCALL_STATE_CALLING,
39+
SYSCALL_STATE_NA,
40+
} SyscallState;
3441

3542
typedef struct LinuxProcess_ {
3643
Process super;
@@ -118,6 +125,11 @@ typedef struct LinuxProcess_ {
118125
/* Autogroup scheduling (CFS) information */
119126
long int autogroup_id;
120127
int autogroup_nice;
128+
129+
#ifdef HAVE_SYSCALL
130+
SyscallState syscall_state;
131+
int syscall_num;
132+
#endif
121133
} LinuxProcess;
122134

123135
extern int pageSize;

linux/LinuxProcessTable.c

+41
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,41 @@ static void LinuxProcessTable_readCwd(LinuxProcess* process, openat_arg_t procFd
10981098
free_and_xStrdup(&process->super.procCwd, pathBuffer);
10991099
}
11001100

1101+
/*
1102+
* Read /proc/<pid>/syscall (thread-specific data)
1103+
*/
1104+
#ifdef HAVE_SYSCALL
1105+
static void LinuxProcessTable_readSyscall(LinuxProcess* process, openat_arg_t procFd) {
1106+
char buffer[1024];
1107+
1108+
ssize_t r = xReadfileat(procFd, "syscall", buffer, sizeof(buffer));
1109+
if (r <= 0) {
1110+
goto failed;
1111+
}
1112+
1113+
char* numPtr = buffer;
1114+
process->syscall_num = fast_strtoull_dec(&numPtr, r);
1115+
if (*numPtr == ' ') {
1116+
process->syscall_state = SYSCALL_STATE_CALLING;
1117+
Row_updateFieldWidth(SYSCALL, snprintf(NULL, 0, "%d", process->syscall_num));
1118+
return;
1119+
}
1120+
1121+
char* eol = String_strchrnul(buffer, '\n');
1122+
*eol = '\0';
1123+
1124+
if (String_eq(buffer, "running")) {
1125+
process->syscall_state = SYSCALL_STATE_RUNNING;
1126+
Row_updateFieldWidth(SYSCALL, strlen("running"));
1127+
return;
1128+
}
1129+
1130+
failed:
1131+
process->syscall_state = SYSCALL_STATE_NA;
1132+
Row_updateFieldWidth(SYSCALL, strlen("N/A"));
1133+
}
1134+
#endif /* HAVE_SYSCALL */
1135+
11011136
/*
11021137
* Read /proc/<pid>/exe (process-shared data)
11031138
*/
@@ -1694,6 +1729,12 @@ static bool LinuxProcessTable_recurseProcTree(LinuxProcessTable* this, openat_ar
16941729
LinuxProcessTable_readCwd(lp, procFd, mainTask);
16951730
}
16961731

1732+
#ifdef HAVE_SYSCALL
1733+
if (ss->flags & PROCESS_FLAG_LINUX_SYSCALL) {
1734+
LinuxProcessTable_readSyscall(lp, procFd);
1735+
}
1736+
#endif
1737+
16971738
if ((ss->flags & PROCESS_FLAG_LINUX_AUTOGROUP) && this->haveAutogroup) {
16981739
LinuxProcessTable_readAutogroup(lp, procFd, mainTask);
16991740
}

linux/ProcessField.h

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ in the source distribution for its full text.
5151
GPU_TIME = 132, \
5252
GPU_PERCENT = 133, \
5353
ISCONTAINER = 134, \
54+
SYSCALL = 135, \
5455
// End of list
5556

5657

0 commit comments

Comments
 (0)