8315220: Event NativeLibraryLoad breaks invariant by taking a stacktrace when thread is in state _thread_in_native
Reviewed-by: mbaesken, egahlin
This commit is contained in:
parent
8f7e29b2cd
commit
1cae0f53a9
@ -81,7 +81,7 @@
|
|||||||
#include "utilities/growableArray.hpp"
|
#include "utilities/growableArray.hpp"
|
||||||
#include "utilities/vmError.hpp"
|
#include "utilities/vmError.hpp"
|
||||||
#if INCLUDE_JFR
|
#if INCLUDE_JFR
|
||||||
#include "jfr/jfrEvents.hpp"
|
#include "jfr/support/jfrNativeLibraryLoadEvent.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// put OS-includes here (sorted alphabetically)
|
// put OS-includes here (sorted alphabetically)
|
||||||
@ -1116,11 +1116,6 @@ void *os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if INCLUDE_JFR
|
|
||||||
EventNativeLibraryLoad event;
|
|
||||||
event.set_name(filename);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// RTLD_LAZY has currently the same behavior as RTLD_NOW
|
// RTLD_LAZY has currently the same behavior as RTLD_NOW
|
||||||
// The dl is loaded immediately with all its dependants.
|
// The dl is loaded immediately with all its dependants.
|
||||||
int dflags = RTLD_LAZY;
|
int dflags = RTLD_LAZY;
|
||||||
@ -1131,19 +1126,14 @@ void *os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
|||||||
dflags |= RTLD_MEMBER;
|
dflags |= RTLD_MEMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void * result= ::dlopen(filename, dflags);
|
void* result;
|
||||||
|
JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
|
||||||
|
result = ::dlopen(filename, dflags);
|
||||||
if (result != nullptr) {
|
if (result != nullptr) {
|
||||||
Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
|
Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
|
||||||
// Reload dll cache. Don't do this in signal handling.
|
// Reload dll cache. Don't do this in signal handling.
|
||||||
LoadedLibraries::reload();
|
LoadedLibraries::reload();
|
||||||
log_info(os)("shared library load of %s was successful", filename);
|
log_info(os)("shared library load of %s was successful", filename);
|
||||||
|
|
||||||
#if INCLUDE_JFR
|
|
||||||
event.set_success(true);
|
|
||||||
event.set_errorMessage(nullptr);
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
// error analysis when dlopen fails
|
// error analysis when dlopen fails
|
||||||
@ -1157,12 +1147,7 @@ void *os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
|||||||
}
|
}
|
||||||
Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
|
Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
|
||||||
log_info(os)("shared library load of %s failed, %s", filename, error_report);
|
log_info(os)("shared library load of %s failed, %s", filename, error_report);
|
||||||
|
JFR_ONLY(load_event.set_error_msg(error_report);)
|
||||||
#if INCLUDE_JFR
|
|
||||||
event.set_success(false);
|
|
||||||
event.set_errorMessage(error_report);
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
#include "utilities/vmError.hpp"
|
#include "utilities/vmError.hpp"
|
||||||
#if INCLUDE_JFR
|
#if INCLUDE_JFR
|
||||||
#include "jfr/jfrEvents.hpp"
|
#include "jfr/jfrEvents.hpp"
|
||||||
|
#include "jfr/support/jfrNativeLibraryLoadEvent.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// put OS-includes here
|
// put OS-includes here
|
||||||
@ -979,21 +980,13 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
|||||||
#else
|
#else
|
||||||
log_info(os)("attempting shared library load of %s", filename);
|
log_info(os)("attempting shared library load of %s", filename);
|
||||||
|
|
||||||
#if INCLUDE_JFR
|
void* result;
|
||||||
EventNativeLibraryLoad event;
|
JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
|
||||||
event.set_name(filename);
|
result = ::dlopen(filename, RTLD_LAZY);
|
||||||
#endif
|
|
||||||
|
|
||||||
void * result= ::dlopen(filename, RTLD_LAZY);
|
|
||||||
if (result != nullptr) {
|
if (result != nullptr) {
|
||||||
Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
|
Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
|
||||||
// Successful loading
|
// Successful loading
|
||||||
log_info(os)("shared library load of %s was successful", filename);
|
log_info(os)("shared library load of %s was successful", filename);
|
||||||
#if INCLUDE_JFR
|
|
||||||
event.set_success(true);
|
|
||||||
event.set_errorMessage(nullptr);
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1008,11 +1001,7 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
|||||||
}
|
}
|
||||||
Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
|
Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
|
||||||
log_info(os)("shared library load of %s failed, %s", filename, error_report);
|
log_info(os)("shared library load of %s failed, %s", filename, error_report);
|
||||||
#if INCLUDE_JFR
|
JFR_ONLY(load_event.set_error_msg(error_report);)
|
||||||
event.set_success(false);
|
|
||||||
event.set_errorMessage(error_report);
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#endif // STATIC_BUILD
|
#endif // STATIC_BUILD
|
||||||
@ -1024,21 +1013,13 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
|||||||
#else
|
#else
|
||||||
log_info(os)("attempting shared library load of %s", filename);
|
log_info(os)("attempting shared library load of %s", filename);
|
||||||
|
|
||||||
#if INCLUDE_JFR
|
void* result;
|
||||||
EventNativeLibraryLoad event;
|
JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
|
||||||
event.set_name(filename);
|
result = ::dlopen(filename, RTLD_LAZY);
|
||||||
#endif
|
|
||||||
|
|
||||||
void * result= ::dlopen(filename, RTLD_LAZY);
|
|
||||||
if (result != nullptr) {
|
if (result != nullptr) {
|
||||||
Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
|
Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
|
||||||
// Successful loading
|
// Successful loading
|
||||||
log_info(os)("shared library load of %s was successful", filename);
|
log_info(os)("shared library load of %s was successful", filename);
|
||||||
#if INCLUDE_JFR
|
|
||||||
event.set_success(true);
|
|
||||||
event.set_errorMessage(nullptr);
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1055,11 +1036,7 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
|||||||
}
|
}
|
||||||
Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
|
Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
|
||||||
log_info(os)("shared library load of %s failed, %s", filename, error_report);
|
log_info(os)("shared library load of %s failed, %s", filename, error_report);
|
||||||
#if INCLUDE_JFR
|
JFR_ONLY(load_event.set_error_msg(error_report);)
|
||||||
event.set_success(false);
|
|
||||||
event.set_errorMessage(error_report);
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
int diag_msg_max_length=ebuflen-strlen(ebuf);
|
int diag_msg_max_length=ebuflen-strlen(ebuf);
|
||||||
char* diag_msg_buf=ebuf+strlen(ebuf);
|
char* diag_msg_buf=ebuf+strlen(ebuf);
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@
|
|||||||
#include "utilities/vmError.hpp"
|
#include "utilities/vmError.hpp"
|
||||||
#if INCLUDE_JFR
|
#if INCLUDE_JFR
|
||||||
#include "jfr/jfrEvents.hpp"
|
#include "jfr/jfrEvents.hpp"
|
||||||
|
#include "jfr/support/jfrNativeLibraryLoadEvent.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// put OS-includes here
|
// put OS-includes here
|
||||||
@ -1794,15 +1795,10 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void * os::Linux::dlopen_helper(const char *filename, char *ebuf,
|
void * os::Linux::dlopen_helper(const char *filename, char *ebuf, int ebuflen) {
|
||||||
int ebuflen) {
|
void* result;
|
||||||
void * result = ::dlopen(filename, RTLD_LAZY);
|
JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
|
||||||
|
result = ::dlopen(filename, RTLD_LAZY);
|
||||||
#if INCLUDE_JFR
|
|
||||||
EventNativeLibraryLoad event;
|
|
||||||
event.set_name(filename);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (result == nullptr) {
|
if (result == nullptr) {
|
||||||
const char* error_report = ::dlerror();
|
const char* error_report = ::dlerror();
|
||||||
if (error_report == nullptr) {
|
if (error_report == nullptr) {
|
||||||
@ -1814,19 +1810,10 @@ void * os::Linux::dlopen_helper(const char *filename, char *ebuf,
|
|||||||
}
|
}
|
||||||
Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
|
Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
|
||||||
log_info(os)("shared library load of %s failed, %s", filename, error_report);
|
log_info(os)("shared library load of %s failed, %s", filename, error_report);
|
||||||
#if INCLUDE_JFR
|
JFR_ONLY(load_event.set_error_msg(error_report);)
|
||||||
event.set_success(false);
|
|
||||||
event.set_errorMessage(error_report);
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
|
Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
|
||||||
log_info(os)("shared library load of %s was successful", filename);
|
log_info(os)("shared library load of %s was successful", filename);
|
||||||
#if INCLUDE_JFR
|
|
||||||
event.set_success(true);
|
|
||||||
event.set_errorMessage(nullptr);
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
#include "utilities/macros.hpp"
|
#include "utilities/macros.hpp"
|
||||||
#include "utilities/vmError.hpp"
|
#include "utilities/vmError.hpp"
|
||||||
#if INCLUDE_JFR
|
#if INCLUDE_JFR
|
||||||
#include "jfr/jfrEvents.hpp"
|
#include "jfr/support/jfrNativeLibraryLoadEvent.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef AIX
|
#ifdef AIX
|
||||||
@ -728,10 +728,7 @@ void os::dll_unload(void *lib) {
|
|||||||
}
|
}
|
||||||
#endif // LINUX
|
#endif // LINUX
|
||||||
|
|
||||||
#if INCLUDE_JFR
|
JFR_ONLY(NativeLibraryUnloadEvent unload_event(l_path);)
|
||||||
EventNativeLibraryUnload event;
|
|
||||||
event.set_name(l_path);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (l_path == nullptr) {
|
if (l_path == nullptr) {
|
||||||
l_path = "<not available>";
|
l_path = "<not available>";
|
||||||
@ -742,11 +739,7 @@ void os::dll_unload(void *lib) {
|
|||||||
Events::log_dll_message(nullptr, "Unloaded shared library \"%s\" [" INTPTR_FORMAT "]",
|
Events::log_dll_message(nullptr, "Unloaded shared library \"%s\" [" INTPTR_FORMAT "]",
|
||||||
l_path, p2i(lib));
|
l_path, p2i(lib));
|
||||||
log_info(os)("Unloaded shared library \"%s\" [" INTPTR_FORMAT "]", l_path, p2i(lib));
|
log_info(os)("Unloaded shared library \"%s\" [" INTPTR_FORMAT "]", l_path, p2i(lib));
|
||||||
#if INCLUDE_JFR
|
JFR_ONLY(unload_event.set_result(true);)
|
||||||
event.set_success(true);
|
|
||||||
event.set_errorMessage(nullptr);
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
const char* error_report = ::dlerror();
|
const char* error_report = ::dlerror();
|
||||||
if (error_report == nullptr) {
|
if (error_report == nullptr) {
|
||||||
@ -757,11 +750,7 @@ void os::dll_unload(void *lib) {
|
|||||||
l_path, p2i(lib), error_report);
|
l_path, p2i(lib), error_report);
|
||||||
log_info(os)("Attempt to unload shared library \"%s\" [" INTPTR_FORMAT "] failed, %s",
|
log_info(os)("Attempt to unload shared library \"%s\" [" INTPTR_FORMAT "] failed, %s",
|
||||||
l_path, p2i(lib), error_report);
|
l_path, p2i(lib), error_report);
|
||||||
#if INCLUDE_JFR
|
JFR_ONLY(unload_event.set_error_msg(error_report);)
|
||||||
event.set_success(false);
|
|
||||||
event.set_errorMessage(error_report);
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
// Update the dll cache
|
// Update the dll cache
|
||||||
AIX_ONLY(LoadedLibraries::reload());
|
AIX_ONLY(LoadedLibraries::reload());
|
||||||
|
@ -80,6 +80,7 @@
|
|||||||
#include "windbghelp.hpp"
|
#include "windbghelp.hpp"
|
||||||
#if INCLUDE_JFR
|
#if INCLUDE_JFR
|
||||||
#include "jfr/jfrEvents.hpp"
|
#include "jfr/jfrEvents.hpp"
|
||||||
|
#include "jfr/support/jfrNativeLibraryLoadEvent.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
@ -1246,33 +1247,22 @@ void os::dll_unload(void *lib) {
|
|||||||
snprintf(name, MAX_PATH, "<not available>");
|
snprintf(name, MAX_PATH, "<not available>");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if INCLUDE_JFR
|
JFR_ONLY(NativeLibraryUnloadEvent unload_event(name);)
|
||||||
EventNativeLibraryUnload event;
|
|
||||||
event.set_name(name);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (::FreeLibrary((HMODULE)lib)) {
|
if (::FreeLibrary((HMODULE)lib)) {
|
||||||
Events::log_dll_message(nullptr, "Unloaded dll \"%s\" [" INTPTR_FORMAT "]", name, p2i(lib));
|
Events::log_dll_message(nullptr, "Unloaded dll \"%s\" [" INTPTR_FORMAT "]", name, p2i(lib));
|
||||||
log_info(os)("Unloaded dll \"%s\" [" INTPTR_FORMAT "]", name, p2i(lib));
|
log_info(os)("Unloaded dll \"%s\" [" INTPTR_FORMAT "]", name, p2i(lib));
|
||||||
#if INCLUDE_JFR
|
JFR_ONLY(unload_event.set_result(true);)
|
||||||
event.set_success(true);
|
|
||||||
event.set_errorMessage(nullptr);
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
const DWORD errcode = ::GetLastError();
|
const DWORD errcode = ::GetLastError();
|
||||||
char buf[500];
|
char buf[500];
|
||||||
size_t tl = os::lasterror(buf, sizeof(buf));
|
size_t tl = os::lasterror(buf, sizeof(buf));
|
||||||
Events::log_dll_message(nullptr, "Attempt to unload dll \"%s\" [" INTPTR_FORMAT "] failed (error code %d)", name, p2i(lib), errcode);
|
Events::log_dll_message(nullptr, "Attempt to unload dll \"%s\" [" INTPTR_FORMAT "] failed (error code %d)", name, p2i(lib), errcode);
|
||||||
log_info(os)("Attempt to unload dll \"%s\" [" INTPTR_FORMAT "] failed (error code %d)", name, p2i(lib), errcode);
|
log_info(os)("Attempt to unload dll \"%s\" [" INTPTR_FORMAT "] failed (error code %d)", name, p2i(lib), errcode);
|
||||||
#if INCLUDE_JFR
|
|
||||||
event.set_success(false);
|
|
||||||
if (tl == 0) {
|
if (tl == 0) {
|
||||||
os::snprintf(buf, sizeof(buf), "Attempt to unload dll failed (error code %d)", (int) errcode);
|
os::snprintf(buf, sizeof(buf), "Attempt to unload dll failed (error code %d)", (int) errcode);
|
||||||
}
|
}
|
||||||
event.set_errorMessage(buf);
|
JFR_ONLY(unload_event.set_error_msg(buf);)
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1541,21 +1531,14 @@ static int _print_module(const char* fname, address base_address,
|
|||||||
// same architecture as Hotspot is running on
|
// same architecture as Hotspot is running on
|
||||||
void * os::dll_load(const char *name, char *ebuf, int ebuflen) {
|
void * os::dll_load(const char *name, char *ebuf, int ebuflen) {
|
||||||
log_info(os)("attempting shared library load of %s", name);
|
log_info(os)("attempting shared library load of %s", name);
|
||||||
#if INCLUDE_JFR
|
void* result;
|
||||||
EventNativeLibraryLoad event;
|
JFR_ONLY(NativeLibraryLoadEvent load_event(name, &result);)
|
||||||
event.set_name(name);
|
result = LoadLibrary(name);
|
||||||
#endif
|
|
||||||
void * result = LoadLibrary(name);
|
|
||||||
if (result != nullptr) {
|
if (result != nullptr) {
|
||||||
Events::log_dll_message(nullptr, "Loaded shared library %s", name);
|
Events::log_dll_message(nullptr, "Loaded shared library %s", name);
|
||||||
// Recalculate pdb search path if a DLL was loaded successfully.
|
// Recalculate pdb search path if a DLL was loaded successfully.
|
||||||
SymbolEngine::recalc_search_path();
|
SymbolEngine::recalc_search_path();
|
||||||
log_info(os)("shared library load of %s was successful", name);
|
log_info(os)("shared library load of %s was successful", name);
|
||||||
#if INCLUDE_JFR
|
|
||||||
event.set_success(true);
|
|
||||||
event.set_errorMessage(nullptr);
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
DWORD errcode = GetLastError();
|
DWORD errcode = GetLastError();
|
||||||
@ -1569,11 +1552,7 @@ void * os::dll_load(const char *name, char *ebuf, int ebuflen) {
|
|||||||
if (errcode == ERROR_MOD_NOT_FOUND) {
|
if (errcode == ERROR_MOD_NOT_FOUND) {
|
||||||
strncpy(ebuf, "Can't find dependent libraries", ebuflen - 1);
|
strncpy(ebuf, "Can't find dependent libraries", ebuflen - 1);
|
||||||
ebuf[ebuflen - 1] = '\0';
|
ebuf[ebuflen - 1] = '\0';
|
||||||
#if INCLUDE_JFR
|
JFR_ONLY(load_event.set_error_msg(ebuf);)
|
||||||
event.set_success(false);
|
|
||||||
event.set_errorMessage(ebuf);
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1584,11 +1563,7 @@ void * os::dll_load(const char *name, char *ebuf, int ebuflen) {
|
|||||||
// else call os::lasterror to obtain system error message
|
// else call os::lasterror to obtain system error message
|
||||||
int fd = ::open(name, O_RDONLY | O_BINARY, 0);
|
int fd = ::open(name, O_RDONLY | O_BINARY, 0);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
#if INCLUDE_JFR
|
JFR_ONLY(load_event.set_error_msg("open on dll file did not work");)
|
||||||
event.set_success(false);
|
|
||||||
event.set_errorMessage("open on dll file did not work");
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1615,11 +1590,7 @@ void * os::dll_load(const char *name, char *ebuf, int ebuflen) {
|
|||||||
::close(fd);
|
::close(fd);
|
||||||
if (failed_to_get_lib_arch) {
|
if (failed_to_get_lib_arch) {
|
||||||
// file i/o error - report os::lasterror(...) msg
|
// file i/o error - report os::lasterror(...) msg
|
||||||
#if INCLUDE_JFR
|
JFR_ONLY(load_event.set_error_msg("failed to get lib architecture");)
|
||||||
event.set_success(false);
|
|
||||||
event.set_errorMessage("failed to get lib architecture");
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1664,11 +1635,7 @@ void * os::dll_load(const char *name, char *ebuf, int ebuflen) {
|
|||||||
// If the architecture is right
|
// If the architecture is right
|
||||||
// but some other error took place - report os::lasterror(...) msg
|
// but some other error took place - report os::lasterror(...) msg
|
||||||
if (lib_arch == running_arch) {
|
if (lib_arch == running_arch) {
|
||||||
#if INCLUDE_JFR
|
JFR_ONLY(load_event.set_error_msg("lib architecture matches, but other error occured");)
|
||||||
event.set_success(false);
|
|
||||||
event.set_errorMessage("lib architecture matches, but other error occured");
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1682,12 +1649,7 @@ void * os::dll_load(const char *name, char *ebuf, int ebuflen) {
|
|||||||
"Can't load this .dll (machine code=0x%x) on a %s-bit platform",
|
"Can't load this .dll (machine code=0x%x) on a %s-bit platform",
|
||||||
lib_arch, running_arch_str);
|
lib_arch, running_arch_str);
|
||||||
}
|
}
|
||||||
#if INCLUDE_JFR
|
JFR_ONLY(load_event.set_error_msg(ebuf);)
|
||||||
event.set_success(false);
|
|
||||||
event.set_errorMessage(ebuf);
|
|
||||||
event.commit();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -939,14 +939,14 @@
|
|||||||
<Field type="ulong" contentType="address" name="topAddress" label="Top Address" description="Ending address of the module, if available" />
|
<Field type="ulong" contentType="address" name="topAddress" label="Top Address" description="Ending address of the module, if available" />
|
||||||
</Event>
|
</Event>
|
||||||
|
|
||||||
<Event name="NativeLibraryLoad" category="Java Virtual Machine, Runtime" label="Native Library Load" thread="false" stackTrace="true" startTime="true"
|
<Event name="NativeLibraryLoad" category="Java Virtual Machine, Runtime" label="Native Library Load" thread="true" stackTrace="true" startTime="true"
|
||||||
description="Information about a dynamic library or other native image load operation">
|
description="Information about a dynamic library or other native image load operation">
|
||||||
<Field type="string" name="name" label="Name" />
|
<Field type="string" name="name" label="Name" />
|
||||||
<Field type="boolean" name="success" label="Success" description="Success or failure of the load operation" />
|
<Field type="boolean" name="success" label="Success" description="Success or failure of the load operation" />
|
||||||
<Field type="string" name="errorMessage" label="Error Message" description="In case of a load error, error description" />
|
<Field type="string" name="errorMessage" label="Error Message" description="In case of a load error, error description" />
|
||||||
</Event>
|
</Event>
|
||||||
|
|
||||||
<Event name="NativeLibraryUnload" category="Java Virtual Machine, Runtime" label="Native Library Unload" thread="false" stackTrace="true" startTime="true"
|
<Event name="NativeLibraryUnload" category="Java Virtual Machine, Runtime" label="Native Library Unload" thread="true" stackTrace="true" startTime="true"
|
||||||
description="Information about a dynamic library or other native image unload operation">
|
description="Information about a dynamic library or other native image unload operation">
|
||||||
<Field type="string" name="name" label="Name" />
|
<Field type="string" name="name" label="Name" />
|
||||||
<Field type="boolean" name="success" label="Success" description="Success or failure of the unload operation" />
|
<Field type="boolean" name="success" label="Success" description="Success or failure of the unload operation" />
|
||||||
|
123
src/hotspot/share/jfr/support/jfrNativeLibraryLoadEvent.cpp
Normal file
123
src/hotspot/share/jfr/support/jfrNativeLibraryLoadEvent.cpp
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.hpp"
|
||||||
|
#include "jfr/jfrEvents.hpp"
|
||||||
|
#include "jfr/support/jfrNativeLibraryLoadEvent.hpp"
|
||||||
|
#include "jfr/utilities/jfrTime.hpp"
|
||||||
|
#include "runtime/interfaceSupport.inline.hpp"
|
||||||
|
#include "runtime/thread.inline.hpp"
|
||||||
|
|
||||||
|
JfrNativeLibraryEventBase::JfrNativeLibraryEventBase(const char* name) : _name(name), _error_msg(nullptr), _start_time(nullptr) {}
|
||||||
|
|
||||||
|
JfrNativeLibraryEventBase::~JfrNativeLibraryEventBase() {
|
||||||
|
delete _start_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* JfrNativeLibraryEventBase::name() const {
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
JfrTicksWrapper* JfrNativeLibraryEventBase::start_time() const {
|
||||||
|
return _start_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JfrNativeLibraryEventBase::has_start_time() const {
|
||||||
|
return _start_time != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* JfrNativeLibraryEventBase::error_msg() const {
|
||||||
|
return _error_msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JfrNativeLibraryEventBase::set_error_msg(const char* error_msg) {
|
||||||
|
assert(_error_msg == nullptr, "invariant");
|
||||||
|
_error_msg = error_msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The JfrTicks value is heap allocated inside an object of type JfrTicksWrapper.
|
||||||
|
* The reason is that a raw value object of type Ticks is not possible at this
|
||||||
|
* location because this code runs as part of early VM bootstrap, at a moment
|
||||||
|
* where Ticks support is not yet initialized.
|
||||||
|
*/
|
||||||
|
template <typename EventType>
|
||||||
|
static inline JfrTicksWrapper* allocate_start_time() {
|
||||||
|
return EventType::is_enabled() ? new JfrTicksWrapper() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeLibraryLoadEvent::NativeLibraryLoadEvent(const char* name, void** result) : JfrNativeLibraryEventBase(name), _result(result) {
|
||||||
|
assert(_result != nullptr, "invariant");
|
||||||
|
_start_time = allocate_start_time<EventNativeLibraryLoad>();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeLibraryLoadEvent::success() const {
|
||||||
|
return *_result != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeLibraryUnloadEvent::NativeLibraryUnloadEvent(const char* name) : JfrNativeLibraryEventBase(name), _result(false) {
|
||||||
|
_start_time = allocate_start_time<EventNativeLibraryUnload>();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeLibraryUnloadEvent::success() const {
|
||||||
|
return _result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeLibraryUnloadEvent::set_result(bool result) {
|
||||||
|
_result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename EventType, typename HelperType>
|
||||||
|
static void commit(HelperType& helper) {
|
||||||
|
if (!helper.has_start_time()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
EventType event(UNTIMED);
|
||||||
|
event.set_endtime(JfrTicks::now());
|
||||||
|
event.set_starttime(*helper.start_time());
|
||||||
|
event.set_name(helper.name());
|
||||||
|
event.set_errorMessage(helper.error_msg());
|
||||||
|
event.set_success(helper.success());
|
||||||
|
Thread* thread = Thread::current();
|
||||||
|
assert(thread != nullptr, "invariant");
|
||||||
|
if (thread->is_Java_thread()) {
|
||||||
|
JavaThread* jt = JavaThread::cast(thread);
|
||||||
|
if (jt->thread_state() != _thread_in_vm) {
|
||||||
|
assert(jt->thread_state() == _thread_in_native, "invariant");
|
||||||
|
// For a JavaThread to take a JFR stacktrace, it must be in _thread_in_vm. Can safepoint here.
|
||||||
|
ThreadInVMfromNative transition(jt);
|
||||||
|
event.commit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
event.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeLibraryLoadEvent::~NativeLibraryLoadEvent() {
|
||||||
|
commit<EventNativeLibraryLoad>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeLibraryUnloadEvent::~NativeLibraryUnloadEvent() {
|
||||||
|
commit<EventNativeLibraryUnload>(*this);
|
||||||
|
}
|
71
src/hotspot/share/jfr/support/jfrNativeLibraryLoadEvent.hpp
Normal file
71
src/hotspot/share/jfr/support/jfrNativeLibraryLoadEvent.hpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SHARE_JFR_SUPPORT_JFRNATIVELIBRARYLOADEVENT_HPP
|
||||||
|
#define SHARE_JFR_SUPPORT_JFRNATIVELIBRARYLOADEVENT_HPP
|
||||||
|
|
||||||
|
#include "memory/allocation.hpp"
|
||||||
|
|
||||||
|
class JfrTicksWrapper;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper types for populating NativeLibrary events.
|
||||||
|
* Event commit is run as part of destructors.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class JfrNativeLibraryEventBase : public StackObj {
|
||||||
|
protected:
|
||||||
|
const char* _name;
|
||||||
|
const char* _error_msg;
|
||||||
|
JfrTicksWrapper* _start_time;
|
||||||
|
JfrNativeLibraryEventBase(const char* name);
|
||||||
|
~JfrNativeLibraryEventBase();
|
||||||
|
public:
|
||||||
|
const char* name() const;
|
||||||
|
const char* error_msg() const;
|
||||||
|
void set_error_msg(const char* error_msg);
|
||||||
|
JfrTicksWrapper* start_time() const;
|
||||||
|
bool has_start_time() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NativeLibraryLoadEvent : public JfrNativeLibraryEventBase {
|
||||||
|
private:
|
||||||
|
void** _result;
|
||||||
|
public:
|
||||||
|
NativeLibraryLoadEvent(const char* name, void** result);
|
||||||
|
~NativeLibraryLoadEvent();
|
||||||
|
bool success() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NativeLibraryUnloadEvent : public JfrNativeLibraryEventBase {
|
||||||
|
private:
|
||||||
|
bool _result;
|
||||||
|
public:
|
||||||
|
NativeLibraryUnloadEvent(const char* name);
|
||||||
|
~NativeLibraryUnloadEvent();
|
||||||
|
bool success() const;
|
||||||
|
void set_result(bool result);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SHARE_JFR_SUPPORT_JFRNATIVELIBRARYLOADEVENT_HPP
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,6 +25,7 @@
|
|||||||
#ifndef SHARE_JFR_UTILITIES_JFRTIME_HPP
|
#ifndef SHARE_JFR_UTILITIES_JFRTIME_HPP
|
||||||
#define SHARE_JFR_UTILITIES_JFRTIME_HPP
|
#define SHARE_JFR_UTILITIES_JFRTIME_HPP
|
||||||
|
|
||||||
|
#include "jfr/utilities/jfrAllocation.hpp"
|
||||||
#include "utilities/ticks.hpp"
|
#include "utilities/ticks.hpp"
|
||||||
|
|
||||||
typedef TimeInstant<CounterRepresentation, FastUnorderedElapsedCounterSource> JfrTicks;
|
typedef TimeInstant<CounterRepresentation, FastUnorderedElapsedCounterSource> JfrTicks;
|
||||||
@ -41,4 +42,13 @@ class JfrTime {
|
|||||||
static const void* time_function();
|
static const void* time_function();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// For dynamically allocated Ticks values.
|
||||||
|
class JfrTicksWrapper : public JfrCHeapObj {
|
||||||
|
private:
|
||||||
|
JfrTicks _ticks;
|
||||||
|
public:
|
||||||
|
JfrTicksWrapper() : _ticks(JfrTicks::now()) {}
|
||||||
|
operator JfrTicks() const { return _ticks; }
|
||||||
|
};
|
||||||
|
|
||||||
#endif // SHARE_JFR_UTILITIES_JFRTIME_HPP
|
#endif // SHARE_JFR_UTILITIES_JFRTIME_HPP
|
||||||
|
@ -23,14 +23,15 @@
|
|||||||
|
|
||||||
package jdk.jfr.event.runtime;
|
package jdk.jfr.event.runtime;
|
||||||
|
|
||||||
|
import static jdk.test.lib.Asserts.assertNotNull;
|
||||||
|
import static jdk.test.lib.Asserts.assertNull;
|
||||||
import static jdk.test.lib.Asserts.assertTrue;
|
import static jdk.test.lib.Asserts.assertTrue;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import jdk.jfr.Recording;
|
import jdk.jfr.Recording;
|
||||||
import jdk.jfr.consumer.RecordedEvent;
|
import jdk.jfr.consumer.RecordedEvent;
|
||||||
|
import jdk.jfr.consumer.RecordedFrame;
|
||||||
|
import jdk.jfr.consumer.RecordedMethod;
|
||||||
|
import jdk.jfr.consumer.RecordedStackTrace;
|
||||||
import jdk.test.lib.Platform;
|
import jdk.test.lib.Platform;
|
||||||
import jdk.test.lib.jfr.EventNames;
|
import jdk.test.lib.jfr.EventNames;
|
||||||
import jdk.test.lib.jfr.Events;
|
import jdk.test.lib.jfr.Events;
|
||||||
@ -46,25 +47,49 @@ import jdk.test.lib.jfr.Events;
|
|||||||
public class TestNativeLibraryLoadEvent {
|
public class TestNativeLibraryLoadEvent {
|
||||||
|
|
||||||
private final static String EVENT_NAME = EventNames.NativeLibraryLoad;
|
private final static String EVENT_NAME = EventNames.NativeLibraryLoad;
|
||||||
|
private final static String LOAD_CLASS_NAME = "java.lang.System";
|
||||||
|
private final static String LOAD_METHOD_NAME = "loadLibrary";
|
||||||
|
private final static String LIBRARY = "instrument";
|
||||||
|
private final static String PLATFORM_LIBRARY_NAME = Platform.buildSharedLibraryName(LIBRARY);
|
||||||
|
|
||||||
public static void main(String[] args) throws Throwable {
|
public static void main(String[] args) throws Throwable {
|
||||||
try (Recording recording = new Recording()) {
|
try (Recording recording = new Recording()) {
|
||||||
recording.enable(EVENT_NAME);
|
recording.enable(EVENT_NAME);
|
||||||
recording.start();
|
recording.start();
|
||||||
System.loadLibrary("instrument");
|
System.loadLibrary(LIBRARY);
|
||||||
recording.stop();
|
recording.stop();
|
||||||
|
|
||||||
String expectedLib = Platform.buildSharedLibraryName("instrument");
|
|
||||||
boolean expectedLibFound = false;
|
|
||||||
for (RecordedEvent event : Events.fromRecording(recording)) {
|
for (RecordedEvent event : Events.fromRecording(recording)) {
|
||||||
System.out.println("Event:" + event);
|
if (validate(event)) {
|
||||||
String lib = Events.assertField(event, "name").notEmpty().getValue();
|
return;
|
||||||
Events.assertField(event, "success");
|
|
||||||
if (lib.contains(expectedLib)) {
|
|
||||||
expectedLibFound = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertTrue(expectedLibFound, "Missing library " + expectedLib);
|
assertTrue(false, "Missing library " + PLATFORM_LIBRARY_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean validate(RecordedEvent event) {
|
||||||
|
assertTrue(event.getEventType().getName().equals(EVENT_NAME));
|
||||||
|
String lib = Events.assertField(event, "name").notEmpty().getValue();
|
||||||
|
System.out.println(lib);
|
||||||
|
if (!lib.endsWith(PLATFORM_LIBRARY_NAME)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
assertTrue(Events.assertField(event, "success").getValue());
|
||||||
|
assertNull(Events.assertField(event, "errorMessage").getValue());
|
||||||
|
RecordedStackTrace stacktrace = event.getStackTrace();
|
||||||
|
assertNotNull(stacktrace);
|
||||||
|
for (RecordedFrame f : stacktrace.getFrames()) {
|
||||||
|
if (match(f.getMethod())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean match(RecordedMethod method) {
|
||||||
|
assertNotNull(method);
|
||||||
|
System.out.println(method.getType().getName() + "." + method.getName());
|
||||||
|
return method.getName().equals(LOAD_METHOD_NAME) && method.getType().getName().equals(LOAD_CLASS_NAME);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user