-
Notifications
You must be signed in to change notification settings - Fork 400
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add an API for system processes #7681
base: master
Are you sure you want to change the base?
Conversation
@keithc-ca could you please help in reviewing this PR? |
port/unix/omrsysinfo.c
Outdated
DIR *dir = opendir("/proc"); | ||
if (!dir) { | ||
int32_t rc = findError(errno); | ||
portLibrary->error_set_last_error(portLibrary, errno, rc); | ||
Trc_PRT_sysinfo_get_open_file_count_failedOpeningProcFS(rc); | ||
return -1; | ||
} | ||
struct dirent *entry; | ||
char cmdline_path[PATH_MAX]; | ||
char comm_path[PATH_MAX]; | ||
char command[PATH_MAX]; | ||
size_t bytes_read; | ||
while ((entry = readdir(dir)) != NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not strictly legal C code: declarations must be at the beginning of a block.
Please first update this so the additions follow the coding standard. Some examples of things that don't follow those guidelines:
- comparisons (
==
and!=
where the constant is not on the left - conditions with embedded assignments
- uninitialized local variables (e.g.
entry
,bytes_read
above) - code should be indented one tab per level (not 8 spaces)
- missing comments on
#else
and#endif
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have made the changes given by you and updated PR
e45d7db
to
ea48042
Compare
port/common/omrport.c
Outdated
@@ -85,6 +85,7 @@ static OMRPortLibrary MainPortLibraryTable = { | |||
omrsysinfo_get_load_average, /* sysinfo_get_load_average */ | |||
omrsysinfo_get_CPU_utilization, /* sysinfo_get_CPU_utilization */ | |||
omrsysinfo_get_CPU_load, /* sysinfo_get_CPU_load */ | |||
omrsysinfo_get_processes, /*sysinfo_get_processes */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing space after /*
.
port/common/omrsysinfo.c
Outdated
uintptr_t | ||
omrsysinfo_get_processes(struct OMRPortLibrary *portLibrary, OMRProcessInfoCallback callback, void *userData) | ||
{ | ||
return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please indent with a tab instead of spaces.
port/unix/omrsysinfo.c
Outdated
#include <ctype.h> | ||
#include <stdint.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ctype.h
is not needed (we can use juststrtoull()
withoutisdigit()
)stdint.h
is already included viainttypes.h
port/unix/omrsysinfo.c
Outdated
omrsysinfo_get_processes(struct OMRPortLibrary *portLibrary, OMRProcessInfoCallback callback, void *userData) | ||
{ | ||
#if defined(LINUX) | ||
DIR *dir = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest moving this declaration to the point of initialization (after line 7581):
DIR *dir = opendir("/proc");
port/unix/omrsysinfo.c
Outdated
char cmdline_path[PATH_MAX]; | ||
char comm_path[PATH_MAX]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest we only need one of these buffers at a time (write the first path, try to read that file and only write the second path if necessary).
port/unix/omrsysinfo.c
Outdated
portLibrary->file_close(portLibrary, file); | ||
} | ||
/* If cmdline is empty, try reading from comm */ | ||
if (0 == bytes_read) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This must check for negative values:
if (bytes_read <= 0) {
Likewise on line 7615.
port/unix/omrsysinfo.c
Outdated
command[i] = ' '; | ||
} | ||
} | ||
/* Call the callback function with the process ID and command */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
command
should be NUL-terminated here:
command[bytes_read] = '\0';
port/unix/omrsysinfo.c
Outdated
} | ||
} | ||
/* Call the callback function with the process ID and command */ | ||
callback_result = callback((uintptr_t)strtoull(entry->d_name, NULL, 10), command, userData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should use pid
computed above:
callback_result = callback(pid, command, userData);
port/unix/omrsysinfo.c
Outdated
#else | ||
/* sysinfo_get_processes is not supported on this platform */ | ||
return OMRPORT_ERROR_SYSINFO_NOT_SUPPORTED; | ||
#endif /* LINUX */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please correct this comment (and repeat it on line 7635):
#endif /* defined(LINUX) */
8dcf87f
to
a947338
Compare
port/common/omrport.tdf
Outdated
@@ -914,6 +914,8 @@ TraceException=Trc_PRT_find_executable_name_invalidRead Group=sysinfo Overhead=1 | |||
|
|||
TraceException=Trc_PRT_sysinfo_get_tmp_failed_str_covert Group=sysinfo Overhead=1 Level=1 NoEnv Template="omrsysinfo_get_tmp: omrstr_convert() failed to convert unicode to modified utf8 with error code=%d" | |||
|
|||
TraceException=Trc_PRT_sysinfo_get_processes_failedOpeningProcFS Group=sysinfo Overhead=1 Level=1 NoEnv Template="omrsysinfo_get_processes failed opening /proc = %d." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New tracepoints must be added to the end of the file; see https://github.com/eclipse-openj9/openj9/blob/master/doc/diagnostics/AddingTracepoints.md.
port/unix/omrsysinfo.c
Outdated
omrsysinfo_get_processes(struct OMRPortLibrary *portLibrary, OMRProcessInfoCallback callback, void *userData) | ||
{ | ||
#if defined(LINUX) | ||
struct dirent *entry = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Locals should be declared in the smallest block possible; entry
should be declared where it is initialized (on line 7588).
Only these need to be declared here:
uintptr_t callback_result = 0;
DIR *dir = opendir("/proc");
port/unix/omrsysinfo.c
Outdated
continue; | ||
} | ||
/* Convert name to pid, skipping non-numeric entries. */ | ||
char *end = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not strictly legal in C to declare a local here.
port/unix/omrsysinfo.c
Outdated
if (NULL == dir) { | ||
int32_t rc = findError(errno); | ||
portLibrary->error_set_last_error(portLibrary, errno, rc); | ||
Trc_PRT_sysinfo_get_processes_failedOpeningProcFS(rc); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No trailing spaces, please (here and line 7629).
port/unix/omrsysinfo.c
Outdated
portLibrary->str_printf(portLibrary, path, sizeof(path), "/proc/%s/cmdline", entry->d_name); | ||
file = portLibrary->file_open(portLibrary, path, EsOpenRead, 0); | ||
if (0 != file) { | ||
bytes_read = portLibrary->file_read(portLibrary, file, command, sizeof(command) - 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may truncate commands which can be much longer than PATH_MAX
(think megabytes).
62cef76
to
2626483
Compare
port/unix/omrsysinfo.c
Outdated
#define ARG_MAX 2097152 | ||
char path[PATH_MAX]; | ||
char command[ARG_MAX]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not impose a fixed limit on the size of a command line. Greater than 4MB is unreasonable for a single stack frame.
This should not make reference to JFR; yes, it might be one of the first consumers of this new API, but this project aims to be language neutral. |
498f43a
to
0d65739
Compare
port/unix/omrsysinfo.c
Outdated
/* Try reading /proc/[pid]/cmdline. */ | ||
portLibrary->str_printf(portLibrary, path, sizeof(path), "/proc/%s/cmdline", entry->d_name); | ||
file = portLibrary->file_open(portLibrary, path, EsOpenRead, 0); | ||
if (0 != file) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test should be file >= 0
(a negative value signals failure, 0
is a valid file descriptor); same for line 7640.
port/unix/omrsysinfo.c
Outdated
for (;;) { | ||
bytes_read = portLibrary->file_read(portLibrary, file, command, buffer_size - 1); | ||
if (bytes_read < 0) { | ||
break; | ||
} | ||
if (bytes_read == buffer_size - 1) { | ||
/* Buffer may be too small, increase and retry. */ | ||
new_size = buffer_size * 2; | ||
new_command = (char *)portLibrary->mem_reallocate_memory( | ||
portLibrary, | ||
command, | ||
new_size, OMR_GET_CALLSITE(), OMRMEM_CATEGORY_PORT_LIBRARY); | ||
if (NULL == new_command) { | ||
break; /* Stop resizing if allocation fails. */ | ||
} | ||
command = new_command; | ||
buffer_size = new_size; | ||
continue; | ||
} | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be extracted into a new function which can be reused on line 7641.
Note that the second and subsequent reads should not write to the beginning of command
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked kernel header file and The result shows that TASK_COMM_LEN is defined as 16 in the kernel header file
278:#define TASK_COMM_LEN 16
1050: char comm[TASK_COMM_LEN];
1941: BUILD_BUG_ON(sizeof(buf) != TASK_COMM_LEN);
comm is a fixed-size buffer of 16 characters, so it doesn’t need resizing.
port/unix/omrsysinfo.c
Outdated
return (uintptr_t)(intptr_t)rc; | ||
} | ||
/* Allocate initial buffer. */ | ||
char *command = (char *)portLibrary->mem_allocate_memory(portLibrary, buffer_size, OMR_GET_CALLSITE(), OMRMEM_CATEGORY_PORT_LIBRARY); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not legal C code; variables must be declared at the beginning of a block.
Please correct the spelling of "API" in the commit summary line and update the title here (also removing "jfr:"). |
Use /proc filesystem to extract command line. Used cmdline for user space processes and comm for others.
0d65739
to
ff79304
Compare
Use /proc followed by iterating the directories of each process and extracted the command line. Used cmdline for user space processes and comm for others.