posts - 15,comments - 65,trackbacks - 0
          <2013年4月>
          31123456
          78910111213
          14151617181920
          21222324252627
          2829301234
          567891011

          常用鏈接

          留言簿(5)

          隨筆檔案

          文章檔案

          blog

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

                想必不少人聽(tīng)說(shuō)過(guò)javaagent,但是很少人聽(tīng)說(shuō)Instrumentation,其實(shí)Instrumentation就是javaagent的實(shí)現(xiàn)機(jī)制,說(shuō)到Instrumentation,就必須想了解javaattach機(jī)制,那就先說(shuō)下attach的實(shí)現(xiàn)。

                  大家進(jìn)行jstack的時(shí)候,是不是經(jīng)常看到兩個(gè)線程Signal Dispatcher Attach Listener線程,可能不知道是干嘛的吧,這兩個(gè)線程是實(shí)現(xiàn)attach的關(guān)鍵所在,其中前者是在jvm啟動(dòng)的時(shí)候就會(huì)創(chuàng)建的,后者只有接收過(guò)attach請(qǐng)求的時(shí)候vm才會(huì)創(chuàng)建,顧名思義,Signal Dispatcher是分發(fā)信號(hào)的, Attach Listener 是處理attach請(qǐng)求的,那么兩者有什么關(guān)系呢,當(dāng)我們執(zhí)行attach方法的時(shí)候,會(huì)向目標(biāo)vm發(fā)出一個(gè)SIGQUIT 的信號(hào),目標(biāo)vm收到這個(gè)信號(hào)之后就會(huì)創(chuàng)建Attach Listener線程了,當(dāng)然jvm保證了不會(huì)多創(chuàng)建。
           1  path = findSocketFile(pid);
           2         if (path == null) {
           3             File f = new File(tmpdir, ".attach_pid" + pid);
           4             createAttachFile(f.getPath());
           5             try {
           6                 sendQuitTo(pid);
           7 
           8                 // give the target VM time to start the attach mechanism
           9                 int i = 0;
          10                 long delay = 200;
          11                 int retries = (int)(attachTimeout() / delay);
          12                 do {
          13                     try {
          14                         Thread.sleep(delay);
          15                     } catch (InterruptedException x) { }
          16                     path = findSocketFile(pid);
          17                     i++;
          18                 } while (i <= retries && path == null);
          19                 if (path == null) {
          20                     throw new AttachNotSupportedException(
          21                         "Unable to open socket file: target process not responding " +
          22                         "or HotSpot VM not loaded");
          23                 }
          24             } finally {
          25                 f.delete();
          26             }
          27         }
                  Attach機(jī)制說(shuō)得簡(jiǎn)單點(diǎn)就是提供A進(jìn)程可以連上B進(jìn)程(當(dāng)然是java進(jìn)程),創(chuàng)建socket進(jìn)行通信,A通過(guò)發(fā)命令給B,B然后對(duì)命令進(jìn)行截取從自己的vm中獲取信息發(fā)回給客戶端vm,但是并不是隨便發(fā)指令都會(huì)處理的,那么attach Listener接收哪些命令呢,如下所示
          static AttachOperationFunctionInfo funcs[] = {
            { "agentProperties",  get_agent_properties },
            { "datadump",         data_dump },
            { "dumpheap",         dump_heap },
            { "load",             JvmtiExport::load_agent_library },
            { "properties",       get_system_properties },
            { "threaddump",       thread_dump },
            { "inspectheap",      heap_inspection },
            { "setflag",          set_flag },
            { "printflag",        print_flag },
            { "jcmd",             jcmd },
            { NULL,               NULL }
          };
                   Instrumentation的實(shí)現(xiàn)其實(shí)主要使用了load這個(gè)指令,它用來(lái)實(shí)現(xiàn)讓target vm動(dòng)態(tài)加載agentlib,Instrumentation的實(shí)現(xiàn)在一個(gè)名為libinstrument.dylib的動(dòng)態(tài)lib庫(kù),linux下是libinstrument.so,它是基于jvmti接口實(shí)現(xiàn)的,因此在對(duì)其進(jìn)行l(wèi)oad的時(shí)候會(huì)創(chuàng)建一個(gè)agent實(shí)例,并往jvmti環(huán)境注冊(cè)一些回調(diào)方法,比如監(jiān)聽(tīng)類文件加載的事件,vm初始化完成事件等,執(zhí)行Agent_OnAttach,這里會(huì)創(chuàng)建一個(gè)Instrumentation實(shí)例并返回給用戶供大家擴(kuò)展Instrumentation,比如增加一些transform。并會(huì)執(zhí)行Instrumentation實(shí)例的loadClassAndCallAgentmain方法,該方法主要執(zhí)行agent的MF文件里定義的 Agent-Class類的agentmain方法,當(dāng)vm初始化完畢之后,會(huì)調(diào)用loadClassAndCallPremain方法,該方法主要執(zhí)行agent的MF文件里定義的 Agent-Class類的pre main方法。在類進(jìn)行加載的時(shí)候會(huì)調(diào)用Instrumentation的transform方法,可以看看參數(shù)里有個(gè)byte數(shù)組,這個(gè)數(shù)組其實(shí)就是正在加載的class字節(jié)碼,所以如果要字節(jié)碼增強(qiáng)在這里就可以入手啦,甚至可以實(shí)現(xiàn)偷天換日.
          posted on 2013-04-12 22:38 你假笨 閱讀(2206) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 旺苍县| 威海市| 邻水| 华坪县| 四子王旗| 时尚| 临潭县| 辰溪县| 红安县| 潞西市| 马公市| 广灵县| 抚远县| 东平县| 天等县| 五华县| 清新县| 连城县| 五河县| 朝阳县| 环江| 湘潭县| 许昌市| 泰兴市| 山西省| 宣威市| 武陟县| 马边| 六安市| 奎屯市| 太康县| 梓潼县| 吉林省| 景洪市| 通道| 通化市| 黑山县| 灌阳县| 咸丰县| 天等县| 平江县|