hotspot/src/share/vm/prims/jvmtiExport.cpp
jint JvmtiExport::load_agent_library(AttachOperation* op, outputStream* st) {
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
char ebuf[1024];
char buffer[JVM_MAXPATHLEN];
void* library;
jint result = JNI_ERR;
// get agent name and options
const char* agent = op->arg(0);
const char* absParam = op->arg(1);
const char* options = op->arg(2);
// The abs paramter should be "true" or "false"
bool is_absolute_path = (absParam != NULL) && (strcmp(absParam,"true")==0);
{- -------------------------------------------
(1) os::dll_load() で, 指定されたライブラリをロードする.
(なお, 絶対パスでない場合は
os::dll_build_name() で絶対パスに直してからロードする)
---------------------------------------- -}
// If the path is absolute we attempt to load the library. Otherwise we try to
// load it from the standard dll directory.
if (is_absolute_path) {
library = os::dll_load(agent, ebuf, sizeof ebuf);
} else {
// Try to load the agent from the standard dll directory
os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), agent);
library = os::dll_load(buffer, ebuf, sizeof ebuf);
if (library == NULL) {
// not found - try local path
char ns[1] = {0};
os::dll_build_name(buffer, sizeof(buffer), ns, agent);
library = os::dll_load(buffer, ebuf, sizeof ebuf);
}
}
{- -------------------------------------------
(1) ロードが成功した場合は, ライブラリ中の Agent_OnAttach() 関数を呼び出しておく.
(Agent_OnAttach() が JNI_OK を返した場合は, Agent_OnUnload() を後で呼び出すために,
Arguments::add_loaded_agent() で内部のリストに登録しておく)
(なお, Agent_OnAttach() が見つからない場合は os::dll_unload() でアンロードする)
---------------------------------------- -}
// If the library was loaded then we attempt to invoke the Agent_OnAttach
// function
if (library != NULL) {
// Lookup the Agent_OnAttach function
OnAttachEntry_t on_attach_entry = NULL;
const char *on_attach_symbols[] = AGENT_ONATTACH_SYMBOLS;
for (uint symbol_index = 0; symbol_index < ARRAY_SIZE(on_attach_symbols); symbol_index++) {
on_attach_entry =
CAST_TO_FN_PTR(OnAttachEntry_t, os::dll_lookup(library, on_attach_symbols[symbol_index]));
if (on_attach_entry != NULL) break;
}
if (on_attach_entry == NULL) {
// Agent_OnAttach missing - unload library
os::dll_unload(library);
} else {
// Invoke the Agent_OnAttach function
JavaThread* THREAD = JavaThread::current();
{
extern struct JavaVM_ main_vm;
JvmtiThreadEventMark jem(THREAD);
JvmtiJavaThreadEventTransition jet(THREAD);
result = (*on_attach_entry)(&main_vm, (char*)options, NULL);
}
// Agent_OnAttach may have used JNI
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
}
// If OnAttach returns JNI_OK then we add it to the list of
// agent libraries so that we can call Agent_OnUnload later.
if (result == JNI_OK) {
Arguments::add_loaded_agent(agent, (char*)options, is_absolute_path, library);
}
// Agent_OnAttach executed so completion status is JNI_OK
st->print_cr("%d", result);
result = JNI_OK;
}
}
{- -------------------------------------------
(1) 結果をリターン
---------------------------------------- -}
return result;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.