-
Notifications
You must be signed in to change notification settings - Fork 401
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 native libraries #7682
base: master
Are you sure you want to change the base?
Conversation
@keithc-ca could you please help in reviewing this PR? |
port/common/omrsl.c
Outdated
/** | ||
* Native Libraries | ||
* | ||
* This function is called go get all the shared libraries loaded by the Java process. |
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 specific to Java: please remove that reference.
port/unix/omrsl.c
Outdated
intptr_t fd=portLibrary->file_open(portLibrary,"/proc/self/maps",EsOpenRead,0); | ||
if(0 > fd){ | ||
return -1; | ||
} | ||
char buffer[READ_CHUNK_SIZE +1]; | ||
char carryOver[READ_CHUNK_SIZE +1]=""; | ||
intptr_t bytesRead = 0; | ||
uintptr_t result=0; | ||
while (0<(bytesRead = portLibrary->file_read(portLibrary, fd, buffer, READ_CHUNK_SIZE))){ |
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
- code should be indented consistently one tab per level (not spaces)
- missing comments on
#else
and#endif
- binary operators (e.g.
+
,=
,<
) should have a space before and after - a space should appear consistently after
if
,while
,switch
, etc. - compound expressions should have parentheses to avoid any concern for precedence rules
- a space should appear before
{
for eachif
,while
,else
etc, block
3b237c5
to
a21d95e
Compare
include_core/omrport.h
Outdated
@@ -2115,6 +2116,8 @@ typedef struct OMRPortLibrary { | |||
uintptr_t (*sl_open_shared_library)(struct OMRPortLibrary *portLibrary, char *name, uintptr_t *descriptor, uintptr_t flags) ; | |||
/** see @ref omrsl.c::omrsl_lookup_name "omrsl_lookup_name"*/ | |||
uintptr_t (*sl_lookup_name)(struct OMRPortLibrary *portLibrary, uintptr_t descriptor, char *name, uintptr_t *func, const char *argSignature) ; | |||
/** see @ref omrsl.c::omrsl_get_shared_libraries "omrsl_open_shared_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.
Please correct the comment:
/** see @ref omrsl.c::omrsl_get_libraries "omrsl_get_libraries"*/
port/common/omrport.c
Outdated
@@ -29,6 +29,7 @@ | |||
#include "omrport.h" | |||
#include "omrportpriv.h" | |||
#include "ut_omrport.h" | |||
#include "omrsl.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.
I don't think this is wanted: the declaration of omrsl_get_libraries()
should be in omrportpriv.h
instead.
port/common/omrsl.h
Outdated
uintptr_t | ||
omrsl_get_libraries(struct OMRPortLibrary *portLibrary, OMRLibraryInfoCallback callback, void *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.
Please move this to omrportpriv.h
.
port/unix/omrsl.c
Outdated
/* Max Length of Library name */ | ||
#define READ_CHUNK_SIZE 4096 |
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.
The comment isn't really accurate, should end with a period, and might be better placed just before the function that uses it.
port/unix/omrsl.c
Outdated
/** | ||
* Native Libraries | ||
* | ||
* This function is called go get all the shared libraries loaded by a process. |
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.
Just one space between "shared" and "libraries", please.
port/unix/omrsl.c
Outdated
count = sscanf( | ||
line,"%p-%p %4s %lx %x:%x %lu %s", | ||
&addrLow, &addrHigh, permissions, | ||
&offset, &devMajor, &devMinor, &inode, path); |
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.
The first two arguments (at least) should be on lines by themselves:
count = sscanf(
line,
"%p-%p %4s %lx %x:%x %lu %s",
&addrLow, &addrHigh, permissions,
&offset, &devMajor, &devMinor, &inode, path);
port/unix/omrsl.c
Outdated
result = callback(path,addrLow,addrHigh, userData); | ||
} | ||
if (0 != result) { | ||
portLibrary->file_close(portLibrary, fd); | ||
return result; | ||
} |
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 spaces, break
avoids repetition:
result = callback(path, addrLow, addrHigh, userData);
if (0 != result) {
break;
}
port/unix/omrsl.c
Outdated
#else | ||
/* Platform not supported */ | ||
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.
Missing comment, missing period, inconsistent indentation:
#else /* defined(LINUX) */
/* Platform not supported. */
return OMRPORT_ERROR_NOT_SUPPORTED_ON_THIS_PLATFORM;
port/unix/omrsl.c
Outdated
bytesRead = portLibrary->file_read(portLibrary, fd, buffer, READ_CHUNK_SIZE); | ||
do { |
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.
Moving the read inside the loop avoids repetition:
do {
bytesRead = portLibrary->file_read(portLibrary, fd, buffer, sizeof(buffer) - 1);
(line 522 should then be deleted)
port/unix/omrsl.c
Outdated
while (NULL != line) { | ||
nextLine = strtok(NULL, "\n"); | ||
if (NULL == nextLine && !lastCharIsNewline) { | ||
portLibrary->str_printf(portLibrary, carryOver, sizeof(carryOver), "%s", line); |
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.
line
may point within combinedBuffer
and thus may not fit in carryOver
: this must be checked here.
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 will change the length of the buffer to 4146 bytes. The max path length in Unix is 4096 bytes and I am considering another 50 bytes for the addresses, inode number etc. That way line can never exceed the size of the carryOver buffer.
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 should be defined within the LINUX block and be defined in terms of PATH_MAX:
#define READ_CHUNK_SIZE (PATH_MAX + 50)
However, I'm not sure that addresses my concern. No matter what size the buffers are, parts of combinedBuffer
and carryOver
may need more space than is available.
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 don't think we want line 512 any more - line 502 already wrote to carryOver
. After removing that line, line 510 becomes redundant.
e619b0d
to
af91ad3
Compare
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 fix the commit message:
- lines in the body should be no more than 72 characters long
- this does not (nor should it) "combine multiple sections"
port/common/omrport.c
Outdated
@@ -840,3 +841,4 @@ omrport_allocate_library(struct OMRPortLibrary **portLibrary) | |||
} | |||
return 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.
Please remove this extra blank line (the last two characters should be "}\n"
).
port/common/omrsl.c
Outdated
@@ -135,3 +135,19 @@ omrsl_startup(struct OMRPortLibrary *portLibrary) | |||
} | |||
|
|||
|
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 delete this blank line (we don't need more than one in a row).
port/common/omrsl.c
Outdated
/** | ||
* Native Libraries | ||
* | ||
* This function is called to get all the shared libraries loaded by a process. |
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 (here or on any line you add or modify).
port/unix/omrsl.c
Outdated
@@ -45,6 +45,7 @@ | |||
#include <errno.h> | |||
#include <dlfcn.h> | |||
#include "ut_omrport.h" | |||
#include "omrport.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.
Please remove this (see line 76).
port/unix/omrsl.c
Outdated
while (NULL != line) { | ||
nextLine = strtok(NULL, "\n"); | ||
if (NULL == nextLine && !lastCharIsNewline) { | ||
portLibrary->str_printf(portLibrary, carryOver, sizeof(carryOver), "%s", line); |
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 should be defined within the LINUX block and be defined in terms of PATH_MAX:
#define READ_CHUNK_SIZE (PATH_MAX + 50)
However, I'm not sure that addresses my concern. No matter what size the buffers are, parts of combinedBuffer
and carryOver
may need more space than is available.
if (0 != result) { | ||
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.
Lines 518-520 can go before line 517 (only there might result be non-zero).
port/unix/omrsl.c
Outdated
portLibrary->file_close(portLibrary, fd); | ||
return result; | ||
#else /* defined(LINUX) */ | ||
/* Platform not supported. */ |
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 indentation is still incorrect.
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. |
port/unix/omrsl.c
Outdated
omrsl_get_libraries(struct OMRPortLibrary *portLibrary, OMRLibraryInfoCallback callback, void *userData) | ||
{ | ||
#if defined(LINUX) | ||
#include <limits.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.
This isn't likely to work (within the function body); please move it near the top of the file (if needed).
port/unix/omrsl.c
Outdated
carryOver[0] = '\0'; | ||
intptr_t fd = portLibrary->file_open(portLibrary, "/proc/self/maps", EsOpenRead, 0); |
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 isn't legal C code (an assignment statement before a declaration).
port/unix/omrsl.c
Outdated
int portableError = portLibrary->error_last_error_number(portLibrary); | ||
Trc_PRT_find_executable_name_failedOpeningProcFS(portableError); | ||
portLibrary->error_set_last_error_with_message(portLibrary, portableError, "Failed to open /proc fs"); | ||
return -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.
The return type is unsigned; a negative value is not appropriate.
port/unix/omrsl.c
Outdated
char *nextLine = strtok(NULL, "\n"); | ||
if ((NULL == nextLine) && (0 == lastCharIsNewline)) { | ||
int readChars = portLibrary->str_printf(portLibrary, carryOver, sizeof(carryOver), "%s", line); | ||
if(readChars >= sizeof(carryOver)) { |
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.
Space before (
, please.
port/unix/omrsl.c
Outdated
while (NULL != line) { | ||
char *nextLine = strtok(NULL, "\n"); | ||
if ((NULL == nextLine) && (0 == lastCharIsNewline)) { | ||
int readChars = portLibrary->str_printf(portLibrary, carryOver, sizeof(carryOver), "%s", line); |
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.
int
is inappropriate: str_printf
returns uintptr_t
port/unix/omrsl.c
Outdated
} | ||
line = nextLine; | ||
} | ||
} while (bytesRead < 0); |
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.
bytesRead
cannot be negative here (see lines 486-488); please replace the "do...while" loop with a for (;;)
loop.
port/unix/omrsl.c
Outdated
carryOver[0] = '\0'; | ||
if (-1 == fd) { | ||
portableError = portLibrary->error_last_error_number(portLibrary); | ||
Trc_PRT_find_executable_name_failedOpeningProcFS(portableError); |
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 create a new tracepoint, that one has a different meaning/purpose.
port/unix/omrsl.c
Outdated
portLibrary->error_set_last_error_with_message( | ||
portLibrary, | ||
portableError, | ||
"Failed to open /proc fs"); |
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.
The error message should mention the actual path for which open failed.
port/unix/omrsl.c
Outdated
portLibrary, | ||
portableError, | ||
"Failed to open /proc fs"); | ||
return (uintptr_t)portableError; |
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.
Casts can't change both the size and signedness in one step; change the size, then the signedness:
return (uintptr_t)(intptr_t)portableError;
port/unix/omrsl.c
Outdated
portLibrary->error_set_last_error_with_message( | ||
portLibrary, | ||
portableError, | ||
"Line from /proc/self/maps was truncated due to exceeding buffer size"); |
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.
The part after "truncated" doesn't help; please omit it.
port/unix/omrsl.c
Outdated
{ | ||
#if defined(LINUX) | ||
/* Length of buffer. */ | ||
#define READ_CHUNK_SIZE (PATH_MAX + 100) |
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 don't indent macro definitions.
port/unix/omrsl.c
Outdated
char *nextLine = strtok(NULL, "\n"); | ||
if ((NULL == nextLine) && (0 == lastCharIsNewline)) { | ||
readChars = portLibrary->str_printf(portLibrary, carryOver, sizeof(carryOver), "%s", line); | ||
if (readChars >= sizeof(carryOver)) { | ||
portableError = portLibrary->error_last_error_number(portLibrary); | ||
portLibrary->error_set_last_error_with_message( | ||
portLibrary, | ||
portableError, | ||
"Line from /proc/self/maps was truncated"); | ||
carryOver[0] = '\0'; | ||
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.
I don't think the timing of this is appropriate: the content of line
should be consumed before considering text after the newline.
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.
The only reason I am extracting nextLine
in the start is because if nextLine
is NULL and the last character of the current line
is not \n
, I want the line
to be copied to the carryOver
buffer because the line is incomplete. I don't want the line to be processed further (extracting the name and addresses). I don't want to end up extracting the name and address ranges for incomplete lines. Hence I am adding this check in the start itself.
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.
That's not how strtok()
works. If combinedBuffer
doesn't contain a newline, then line
will be NULL
.
By the way, we would use strtok_r()
instead (it is thread-safe).
But I don't think we need to use strtok_r()
either: Instead, this should use file_read_text()
which reads only up to the first newline (that will fit in the supplied buffer). Only if one is not present should it be joined to any previous fragment. When a newline is found, the line should be scanned and the information provided to the callback.
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 removed the carryOver
buffer completely as I have changed the implementation to use file_read_text( )
. Since the function reads a single line which fits in the buffer
.
27ada4e
to
f8455bf
Compare
"Failed to open /proc/self/maps"); | ||
return (uintptr_t)(intptr_t)portableError; | ||
} | ||
while (NULL != portLibrary->file_read_text(portLibrary, fd, buffer, sizeof(buffer))) { |
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.
file_read_text()
may return a partial line if it doesn't fit in the supplied buffer; this needs to check whether the line ends with a newline. If it does not, it might be reasonable for this function to signal failure (an unexpectedly long path name).
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 let me know if the function should signal failure and stop further enumeration or continue with reading the further entries in the file?
port/unix/omrsl.c
Outdated
memset(path, 0, sizeof(path)); | ||
count = sscanf( | ||
buffer, | ||
"%p-%p %4s %lx %x:%x %lu %s", |
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 that the local path
is not needed; instead of %s
for the final pattern, use %n
to learn the offset within buffer
where the path is located.
Use /proc file system to capture the dependent libraries. Invoke the callback on each library.
Use /proc file system to capture the dependent libraries. Combine multiple sections into one and iterate over the list plus invoke the callback