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

JDK-8288003: log events for os::dll_unload #9101

Closed
wants to merge 6 commits into from

Conversation

MBaesken
Copy link
Member

@MBaesken MBaesken commented Jun 9, 2022

Currently we only log events for os::dll_load, but not for os::dll_unload, this patch adds it. On some platforms (Linux/Windows) we can use OS APIs (e.g. dlinfo on Linux) to log the path of the unloaded shared lib.


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk pull/9101/head:pull/9101
$ git checkout pull/9101

Update a local copy of the PR:
$ git checkout pull/9101
$ git pull https://git.openjdk.org/jdk pull/9101/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 9101

View PR using the GUI difftool:
$ git pr show -t 9101

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/9101.diff

@bridgekeeper
Copy link

bridgekeeper bot commented Jun 9, 2022

👋 Welcome back mbaesken! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk openjdk bot added the rfr Pull request is ready for review label Jun 9, 2022
@openjdk
Copy link

openjdk bot commented Jun 9, 2022

@MBaesken The following label will be automatically applied to this pull request:

  • hotspot-runtime

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the hotspot-runtime hotspot-runtime-dev@openjdk.org label Jun 9, 2022
@mlbridge
Copy link

mlbridge bot commented Jun 9, 2022

Webrevs

Copy link
Member

@dholmes-ora dholmes-ora left a comment

Choose a reason for hiding this comment

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

Generally okay but I'd like to minimise the conditional code.

Thanks.

Comment on lines 712 to 718
#if defined(LINUX)
struct link_map *lmap;
int res_dli = ::dlinfo(lib, RTLD_DI_LINKMAP, &lmap);
const char* l_path = "<none>";
if (res_dli == 0) {
l_path = lmap->l_name;
}
Copy link
Member

Choose a reason for hiding this comment

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

Can we hide this in os::Linux::dll_path so that the code here would simply be:

const char* l_path = LINUX_ONLY(os::Linux::dll_path(lib))
                     NOT_LINUX("<not available>");

Copy link
Member Author

Choose a reason for hiding this comment

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

Hi David, thanks for the advice, done.
I also added some more quoting and added the dlerror information to the error report (see os_posix.cpp).

int res = ::dlclose(lib);

