30
30
#include " jvmtifiles/jvmtiEnv.hpp"
31
31
#include " prims/jvmtiEnvBase.hpp"
32
32
#include " prims/jvmtiExport.hpp"
33
+ #include " prims/jvmtiAgentList.hpp"
33
34
#include " runtime/arguments.hpp"
34
35
#include " runtime/handles.inline.hpp"
35
36
#include " runtime/interfaceSupport.inline.hpp"
36
37
#include " runtime/java.hpp"
37
38
#include " runtime/jniHandles.hpp"
39
+ #include " runtime/globals_extension.hpp"
38
40
#include " runtime/os.inline.hpp"
39
41
#include " runtime/thread.inline.hpp"
42
+ #include " utilities/defaultStream.hpp"
40
43
41
44
static inline const char * copy_string (const char * str) {
42
45
return str != nullptr ? os::strdup (str, mtServiceability) : nullptr ;
@@ -260,9 +263,9 @@ static void assert_preload(const JvmtiAgent* agent) {
260
263
261
264
// Check for a statically linked-in agent, i.e. in the executable.
262
265
// 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
264
267
// 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().
266
269
static bool load_agent_from_executable (JvmtiAgent* agent, const char * on_load_symbols[], size_t num_symbol_entries) {
267
270
DEBUG_ONLY (assert_preload (agent);)
268
271
assert (on_load_symbols != nullptr , " invariant" );
@@ -483,6 +486,7 @@ extern "C" {
483
486
}
484
487
485
488
// Loading the agent by invoking Agent_OnAttach.
489
+ // This function is called before the agent is added to JvmtiAgentList.
486
490
static bool invoke_Agent_OnAttach (JvmtiAgent* agent, outputStream* st) {
487
491
DEBUG_ONLY (assert_preload (agent);)
488
492
assert (agent->is_dynamic (), " invariant" );
@@ -491,7 +495,10 @@ static bool invoke_Agent_OnAttach(JvmtiAgent* agent, outputStream* st) {
491
495
const char * on_attach_symbols[] = AGENT_ONATTACH_SYMBOLS;
492
496
const size_t num_symbol_entries = ARRAY_SIZE (on_attach_symbols);
493
497
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 {
495
502
library = load_library (agent, &on_attach_symbols[0 ], num_symbol_entries, /* vm_exit_on_error */ false );
496
503
if (library == nullptr ) {
497
504
st->print_cr (" %s was not loaded." , agent->name ());
@@ -503,7 +510,17 @@ static bool invoke_Agent_OnAttach(JvmtiAgent* agent, outputStream* st) {
503
510
agent->set_os_lib_path (&buffer[0 ]);
504
511
agent->set_os_lib (library);
505
512
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 ());
506
522
}
523
+
507
524
assert (agent->is_loaded (), " invariant" );
508
525
// The library was loaded so we attempt to lookup and invoke the Agent_OnAttach function.
509
526
OnAttachEntry_t on_attach_entry = CAST_TO_FN_PTR (OnAttachEntry_t,
0 commit comments