Skip to content

Commit 3cc731a

Browse files
committed
JVMTI agent is not unloaded when Agent_OnAttach is failed
1 parent 4b3a0b7 commit 3cc731a

File tree

4 files changed

+38
-12
lines changed

4 files changed

+38
-12
lines changed

src/hotspot/share/prims/jvmtiExport.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2641,7 +2641,9 @@ jint JvmtiExport::load_agent_library(const char *agent, const char *absParam,
26412641
void* library = NULL;
26422642
jint result = JNI_ERR;
26432643
const char *on_attach_symbols[] = AGENT_ONATTACH_SYMBOLS;
2644-
size_t num_symbol_entries = ARRAY_SIZE(on_attach_symbols);
2644+
size_t num_onattach_symbol_entries = ARRAY_SIZE(on_attach_symbols);
2645+
const char *on_unload_symbols[] = AGENT_ONUNLOAD_SYMBOLS;
2646+
size_t num_onunload_symbol_entries = ARRAY_SIZE(on_unload_symbols);
26452647

26462648
// The abs paramter should be "true" or "false"
26472649
bool is_absolute_path = (absParam != NULL) && (strcmp(absParam,"true")==0);
@@ -2653,7 +2655,7 @@ jint JvmtiExport::load_agent_library(const char *agent, const char *absParam,
26532655
// absolute we attempt to load the library. Otherwise we try to load it
26542656
// from the standard dll directory.
26552657

2656-
if (!os::find_builtin_agent(agent_lib, on_attach_symbols, num_symbol_entries)) {
2658+
if (!os::find_builtin_agent(agent_lib, on_attach_symbols, num_onattach_symbol_entries)) {
26572659
if (is_absolute_path) {
26582660
library = os::dll_load(agent, ebuf, sizeof ebuf);
26592661
} else {
@@ -2677,10 +2679,13 @@ jint JvmtiExport::load_agent_library(const char *agent, const char *absParam,
26772679
// If the library was loaded then we attempt to invoke the Agent_OnAttach
26782680
// function
26792681
if (agent_lib->valid()) {
2682+
JavaThread* THREAD = JavaThread::current();
2683+
extern struct JavaVM_ main_vm;
2684+
26802685
// Lookup the Agent_OnAttach function
26812686
OnAttachEntry_t on_attach_entry = NULL;
26822687
on_attach_entry = CAST_TO_FN_PTR(OnAttachEntry_t,
2683-
os::find_agent_function(agent_lib, false, on_attach_symbols, num_symbol_entries));
2688+
os::find_agent_function(agent_lib, false, on_attach_symbols, num_onattach_symbol_entries));
26842689
if (on_attach_entry == NULL) {
26852690
// Agent_OnAttach missing - unload library
26862691
if (!agent_lib->is_static_lib()) {
@@ -2691,9 +2696,7 @@ jint JvmtiExport::load_agent_library(const char *agent, const char *absParam,
26912696
delete agent_lib;
26922697
} else {
26932698
// Invoke the Agent_OnAttach function
2694-
JavaThread* THREAD = JavaThread::current();
26952699
{
2696-
extern struct JavaVM_ main_vm;
26972700
JvmtiThreadEventMark jem(THREAD);
26982701
JvmtiJavaThreadEventTransition jet(THREAD);
26992702

@@ -2710,6 +2713,23 @@ jint JvmtiExport::load_agent_library(const char *agent, const char *absParam,
27102713
if (result == JNI_OK) {
27112714
Arguments::add_loaded_agent(agent_lib);
27122715
} else {
2716+
// Find the Agent_OnUnload function.
2717+
Agent_OnUnload_t unload_entry = CAST_TO_FN_PTR(Agent_OnUnload_t,
2718+
os::find_agent_function(agent_lib,
2719+
false,
2720+
on_unload_symbols,
2721+
num_onunload_symbol_entries));
2722+
// Invoke the Agent_OnUnload function
2723+
if (unload_entry != NULL) {
2724+
JvmtiThreadEventMark jem(THREAD);
2725+
JvmtiJavaThreadEventTransition jet(THREAD);
2726+
2727+
(*unload_entry)(&main_vm);
2728+
}
2729+
2730+
if (!agent_lib->is_static_lib()) {
2731+
os::dll_unload(library);
2732+
}
27132733
delete agent_lib;
27142734
}
27152735

src/hotspot/share/prims/jvmtiExport.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -40,6 +40,11 @@
4040
// Must be included after jvmti.h.
4141
#include "jvmticmlr.h"
4242

43+
// type for the Agent_OnUnload entry point
44+
extern "C" {
45+
typedef void (JNICALL *Agent_OnUnload_t)(JavaVM *);
46+
}
47+
4348
// Forward declarations
4449

4550
class JvmtiEventControllerPrivate;

src/hotspot/share/runtime/thread.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4325,10 +4325,6 @@ void Threads::create_vm_init_agents() {
43254325
JvmtiExport::enter_primordial_phase();
43264326
}
43274327

4328-
extern "C" {
4329-
typedef void (JNICALL *Agent_OnUnload_t)(JavaVM *);
4330-
}
4331-
43324328
void Threads::shutdown_vm_agents() {
43334329
// Send any Agent_OnUnload notifications
43344330
const char *on_unload_symbols[] = AGENT_ONUNLOAD_SYMBOLS;

test/hotspot/jtreg/serviceability/dcmd/jvmti/AttachFailed/AttachReturnError.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
2525

2626
/*
2727
* @test
28-
* @bug 8165736
28+
* @bug 8165736 8252657
2929
* @library /test/lib
3030
* @run testng AttachReturnError
3131
*/
@@ -36,8 +36,13 @@ public void run(CommandExecutor executor) {
3636
String libpath = getSharedObjectPath("ReturnError");
3737
OutputAnalyzer output = null;
3838

39+
// Check return code
3940
output = executor.execute("JVMTI.agent_load " + libpath);
4041
output.shouldContain("return code: -1");
42+
43+
// Check agent unloading
44+
output = executor.execute("VM.dynlibs");
45+
output.shouldNotContain(libpath);
4146
} catch (Exception e) {
4247
throw new RuntimeException(e);
4348
}

0 commit comments

Comments
 (0)