-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
JDK-8320890: [AIX] Find a better way to mimic dl handle equality #16920
Conversation
👋 Welcome back jkern! A progress list of the required criteria for merging this PR into |
Webrevs
|
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.
Excellent, this is how I have pictured a good solution. Very nice.
A number of remarks, but nothing fundamental.
src/hotspot/os/aix/os_aix.cpp
Outdated
}; | ||
constexpr int max_handletable = 1024; | ||
static int g_handletable_used = 0; | ||
static struct handletableentry g_handletable[max_handletable] = {{0,0,0,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.
style nits:
- we usually write the * behind type, not before var name
{{0,0}}
-> insert spaces
src/hotspot/os/aix/os_aix.cpp
Outdated
// file with filename does not exist | ||
result = ::dlopen(filename, dflags); | ||
if (result != nullptr) { | ||
assert(false, "dll_load: Could not stat() file %s, but dlopen() worked; Have to improve stat()", filename); |
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.
use assert(result != nullptr) and remove condition
::strncpy(ebuf, "dll_load: empty filename specified", ebuflen - 1); | ||
if (ebuf != nullptr && ebuflen > 0) { | ||
::strncpy(ebuf, "dll_load: empty filename specified", ebuflen - 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.
Are there any cases where we don't hand in the error buffer? If so, I would just assert ebuf and ebuflen. No need for this kind of flexibility.
src/hotspot/os/aix/os_aix.cpp
Outdated
@@ -3033,29 +3049,134 @@ void os::jfr_report_memory_info() {} | |||
|
|||
// Simulate the library search algorithm of dlopen() (in os::dll_load) | |||
int os::Aix::stat64x_via_LIBPATH(const char* path, struct stat64x* stat) { |
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 need to export this, make it filescope static
- please return bool, with false = error
- please rename it to something like "search_file_in_LIBPATH"
src/hotspot/os/aix/os_aix.cpp
Outdated
// if exist, strip off trailing (shr_64.o) or similar | ||
int idx = strlen(path2) - 1; | ||
if (path2[idx] == ')') { | ||
while (path2[idx] != '(' && idx > 0) idx--; |
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.
? Why not strrchr()
?
src/hotspot/os/aix/os_aix.cpp
Outdated
return result; | ||
} | ||
|
||
int os::Aix::dlclose(void* lib) { |
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.
can we call lib something better, maybe "handle"?
src/hotspot/os/aix/os_aix.cpp
Outdated
} | ||
// refcount == 0, so we have to ::dlclose() the lib | ||
// and delete the entry from the array. | ||
res = ::dlclose(lib); |
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.
Handle dlclose error. We expect it to work; if it doesn't, it indicates that something is wrong with the handle logic, e.g. an invalid or already closed handle had been handed in. So, assert.
src/hotspot/os/aix/os_aix.cpp
Outdated
// specific AIX versions for ::dlopen() and ::dlclose(), which handles the struct g_handletable | ||
// filled by os::dll_load(). This way we mimic dl handle equality for a library | ||
// opened a second time, as it is implemented on other platforms. | ||
void* os::Aix::dlopen(const char* filename, int Flags) { |
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.
Does not need to be exported, nor does os::AIX::dlclose. Make file scope static. See my remarks in os_posix.cpp.
src/hotspot/os/aix/os_aix.hpp
Outdated
// filled by os::dll_load(). This way we mimic dl handle equality for a library | ||
// opened a second time, as it is implemented on other platforms. | ||
static void* dlopen(const char* filename, int Flags); | ||
static int dlclose(void* lib); |
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.
Remove; should not be exported.
src/hotspot/os/posix/os_posix.cpp
Outdated
@@ -731,7 +732,7 @@ void os::dll_unload(void *lib) { | |||
if (l_path == nullptr) { | |||
l_path = "<not available>"; | |||
} | |||
int res = ::dlclose(lib); | |||
int res = AIX_ONLY(os::Aix)::dlclose(lib); |
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.
Lets do this cleaner, and in the style of hotspot coding elsewhere:
- introduce a new function "os::pd_dll_unload(handle, errorbuf, errbuflen)". Add it to os.hpp, but somewhere non-public. The implementations will live in os_aix.cpp, os_bsd.cpp and os_linux.cpp.
- make os::Aix::dlclose -> os::pd_dll_unload; the only difference is that you should fill in error buffer with either ::dlerror or, if you have errors in handle table, a text describing that error
- on all other posix platforms (os_bsd.cpp + os_linux.cpp), implement a minimal version of os::pd_dll_unload() that calls ::dlunload, and on error calls ::dlerror and copies the string into errbuf
- Here, call os::pd_dll_unload instead of ::dlclose/os::aix::dlclose
- change the JFR code below to not use ::dlerror but the string returned from the buffer
@tstuefe Sorry to tag you. Can you review the code. Once this code goes in I can push in my changes. |
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.
Is this libpath parsing code copied from the R3 kernel? If yes, pls make sure there are no licensing issues.
src/hotspot/os/aix/os_aix.cpp
Outdated
}; | ||
constexpr int max_handletable = 1024; | ||
static int g_handletable_used = 0; | ||
static struct handletableentry g_handletable[max_handletable] = {{0, 0, 0, 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.
I would move all that new and clearly delineated dlopen stuff into an own file, e.g. dlopen_aix.cpp or porting_aix.cpp (in porting_aix.cpp, we already have wrappers for other functions). os_aix.cpp is already massive.
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 moved the static variable declarations and the functions Aix_dlopen(), search_file_in_LIBPATH(), rtv_linkedin_libpath()
and os::pd_dll_unload()
to porting_aix.cpp. This links, but in my opinion os::pd_dll_unload()
should reside in os_aix.cpp, because it is member of the os class. But there it will not compile anymore if the static variables are moved away.
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, what I meant was to provide a "libc-like" equivalent for dlopen, similar to what we do with dladdr (see
jdk/src/hotspot/os/aix/porting_aix.cpp
Line 306 in b767682
int dladdr(void* addr, Dl_info* info) { |
But never mind; I am also fine with moving os::pd_dlopen into a different cpp file, e.g. "dlopen_aix.cpp". Just move it out of os_aix.cpp, since that is already massive and you add >300 lines of more code and more dependencies.
src/hotspot/os/aix/os_aix.cpp
Outdated
static const char* libpath = 0; | ||
|
||
if (libpath) | ||
return libpath; |
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.
{ }
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.
done
src/hotspot/os/aix/os_aix.cpp
Outdated
@@ -1108,6 +1125,282 @@ bool os::dll_address_to_library_name(address addr, char* buf, | |||
return true; | |||
} | |||
|
|||
// get the library search path burned in to the executable file during linking | |||
// If the libpath cannot be retrieved return an empty 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.
This is new. Is this complexity needed, if yes, why? Don't see a comment, may have missed it.
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.
Also, why are we parsing xcoff32 headers in there? AIX OpenJDK will always be 64-bit. So, you can replace the whole xcoff32 section with assert( f_magic == U802TOCMAGIC, ..). The function becomes a lot simpler then.
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 found a leak in my previous implementation. It is more or less academical, but this solution is the complete one. I would prefer this complete solution even it is complex, because if dlopen follows a slightly different algorithm in resolving the library we surely get into trouble.
If we omit the xcoff32 we have to ensure that no xcoff32 executable file comes into play.
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.
If we omit the xcoff32 we have to ensure that no xcoff32 executable file comes into play.
xcoff32 is for 32-bit binaries. The AIX port only exists for 64-bit, and there will never be a 32-bit AIX port, so there is no reason for handling 32-bit xcoff headers.
src/hotspot/os/aix/os_aix.cpp
Outdated
if (libpath) | ||
return libpath; | ||
|
||
char pgmpath[32+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.
Will overflow if pid_t is 64bit. Give it a larger size; after all, you are giving buffer 4K above, so you are not overly concerned with saving stack space.
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.
adopted. use buffer instead of pgmpath
src/hotspot/os/aix/os_aix.cpp
Outdated
// get the library search path burned in to the executable file during linking | ||
// If the libpath cannot be retrieved return an empty path | ||
static const char* rtv_linkedin_libpath() { | ||
static char buffer[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.
This coding has some issues:
- a generic char buffer is not a good idea. Forces you to do casts all over the place, and introduces alignment issues with unaligned char buffer. Which I assume is the reason for all the separate memcpy-into-structures below. I would just read into the structures directly.
- you need to check the return codes for fread to make sure you read the number of bytes expected, lest you work with uninitialized memory and maybe to handle sporadic EINTR.
- I don't get all the separate "SZ" macros. They must be equal to sizeof(structure), right, otherwise you get buffer overruns or work with uninitialized memory?
Proposal: add a local wrapper function like this:
template <class T>
static bool my_checked_fread(FILE* f, T* out) {
// read sizeof(T) from f.
// Check return code.
// Return bool if sizeof(T) bytes were read.
e.g. in a very trivial form:
int bytesread = fread(out, sizeof(T), 1, f);
return bytesread == sizeof(T);
}
and use it in your code like this:
struct xcoff64 the_xcoff64;
struct scn64 the_scn64;
struct ldr64 the_ldr64;
if (!my_checked_fread(f, &the_xcoff64)) {
assert?
}
...
if (!my_checked_fread(f, &the_ldr64) {
.. handle error
}
src/hotspot/os/aix/os_aix.cpp
Outdated
struct _S_(scnhdr) scn64; | ||
struct _S_(ldhdr) ldr64; | ||
memcpy((char*)&xcoff64, buffer, FILHSZ_64 + _AOUTHSZ_EXEC_64); | ||
int ldroffset = FILHSZ_64 + xcoff64.filehdr.f_opthdr + (xcoff64.aouthdr.o_snloader -1)*SCNHSZ_64; |
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.
why the -1? I assume thats the section number? is it 1 based? how odd..
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.
Yes, the section numbers are 1 based. e.g. Beginning of section 4 has an offset of 3 section sizes.
src/hotspot/os/aix/os_aix.cpp
Outdated
// If the libpath cannot be retrieved return an empty path | ||
static const char* rtv_linkedin_libpath() { | ||
static char buffer[4096]; | ||
static const char* libpath = 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.
If your intent is to return an empty buffer if there is no contained libpath, I would just:
static const char* libpath = "";
then you can always just return libpath.
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.
But looking at the using code, returning NULL in case there is no contained libpath would be actually easier, see below.
src/hotspot/os/aix/os_aix.cpp
Outdated
fread(buffer, 1, 4096, f); | ||
} | ||
else | ||
buffer[0] = 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.
{}
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.
Done, due to complete rewriting. s.o.
src/hotspot/os/aix/os_aix.cpp
Outdated
fseek (f, scn64.s_scnptr, SEEK_SET); | ||
fread(buffer, 1, LDHDRSZ_64, f); | ||
memcpy((char*)&ldr64, buffer, LDHDRSZ_64); | ||
fseek (f, scn64.s_scnptr + ldr64.l_impoff, SEEK_SET); |
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.
nit: please use consistent spacing according to hotspot rules. here, remove space.
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.
Do you mean the space fseek (
?
Done.
src/hotspot/os/aix/os_aix.cpp
Outdated
} | ||
|
||
stringStream Libpath; | ||
if (env == nullptr) { |
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.
Proposal for shorter version not needing string assembly:
const char* paths [2] = { env, rtv_linkedin_libpath() }:
for (int i = 0; i < 2; i ++) {
const char* this_libpath = paths[i];
if (this_libpath == nullptr) {
continue;
}
... do the token thing...
}
}
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.
Sorry, I did not clearly understand how this should work. The mystery must be in ... do the token thing ...
The libpath parsing code is from me, so no license problems. |
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 like this, this is good.
Small nits remain.
src/hotspot/os/aix/porting_aix.cpp
Outdated
struct xcoffhdr the_xcoff; | ||
struct scnhdr the_scn; | ||
struct ldhdr the_ldr; | ||
size_t sz = FILHSZ + _AOUTHSZ_EXEC; |
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 rename to xcoffsz, and make constexpr: constexpr size_t xcoffsz = ...
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.
Also, can you please add
STATIC_ASSERT(sizeof(the_xcoff) == xcoffsz);
STATIC_ASSERT(sizeof(the_scn) == SCNHSZ);
STATIC_ASSERT(sizeof(the_ldr) == LDHDRSZ);
const char* env = getenv("LIBPATH"); | ||
if (env == nullptr) { | ||
// no LIBPATH, try with LD_LIBRARY_PATH | ||
env = getenv("LD_LIBRARY_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.
Is LD_LIBRARY_PATH a thing on AIX? I thought it is only used on non-AIX.
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.
Yes it is, It's the fallback if LIBPATH is not defined
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.
In that case there may be errors in other places, since so far we assumed its either one or the other, but not both. Example:
Maybe you need to take a look here, in case LD_LIBRARYPATH needs to be handled in addition to LIBPATH?
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.
Yes, it's one or the other. If LIBPATH envvar exists (even empty string), LD_LIBRARY_PATH is ignored. So, no problems.
// LIBPATH or LD_LIBRARY_PATH given with content -> try first with | ||
// LIBPATH or LD_LIBRARY_PATH and second with burned in libpath. | ||
// No check against current working directory | ||
Libpath.print("%s:%s", env, rtv_linkedin_libpath()); |
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.
Are you sure libpath env var has precedence over the baked-in libpath?
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.
Yes, that was the outcome of my experiments, although the IBM docu says the oposite:
"Specifies that the library path used at process exec time should be prepended to any library path specified in the load call (either as an argument or environment variable). It is recommended that this flag be specified in all calls to the load subroutine."
My experiment showed: LIBPATH=libpath; baked-in-libpath=baked-in-libpath;
mylib.so is in both paths. After dlopen(mylib.so) a map call shows the library was loaded from libpath.
Then I remove the LIBPATH envvar and repeat. Now after dlopen(mylib.so) a map call shows the library was loaded from baked-in-libpath.
So the LIBPATH envvar has precedence over the baked-in-libpath.
src/hotspot/os/aix/porting_aix.cpp
Outdated
// try to find handle in array, which means library was loaded by os::dll_load() call | ||
for (i = 0; i < g_handletable_used; i++) { | ||
if (g_handletable[i].handle == libhandle) { | ||
// handle found, decrease refcount |
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.
assert(refcount > 0, "Sanity"))
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.
Done
src/hotspot/os/aix/porting_aix.cpp
Outdated
ebuf[ebuflen - 1] = '\0'; | ||
} | ||
|
||
pthread_mutex_lock(&g_handletable_mutex); |
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.
You can make your life a lot easier by defining an RAII object at the start of the file:
struct TableLocker {
TableLocker() { pthread_mutex_lock(&g_handletable_mutex); }
~TableLocker() { pthread_mutex_unlock(&g_handletable_mutex); }
};
and just place this at the beginning of your two functions
TableLocker lock:
...
no need to manually unlock then, with the danger of missing a return.
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.
Great, thank you. This was one of the things I thought about, but was not sure, because I did not fully understood the MutexLocker class and the difference between Monitor and Mutex.
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.
In hindsight, pthread mutex is the better choice anyway: it avoids dependencies to the VM lifecycle (VM mutexes are only available after VM initialization, so we could not call dlopen() before that).
src/hotspot/os/aix/porting_aix.cpp
Outdated
// is sufficient to remove the entry from the array, otherwise we move the last | ||
// entry of the array to the place of the entry we want to remove and overwrite it | ||
if (i < g_handletable_used) { | ||
g_handletable[i] = g_handletable[g_handletable_used]; |
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.
To be super careful, I would zero out at least the handle of the moved item like this:
g_handletable[g_handletable_used].handle = nullptr
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.
Done
src/hotspot/os/aix/os_aix.cpp
Outdated
@@ -27,6 +27,7 @@ | |||
// with C++ compiler before referencing the function alloca() | |||
#pragma alloca | |||
|
|||
|
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 whitespace change
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.
Done
src/hotspot/os/aix/os_aix.cpp
Outdated
@@ -189,6 +190,7 @@ int os::Aix::_extshm = -1; | |||
//////////////////////////////////////////////////////////////////////////////// | |||
// local variables | |||
|
|||
|
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 whitespace change
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.
Done
src/hotspot/os/aix/os_aix.cpp
Outdated
@@ -1108,6 +1110,7 @@ bool os::dll_address_to_library_name(address addr, char* buf, | |||
return true; | |||
} | |||
|
|||
|
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 whitespace change
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.
+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.
Well done.
Releasing the mutex before asserting is not necessary; we don't pull the handle table lock as part of error reporting.
@JoKern65 This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 406 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@tstuefe, @TheRealMDoerr) but any other Committer may sponsor as well. ➡️ To flag this PR as ready for integration with the above commit message, type |
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 like getting rid of #ifdef AIX
in shared code. The change is not simple, but looks basically good to me. I'll take a closer look when I find more time. I have some coding style requests. Please also see https://wiki.openjdk.org/display/HotSpot/StyleGuide (especially section Whitespace).
src/hotspot/os/aix/os_aix.cpp
Outdated
@@ -1108,6 +1110,7 @@ bool os::dll_address_to_library_name(address addr, char* buf, | |||
return true; | |||
} | |||
|
|||
|
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.
+1
src/hotspot/os/aix/porting_aix.cpp
Outdated
libpath = buffer; | ||
|
||
return libpath; | ||
|
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.
Empty line could get removed.
src/hotspot/os/aix/porting_aix.cpp
Outdated
// But if FilePath does not start with / or . we have to prepend it with ./ | ||
if (strchr(path2, '/')) { | ||
stringStream combined; | ||
if (*path2 == '/' || *path2 == '.') |
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.
We usually use {
and }
unless for extremely simple substatements on the same line
src/hotspot/share/runtime/os.hpp
Outdated
@@ -1063,6 +1063,9 @@ class os: AllStatic { | |||
char pathSep); | |||
static bool set_boot_path(char fileSep, char pathSep); | |||
|
|||
static bool pd_dll_unload(void* libhandle, char* ebuf, int ebuflen); | |||
|
|||
|
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 empty lines.
Hi @JoKern65 Is this good to integrate now ? |
Hi @suchismith1993, I'm waiting for a second review. Complex hotspot changes should be reviewed twice. |
@suchismith1993 Please don't put pressure on patch authors and developers. There is zero reason why this patch should be rushed.
Not only that, hotspot changes need to be reviewed by at least two reviewers. That is not optional. See OpenJDK bylaws. |
If you talk about #16604, no, you cannot push that even if Joachim finishes his work. Your patch has not even a single review, is quite controversial, and none of the issues the reviewers have mentioned are addressed. This needs a lot more discussion time. |
On AIX, repeated calls to dlopen referring to the same shared library may result in different, unique dl handles to be returned from libc. In that it differs from typical libc implementations that cache dl handles.
This causes problems in the JVM with code that assumes equality of handles. One such problem is in the JVMTI agent handler. That problem was fixed with a local fix to said handler (JDK-8315706). However, this fix causes follow-up problems since it assumes that the file name passed to
os::dll_load()
is the file that has been opened. It prevents efficient, os_aix.cpp-local workarounds for other AIX issues like the .so/.a duality. See JDK-8320005. As such, it is a hack that causes other, more uglier hacks to follow (see discussion of #16604).We propose a different, cleaner way of handling this:
This way we mimic dl handle equality as it is implemented on other platforms, and this works for all callers of os::dll_load.
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/16920/head:pull/16920
$ git checkout pull/16920
Update a local copy of the PR:
$ git checkout pull/16920
$ git pull https://git.openjdk.org/jdk.git pull/16920/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 16920
View PR using the GUI difftool:
$ git pr show -t 16920
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/16920.diff
Webrev
Link to Webrev Comment