Skip to content
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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

harship04
Copy link

@harship04 harship04 commented Mar 7, 2025

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.

@babsingh
Copy link
Contributor

babsingh commented Mar 7, 2025

@keithc-ca could you please help in reviewing this PR?

Comment on lines 7574 to 7586
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) {
Copy link
Contributor

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

Copy link
Author

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

@harship04 harship04 force-pushed the systemprocess-x64 branch 2 times, most recently from e45d7db to ea48042 Compare March 11, 2025 11:23
@@ -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 */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after /*.

uintptr_t
omrsysinfo_get_processes(struct OMRPortLibrary *portLibrary, OMRProcessInfoCallback callback, void *userData)
{
return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM;
Copy link
Contributor

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.

Comment on lines 81 to 82
#include <ctype.h>
#include <stdint.h>
Copy link
Contributor

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 just strtoull() without isdigit())
  • stdint.h is already included via inttypes.h

omrsysinfo_get_processes(struct OMRPortLibrary *portLibrary, OMRProcessInfoCallback callback, void *userData)
{
#if defined(LINUX)
DIR *dir = NULL;
Copy link
Contributor

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");

Comment on lines 7576 to 7577
char cmdline_path[PATH_MAX];
char comm_path[PATH_MAX];
Copy link
Contributor

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).

portLibrary->file_close(portLibrary, file);
}
/* If cmdline is empty, try reading from comm */
if (0 == bytes_read) {
Copy link
Contributor

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.

command[i] = ' ';
}
}
/* Call the callback function with the process ID and command */
Copy link
Contributor

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';

}
}
/* Call the callback function with the process ID and command */
callback_result = callback((uintptr_t)strtoull(entry->d_name, NULL, 10), command, userData);
Copy link
Contributor

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);

#else
/* sysinfo_get_processes is not supported on this platform */
return OMRPORT_ERROR_SYSINFO_NOT_SUPPORTED;
#endif /* LINUX */
Copy link
Contributor

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) */

@harship04 harship04 force-pushed the systemprocess-x64 branch 3 times, most recently from 8dcf87f to a947338 Compare March 14, 2025 14:37
@@ -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."
Copy link
Contributor

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.

omrsysinfo_get_processes(struct OMRPortLibrary *portLibrary, OMRProcessInfoCallback callback, void *userData)
{
#if defined(LINUX)
struct dirent *entry = NULL;
Copy link
Contributor

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");

continue;
}
/* Convert name to pid, skipping non-numeric entries. */
char *end = NULL;
Copy link
Contributor

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.

if (NULL == dir) {
int32_t rc = findError(errno);
portLibrary->error_set_last_error(portLibrary, errno, rc);
Trc_PRT_sysinfo_get_processes_failedOpeningProcFS(rc);
Copy link
Contributor

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).

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);
Copy link
Contributor

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).

@harship04 harship04 force-pushed the systemprocess-x64 branch 2 times, most recently from 62cef76 to 2626483 Compare March 14, 2025 20:17
Comment on lines 7572 to 7574
#define ARG_MAX 2097152
char path[PATH_MAX];
char command[ARG_MAX];
Copy link
Contributor

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.

@keithc-ca
Copy link
Contributor

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.

@harship04 harship04 force-pushed the systemprocess-x64 branch 3 times, most recently from 498f43a to 0d65739 Compare March 19, 2025 10:09
/* 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) {
Copy link
Contributor

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.

Comment on lines 7613 to 7636
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;
Copy link
Contributor

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.

Copy link
Author

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.

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);
Copy link
Contributor

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.

@keithc-ca
Copy link
Contributor

Please correct the spelling of "API" in the commit summary line and update the title here (also removing "jfr:").
Lines in the body of the commit message should be no more than 72 characters long.

@harship04 harship04 changed the title jfr: Add an api for system processes Add an API for system processes Mar 20, 2025
Use /proc filesystem to extract command line.
Used cmdline for user space processes and comm for others.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants