Top


定義場所(file name)

hotspot/src/share/vm/prims/jvmtiExport.cpp

名前(function name)

jint JvmtiExport::load_agent_library(AttachOperation* op, outputStream* st) {

本体部(body)

  {- -------------------------------------------
  (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.