3030#include " jvmtifiles/jvmtiEnv.hpp"
3131#include " prims/jvmtiEnvBase.hpp"
3232#include " prims/jvmtiExport.hpp"
33+ #include " prims/jvmtiAgentList.hpp"
3334#include " runtime/arguments.hpp"
3435#include " runtime/handles.inline.hpp"
3536#include " runtime/interfaceSupport.inline.hpp"
3637#include " runtime/java.hpp"
3738#include " runtime/jniHandles.hpp"
39+ #include " runtime/globals_extension.hpp"
3840#include " runtime/os.inline.hpp"
3941#include " runtime/thread.inline.hpp"
42+ #include " utilities/defaultStream.hpp"
4043
4144static inline const char * copy_string (const char * str) {
4245 return str != nullptr ? os::strdup (str, mtServiceability) : nullptr ;
@@ -260,9 +263,9 @@ static void assert_preload(const JvmtiAgent* agent) {
260263
261264// Check for a statically linked-in agent, i.e. in the executable.
262265// This should be the first function called when loading an agent. It is a bit special:
263- // For statically linked agents we cant 't rely on os_lib == nullptr because
266+ // For statically linked agents we can 't rely on os_lib == nullptr because
264267// statically linked agents could have a handle of RTLD_DEFAULT which == 0 on some platforms.
265- // If this function returns true, then agent->is_static_lib(). && agent->is_loaded().
268+ // If this function returns true, then agent->is_static_lib() && agent->is_loaded().
266269static bool load_agent_from_executable (JvmtiAgent* agent, const char * on_load_symbols[], size_t num_symbol_entries) {
267270 DEBUG_ONLY (assert_preload (agent);)
268271 assert (on_load_symbols != nullptr , " invariant" );
@@ -483,6 +486,7 @@ extern "C" {
483486}
484487
485488// Loading the agent by invoking Agent_OnAttach.
489+ // This function is called before the agent is added to JvmtiAgentList.
486490static bool invoke_Agent_OnAttach (JvmtiAgent* agent, outputStream* st) {
487491 DEBUG_ONLY (assert_preload (agent);)
488492 assert (agent->is_dynamic (), " invariant" );
@@ -491,7 +495,10 @@ static bool invoke_Agent_OnAttach(JvmtiAgent* agent, outputStream* st) {
491495 const char * on_attach_symbols[] = AGENT_ONATTACH_SYMBOLS;
492496 const size_t num_symbol_entries = ARRAY_SIZE (on_attach_symbols);
493497 void * library = nullptr ;
494- if (!load_agent_from_executable (agent, &on_attach_symbols[0 ], num_symbol_entries)) {
498+ bool previously_loaded;
499+ if (load_agent_from_executable (agent, &on_attach_symbols[0 ], num_symbol_entries)) {
500+ previously_loaded = JvmtiAgentList::is_static_lib_loaded (agent->name ());
501+ } else {
495502 library = load_library (agent, &on_attach_symbols[0 ], num_symbol_entries, /* vm_exit_on_error */ false );
496503 if (library == nullptr ) {
497504 st->print_cr (" %s was not loaded." , agent->name ());
@@ -503,7 +510,17 @@ static bool invoke_Agent_OnAttach(JvmtiAgent* agent, outputStream* st) {
503510 agent->set_os_lib_path (&buffer[0 ]);
504511 agent->set_os_lib (library);
505512 agent->set_loaded ();
513+ previously_loaded = JvmtiAgentList::is_dynamic_lib_loaded (library);
514+ }
515+
516+ // Print warning if agent was not previously loaded and EnableDynamicAgentLoading not enabled on the command line.
517+ if (!previously_loaded && !FLAG_IS_CMDLINE (EnableDynamicAgentLoading) && !agent->is_instrument_lib ()) {
518+ jio_fprintf (defaultStream::error_stream (),
519+ " WARNING: A JVM TI agent has been loaded dynamically (%s)\n "
520+ " WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning\n "
521+ " WARNING: Dynamic loading of agents will be disallowed by default in a future release\n " , agent->name ());
506522 }
523+
507524 assert (agent->is_loaded (), " invariant" );
508525 // The library was loaded so we attempt to lookup and invoke the Agent_OnAttach function.
509526 OnAttachEntry_t on_attach_entry = CAST_TO_FN_PTR (OnAttachEntry_t,
0 commit comments