diff options
author | kgallowa <kgallowa@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-04-09 13:24:00 +0000 |
---|---|---|
committer | kgallowa <kgallowa@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-04-09 13:24:00 +0000 |
commit | 4a7e19a162b161c195c9aaf33af8133428ea0380 (patch) | |
tree | 4bdc9140017b37dc50c4160804f5a2aa7e3a648e /libjava/prims.cc | |
parent | d8a0d6b8af37fd836425e5d8e2f510c7e8753bd5 (diff) | |
download | gcc-4a7e19a162b161c195c9aaf33af8133428ea0380.tar.gz |
2007-04-09 Kyle Galloway <kgallowa@redhat.com>
* gij.cc (main): Accept -agentlib and -agentpath options.
* prims.cc (parse_init_args): Deal with -agentlib and -agentpath.
(load_jvmti_agent): New function.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123671 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/prims.cc')
-rw-r--r-- | libjava/prims.cc | 167 |
1 files changed, 165 insertions, 2 deletions
diff --git a/libjava/prims.cc b/libjava/prims.cc index a41912064e4..c610d72eea8 100644 --- a/libjava/prims.cc +++ b/libjava/prims.cc @@ -108,6 +108,16 @@ static bool remoteDebug = false; static char defaultJdwpOptions[] = ""; static char *jdwpOptions = defaultJdwpOptions; +// Typedefs for JVMTI agent functions. +typedef jint jvmti_agent_onload_func (JavaVM *vm, char *options, + void *reserved); +typedef jint jvmti_agent_onunload_func (JavaVM *vm); + +// JVMTI agent function pointers. +static jvmti_agent_onload_func *jvmti_agentonload = NULL; +static jvmti_agent_onunload_func *jvmti_agentonunload = NULL; +static char *jvmti_agent_opts; + // Argument support. int _Jv_GetNbArgs (void) @@ -1358,6 +1368,62 @@ parse_verbose_args (char* option_string, return 0; } +// This function loads the agent functions for JVMTI from the library indicated +// by name. It returns a negative value on failure, the value of which +// indicates where ltdl failed, it also prints an error message. +static jint +load_jvmti_agent (const char *name) +{ +#ifdef USE_LTDL + if (lt_dlinit ()) + { + fprintf (stderr, + "libgcj: Error in ltdl init while loading agent library.\n"); + return -1; + } + + lt_dlhandle lib = lt_dlopenext (name); + if (!lib) + { + fprintf (stderr, + "libgcj: Error opening agent library.\n"); + return -2; + } + + if (lib) + { + jvmti_agentonload + = (jvmti_agent_onload_func *) lt_dlsym (lib, "Agent_OnLoad"); + + if (!jvmti_agentonload) + { + fprintf (stderr, + "libgcj: Error finding agent function in library %s.\n" + name); + lt_dlclose (lib); + lib = NULL; + return -4; + } + else + { + jvmti_agentonunload + = (jvmti_agent_onunload_func *) lt_dlsym (lib, "Agent_OnUnload"); + + return 0; + } + } + else + { + fprintf (stderr, "libgcj: Library %s not found in library path.\n", name); + return -3; + } + +#endif /* USE_LTDL */ + + // If LTDL cannot be used, return an error code indicating this. + return -99; +} + static jint parse_init_args (JvVMInitArgs* vm_args) { @@ -1383,6 +1449,7 @@ parse_init_args (JvVMInitArgs* vm_args) for (int i = 0; i < vm_args->nOptions; ++i) { char* option_string = vm_args->options[i].optionString; + if (! strcmp (option_string, "vfprintf") || ! strcmp (option_string, "exit") || ! strcmp (option_string, "abort")) @@ -1410,6 +1477,95 @@ parse_init_args (JvVMInitArgs* vm_args) continue; } + else if (! strncmp (option_string, "-agentlib", sizeof ("-agentlib") - 1)) + { + char *strPtr; + + if (strlen(option_string) > (sizeof ("-agentlib:") - 1)) + strPtr = &option_string[sizeof ("-agentlib:") - 1]; + else + { + fprintf (stderr, + "libgcj: Malformed agentlib argument %s: expected lib name\n", + option_string); + return -1; + } + + // These are optional arguments to pass to the agent library. + jvmti_agent_opts = strchr (strPtr, '='); + + if (! strncmp (strPtr, "jdwp", 4)) + { + // We want to run JDWP here so set the correct variables. + remoteDebug = true; + jdwpOptions = ++jvmti_agent_opts; + } + else + { + jint nameLength; + + if (jvmti_agent_opts == NULL) + nameLength = strlen (strPtr); + else + { + nameLength = jvmti_agent_opts - strPtr; + jvmti_agent_opts++; + } + + char lib_name[nameLength + 3 + 1]; + strcpy (lib_name, "lib"); + strncat (lib_name, strPtr, nameLength); + + jint result = load_jvmti_agent (lib_name); + + if (result < 0) + { + return -1; + } + } + + continue; + } + else if (! strncmp (option_string, "-agentpath:", + sizeof ("-agentpath:") - 1)) + { + char *strPtr; + + if (strlen(option_string) > 10) + strPtr = &option_string[10]; + else + { + fprintf (stderr, + "libgcj: Malformed agentlib argument %s: expected lib path\n", + option_string); + return -1; + } + + // These are optional arguments to pass to the agent library. + jvmti_agent_opts = strchr (strPtr, '='); + + jint nameLength; + + if (jvmti_agent_opts == NULL) + nameLength = strlen (strPtr); + else + { + nameLength = jvmti_agent_opts - strPtr; + jvmti_agent_opts++; + } + + char lib_name[nameLength + 3 + 1]; + strcpy (lib_name, "lib"); + strncat (lib_name, strPtr, nameLength); + jint result = load_jvmti_agent (strPtr); + + if (result < 0) + { + return -1; + } + + continue; + } else if (vm_args->ignoreUnrecognized) { if (option_string[0] == '_') @@ -1570,6 +1726,10 @@ _Jv_RunMain (JvVMInitArgs *vm_args, jclass klass, const char *name, int argc, main_thread = new MainThread (JvNewStringUTF (name), arg_vec, is_jar); _Jv_AttachCurrentThread (main_thread); + + // Start JVMTI if an agent function has been found. + if (jvmti_agentonload) + (*jvmti_agentonload) (_Jv_GetJavaVM (), jvmti_agent_opts, NULL); // Start JDWP if (remoteDebug) @@ -1577,14 +1737,13 @@ _Jv_RunMain (JvVMInitArgs *vm_args, jclass klass, const char *name, int argc, using namespace gnu::classpath::jdwp; VMVirtualMachine::initialize (); Jdwp *jdwp = new Jdwp (); - jdwp->setDaemon (true); + jdwp->setDaemon (true); jdwp->configure (JvNewStringLatin1 (jdwpOptions)); jdwp->start (); // Wait for JDWP to initialize and start jdwp->join (); } - // Send VMInit if (JVMTI_REQUESTED_EVENT (VMInit)) _Jv_JVMTI_PostEvent (JVMTI_EVENT_VM_INIT, main_thread); @@ -1609,6 +1768,10 @@ _Jv_RunMain (JvVMInitArgs *vm_args, jclass klass, const char *name, int argc, JNIEnv *jni_env = _Jv_GetCurrentJNIEnv (); _Jv_JVMTI_PostEvent (JVMTI_EVENT_VM_DEATH, thread, jni_env); } + + // Run JVMTI AgentOnUnload if it exists and an agent is loaded. + if (jvmti_agentonunload) + (*jvmti_agentonunload) (_Jv_GetJavaVM ()); // If we got here then something went wrong, as MainThread is not // supposed to terminate. |