if (res == 0) {
Events::log_dll_message(NULL, "Unloaded shared library %s [" INTPTR_FORMAT "]", l_path, p2i(lib));
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't the %s be quoted here too? The output will look a bit odd:

Unloaded shared library [0xbaadcafebaadcafe]

vs.

Unloaded shared library "" [0xbaadcafebaadcafe]

@openjdk openjdk bot removed the rfr Pull request is ready for review label Jun 9, 2022
@openjdk openjdk bot added the rfr Pull request is ready for review label Jun 9, 2022
Copy link
Member

@dholmes-ora dholmes-ora left a comment

Choose a reason for hiding this comment

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

Looks good - thanks for incorporating my requests.

One minor item below.

Thanks

const char* os::Linux::dll_path(void* lib) {
struct link_map *lmap;
int res_dli = ::dlinfo(lib, RTLD_DI_LINKMAP, &lmap);
const char* l_path = "<none>";
Copy link
Member

Choose a reason for hiding this comment

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

Should this be "not available" to match the non-Linux case?

@openjdk
Copy link

openjdk bot commented Jun 9, 2022

@MBaesken 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:

8288003: log events for os::dll_unload

Reviewed-by: dholmes, stuefe

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 38 new commits pushed to the master branch:

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.

➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Jun 9, 2022
Copy link
Member

@YaSuenag YaSuenag left a comment

Choose a reason for hiding this comment

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

I think it is better to add null check to dll_unload() because it might be different behavior between Linux and Windows.

GetModuleFileName() on Windows will return the path of executable if NULL is passed to hModule.
https://docs.microsoft.com/ja-JP/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulefilenamea

On the other hand, dlinfo() does not mention if NULL is passed in library handle.
https://man7.org/linux/man-pages/man3/dlinfo.3.html

I think dll_unload() is not expexted to unload executable...

@MBaesken
Copy link
Member Author

Hello, I added a NULL check to os::Linux::dll_path.
Additionally I adjusted l_path to "not available" to match the non-Linux case.

Copy link
Member

@YaSuenag YaSuenag left a comment

Choose a reason for hiding this comment

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

Why didn't you add NULL check to os::dll_unload() both os_windows and os_posix?
If NULL is passed to os::dll_unload() at os_windows.cpp, it would be passed to GetModuleFileName(), then we would get executable path.

I think we can add assert to the start of both dll_unload() because NULL shouldn't be passed to them.

::FreeLibrary((HMODULE)lib);
char name[MAX_PATH];
if (::GetModuleFileName((HMODULE)lib, name, sizeof(name)) == 0) {
name[0] = '\0';
Copy link
Member

Choose a reason for hiding this comment

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

Should we set <not available> to name like a change for linux code?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, it is most likely better to have same output in failure case on Windows and other platforms.

@@ -1786,6 +1786,18 @@ void * os::Linux::dll_load_in_vmthread(const char *filename, char *ebuf,
return result;
}

const char* os::Linux::dll_path(void* lib) {
struct link_map *lmap;
const char* l_path = "<not available>";
Copy link
Member

Choose a reason for hiding this comment

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

To be honest, I prefer to return NULL if dlinfo is failed.
IIUC the caller expects return dll path of lib - <not available> is not the path.

I think it is better that alternative string would be set by the caller (os::dll_unload()) like a change of os_windows. But I do not stick my opinion. I'm ok if other reviewer approve your change.

Copy link
Member Author

Choose a reason for hiding this comment

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

Adjusted dll_path, it returns now NULL in case of failure.

@dholmes-ora
Copy link
Member

I think it is better to add null check to dll_unload()

I would expect NULL checks to be present in the calling code somewhere; at most an assertion for NULL should be present in this lowest-level code.

Copy link
Member

@tstuefe tstuefe left a comment

Choose a reason for hiding this comment

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

Hi Matthias,

this looks okay and is useful.

I worried a bit about the thread safety of ::dlerror(), since it is specified as not threadsafe by Posix: "The dlerror() function need not be reentrant. A function that is not required to be reentrant is not required to be thread-safe." .

However, the glibc variant (https://sources.debian.org/src/glibc/2.28-10/dlfcn/dlerror.c) seems to be thread-safe, using POSIX TLS to store the resulting error string.

But interestingly enough, the string itself only lives as long as ::dlerror() is not called again. A second call to dlerror() will free() the string. So, one should use the string right away, for storing it should be strduped.

I did not look if dlerror is threadsafe on Muslc.

const char* os::Linux::dll_path(void* lib) {
struct link_map *lmap;
const char* l_path = NULL;
if (lib != NULL) {
Copy link
Member

Choose a reason for hiding this comment

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

I still say this can just be an assert - it is checked in the callers.

Copy link
Member Author

Choose a reason for hiding this comment

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

I introduced an assert in dll_path.

@dholmes-ora
Copy link
Member

I worried a bit about the thread safety of ::dlerror()

The usage here is no different to existing usages.

@tstuefe
Copy link
Member

tstuefe commented Jun 13, 2022

I worried a bit about the thread safety of ::dlerror()

The usage here is no different to existing usages.

Sure, but they could have been existing errors :-)

For proof that these thoughts are not completely unfounded see e.g. https://gitlab.gnome.org/GNOME/glib/-/issues/399, in that case pertaining to the now defunct eglibc. But older versions of glibc were not threadsafe either.

@dholmes-ora
Copy link
Member

Sure, but they could have been existing errors :-)

Sure, but my point is that this fix is not introducing anything new. The potential for a broken dlerror has been discussed in the past. I don't think it is something we need to try to jump through hoops to anticipate. It is rare enough we will get an error, let alone concurrent ones.

@tstuefe
Copy link
Member

tstuefe commented Jun 14, 2022

Sure, but they could have been existing errors :-)

Sure, but my point is that this fix is not introducing anything new. The potential for a broken dlerror has been discussed in the past. I don't think it is something we need to try to jump through hoops to anticipate. It is rare enough we will get an error, let alone concurrent ones.

Of course, I agree. Thats why I approved the patch.

@MBaesken
Copy link
Member Author

/integrate

@openjdk
Copy link

openjdk bot commented Jun 14, 2022

Going to push as commit c2ccf4c.
Since your change was applied there have been 57 commits pushed to the master branch:

  • 03dca56: 8287525: Extend IR annotation with new options to test specific target feature.
  • 86c9241: 8287028: AArch64: [vectorapi] Backend implementation of VectorMask.fromLong with SVE2
  • fbe9266: 8288378: [BACKOUT] DST not applying properly with zone id offset set with TZ env variable
  • 1904353: Merge
  • 7aafc69: 8288105: [PPC64] Problems with -XX:+VerifyStack
  • f4b05a1: 8288173: JDK-8202449 fix causes conformance test failure : api/java_util/Random/RandomGenerator/NextFloat.html
  • d9c1364: 8288101: False build warning-as-error with GCC 9 after JDK-8214976
  • a9c2ab6: 8288080: (fc) FileChannel::map for MemorySegments should state it always throws UOE
  • e90b579: 8288332: Tier1 validate-source fails after 8279614
  • b42c1ad: 8279614: The left line of the TitledBorder is not painted on 150 scale factor
  • ... and 47 more: https://git.openjdk.org/jdk/compare/bc28baeba9360991e9b7575e1fbe178d873ccfc1...master

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label Jun 14, 2022
@openjdk openjdk bot closed this Jun 14, 2022
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Jun 14, 2022
@openjdk
Copy link

openjdk bot commented Jun 14, 2022

@MBaesken Pushed as commit c2ccf4c.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hotspot-runtime hotspot-runtime-dev@openjdk.org integrated Pull request has been integrated
Development

Successfully merging this pull request may close these issues.

4 participants