日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

反向 Debug 了解一下?揭秘 Java DEBUG 的基本原理

來源: 責編: 時間:2024-01-03 11:37:17 249觀看
導讀Debug 的時候,都遇到過手速太快,直接跳過了自己想調(diào)試的方法、代碼的時候吧……一旦跳過,可能就得重新執(zhí)行一遍,準備數(shù)據(jù)、重新啟動可能幾分鐘就過去了。好在IDE 們都很強大,還給你后悔的機會,可以直接刪除某個 Stack Frame

Debug 的時候,都遇到過手速太快,直接跳過了自己想調(diào)試的方法、代碼的時候吧……x9m28資訊網(wǎng)——每日最新資訊28at.com

一旦跳過,可能就得重新執(zhí)行一遍,準備數(shù)據(jù)、重新啟動可能幾分鐘就過去了。x9m28資訊網(wǎng)——每日最新資訊28at.com

好在IDE 們都很強大,還給你后悔的機會,可以直接刪除某個 Stack Frame,直接返回到之前的狀態(tài),確切的說是返回到之前的某個 Stack Frame,從而實現(xiàn)讓程序“逆向運行”。x9m28資訊網(wǎng)——每日最新資訊28at.com

x9m28資訊網(wǎng)——每日最新資訊28at.com

這個 Reset Frame 的能力,可不只是返回上一步,上 N 步也是可以的;選中你期望的那個幀,直接Reset Frame/Drop Frame,可以直接回到調(diào)用棧上的某個棧幀,時間反轉(zhuǎn)!x9m28資訊網(wǎng)——每日最新資訊28at.com

可惜這玩意也不是那么萬能,畢竟是通過 stack pop 這種操作實現(xiàn),實際上只是給調(diào)用棧棧頂?shù)?N 個 frame pop 出來而已,還談不上是真正的“反向 DEBUG”。x9m28資訊網(wǎng)——每日最新資訊28at.com

相比之下, GDB 的 Reverse Debugging 就比較強大,真正的 “反向” DEBUG,逆向運行,實現(xiàn)回放。x9m28資訊網(wǎng)——每日最新資訊28at.com

所以吧在運行過程中,已經(jīng)修改的數(shù)據(jù),比如引用傳遞的方法參數(shù)、變量,一旦修改肯定回退不了,不然真的成時光機了。x9m28資訊網(wǎng)——每日最新資訊28at.com

這些亂七八糟的調(diào)試功能,都是基于 Java 內(nèi)置的 Debug 體系來實現(xiàn)的。x9m28資訊網(wǎng)——每日最新資訊28at.com

JAVA DEBUG 體系

Java 提供了一個完整的 Debug 體系 JPDA (Java Platform Debugger Architecture),這個 JPDA 架構(gòu)體系由 3 部分組成:x9m28資訊網(wǎng)——每日最新資訊28at.com

  1. JVM TI - Java VM Tool Interface
  2. JDWP - Java Debug Wire Protocol
  3. JDI - Java Debug Interface

如果結(jié)合IDE 來看,那么一個完整的 Debug 功能看起來就是這個樣子:x9m28資訊網(wǎng)——每日最新資訊28at.com

x9m28資訊網(wǎng)——每日最新資訊28at.com

解釋一下這個體系:x9m28資訊網(wǎng)——每日最新資訊28at.com

JVM TI 是一個 JVM 提供的一個調(diào)試接口,提供了一系列控制 JVM 行為的功能,比如分析、調(diào)試、監(jiān)控、線程分析等等。也就是說,這個接口定義了一系列調(diào)試分析功能,而 JVM 實現(xiàn)了這個接口,從而提供調(diào)試能力。x9m28資訊網(wǎng)——每日最新資訊28at.com

不過吧,這個接口畢竟是 C++的,調(diào)用起來確實不方便,所以Java 還提供了 JDI 這么個 Java 接口。x9m28資訊網(wǎng)——每日最新資訊28at.com

JDI 接口使用 JDWP 這個私有的應用層協(xié)議,通過 TCP 和目標 VM 的 JVMTI 接口進行交互。x9m28資訊網(wǎng)——每日最新資訊28at.com

也可以把簡單這個 JDWP 協(xié)議理解為 JSF/Dubbo 協(xié)議;相當于 IDE 里通過 JDI 這個 SDK,使用 JDWP 協(xié)議調(diào)用遠程 JVMTI 的 RPC 接口,來傳輸調(diào)試時的各種斷點、查看操作。x9m28資訊網(wǎng)——每日最新資訊28at.com

可能有人會問,搞什么套殼!要什么 JDWP,我直接 JVMTI 調(diào)試不是更香,鏈路越短性能越高!x9m28資訊網(wǎng)——每日最新資訊28at.com

當然可以,比如 Arthas 里的部分功能,就直接使用了 JVMTI 接口,要什么 JDI!直接 JVMTI 干就完了。x9m28資訊網(wǎng)——每日最新資訊28at.com

開個玩笑,Arthas 畢竟不是 Debug 工具,人家根本就不用 JDI 接口。而且 JVMTI 的能力也不只是斷點,它的功能非常多:x9m28資訊網(wǎng)——每日最新資訊28at.com

x9m28資訊網(wǎng)——每日最新資訊28at.com

左邊的功能類,提供了各種亂七八糟的功能,比如我們常用的添加一個斷點:x9m28資訊網(wǎng)——每日最新資訊28at.com

jvmtiErrorSetBreakpoint(jvmtiEnv* env,            jmethodID method,            jlocation location)

右邊的事件類,可以簡單的理解為回調(diào);還是拿斷點舉例,如果我用上面的 SetBreakpoint 添加了一個斷點,那么當執(zhí)行到該位置時,就會觸發(fā)這個事件:x9m28資訊網(wǎng)——每日最新資訊28at.com

void JNICALLBreakpoint(jvmtiEnv *jvmti_env,            JNIEnv* jni_env,            jthread thread,            jmethodID method,            jlocation location)

JVMTI 的功能非常之多,而 JDI 只是實現(xiàn)了部分 JVMTI 的方法,所以某些專業(yè)的 Profiler 工具,可能會直接使用 JVMTI,從而實現(xiàn)更豐富的診斷分析功能。x9m28資訊網(wǎng)——每日最新資訊28at.com

遠程調(diào)試與本地調(diào)試

不知道大家有沒有留意過本地 Debug 啟動時的日志:x9m28資訊網(wǎng)——每日最新資訊28at.com

x9m28資訊網(wǎng)——每日最新資訊28at.com

第一行是隱藏了后半段的啟動命令,展開后是這個樣子:x9m28資訊網(wǎng)——每日最新資訊28at.com

/path/to/java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:53631,suspend=y,server=n -javaagent:/path/to/jetbrains/debugger-agent.jar ...

第二行是一個 Connected 日志,意思是使用 socket 連接到遠程 VM 的53631端口x9m28資訊網(wǎng)——每日最新資訊28at.com

上一段說到,IDE 通過 JDI 接口,使用 JDWP 協(xié)議和目標 VM 的 JVMTI 交互。這里的 53631 端口,就是目標 JVM 暴露出的 JVM TI 的 server 端口。x9m28資訊網(wǎng)——每日最新資訊28at.com

而第一行里,IDEA 自動給我們加上了 -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:53631 這么一段,這個參數(shù)的意思就是,讓 jvm 以 53631 暴露 jdwp 協(xié)議x9m28資訊網(wǎng)——每日最新資訊28at.com

小知識,這個 agentlib 可不只是為 jvmti 提供的。它還可以讓 JVM 加載其他的 native lib包,直接“”到你的 jvm 上,下面是參數(shù)格式:x9m28資訊網(wǎng)——每日最新資訊28at.com

x9m28資訊網(wǎng)——每日最新資訊28at.com

所以吧,上面的描述其實不太嚴謹,更專業(yè)的說法是:x9m28資訊網(wǎng)——每日最新資訊28at.com

讓 JVM 加載 JDWP 這個 agent 庫,參數(shù)為transport=dt_socket,address=127.0.0.1:53631 ,這個 jdwp agent 庫以 53631 端口提供了 jdwp 協(xié)議的 server。只不過這個 jdwp 是jvm 內(nèi)部的庫,不需要額外的 so/dylib/dll 文件。x9m28資訊網(wǎng)——每日最新資訊28at.com

如有需要,你完全可以弄個 “datupiao” 的 agentlib,”到這個 jvm 上,然后在這個 lib 里調(diào)用 JVMTI 接口,然后暴露個端口提供服務和遠程交互,實現(xiàn)自己的 jdwp!x9m28資訊網(wǎng)——每日最新資訊28at.com

可能某些老板們注意到了,本地調(diào)試還要127.0.0.1走tcp 交互一遍,那遠程調(diào)試呢?x9m28資訊網(wǎng)——每日最新資訊28at.com

基于上面的解釋,本地調(diào)試和遠程調(diào)試真的沒啥區(qū)別!或者說,在目前 IDEA/Eclipse 的實現(xiàn)下,不存在本地調(diào)試,都是遠程!只不過一個是 127.0.0.1,一個是遠程的 IP 而已。x9m28資訊網(wǎng)——每日最新資訊28at.com

在本地調(diào)試時,IDEA 會自動給我們的 JVM 增加 agent 參數(shù),隨機指定一個端口,然后通過 JDI 接口連接,代碼大概長這樣(JDI 的 SDK 在 JDK_HOME/lib/tools.jar ):x9m28資訊網(wǎng)——每日最新資訊28at.com

Map<String, Connector.Argument> env = connector.defaultArguments();env.get("hostname").setValue(hostname);env.get("port").setValue(port);VirtualMachine vm = connector.attach(env);

瞅瞅, VirtualMachine 里的就這點方法,能力上比 JVMTI 還是差遠了x9m28資訊網(wǎng)——每日最新資訊28at.com

List<ReferenceType> classesByName(String className);List<ReferenceType> allClasses();void redefineClasses(Map<? extends ReferenceType, byte[]> classToBytes);List<ThreadReference> allThreads();void suspend();void resume();List<ThreadGroupReference> topLevelThreadGroups();EventQueue eventQueue();EventRequestManager eventRequestManager();VoidValue mirrorOfVoid();Process process();

再回來看看 IDEA 中獨立的遠程調(diào)試,配置好之后,紅框里的信息會提示你 ,遠程的 JVM 需增加這一段啟動參數(shù),而且支持多個版本 JDK 的格式,CV 大法就能直接用。x9m28資訊網(wǎng)——每日最新資訊28at.com

x9m28資訊網(wǎng)——每日最新資訊28at.com

-agentlib 和 -javaagent

有些細心的同學可能發(fā)現(xiàn)了,IDEA 默認的啟動腳本里,同時配置了 -agentlib 和 -javaagent。x9m28資訊網(wǎng)——每日最新資訊28at.com

-javaagent:/path/to/jetbrains/debugger-agent.jar

這個 debugger-agent吧,其實也沒干啥事,只是對 JDK 內(nèi)置的一些線程做了些增強,輔助 IDEA 的 debug 功能,支持一些異步的調(diào)試。x9m28資訊網(wǎng)——每日最新資訊28at.com

x9m28資訊網(wǎng)——每日最新資訊28at.com

agentlib、javaagent 這倆兄弟,定位其實很像,都是加載自定義的代碼。x9m28資訊網(wǎng)——每日最新資訊28at.com

不過區(qū)別在于,agentlib 是加載 native lib,需要c/cpp 去寫,相當于自己的代碼在 jvm 上,可以為所欲為,比如在 agentlib 里調(diào)用上面說的 JVMTI 。x9m28資訊網(wǎng)——每日最新資訊28at.com

而 javaagent 是用 java 寫的,可以直接用上層的 Instrumentation API,做一些類的增強轉(zhuǎn)換之類,這也是大多數(shù) APM Agent、Profiler Agent實現(xiàn)的基本原理。x9m28資訊網(wǎng)——每日最新資訊28at.com

Arthas 的玩法

Arthas 的核心入口,其實還是 javaagent,支持靜態(tài)加載和動態(tài)加載兩種玩法。x9m28資訊網(wǎng)——每日最新資訊28at.com

靜態(tài)沒啥好說的,啟動腳本里增加一個-javaagent:/tmp/test/arthas-agent.jar,然后為所欲為。x9m28資訊網(wǎng)——每日最新資訊28at.com

動態(tài)的叫 attach,使用 Java 提供的 VirtualMachine 就可以實現(xiàn)運行時添加 -javaagent,效果一樣:x9m28資訊網(wǎng)——每日最新資訊28at.com

VirtualMachine virtualMachine = VirtualMachine.attach(virtualMachineDescriptor);virtualMachine.loadAgent(agentPath, agentArgs);

這個 Agent 在 JVM 里啟動了一個TCP server,用于收發(fā) Arthas Client 的各種 trace、watch 、Dashboard 等指令,然后通過 Instrumentation 增強Class 插入代碼、或者直接調(diào)用某些 Java API,實現(xiàn)各種功能。x9m28資訊網(wǎng)——每日最新資訊28at.com

注意到了嗎?Arthas 可以直接下載一個 jar 包,java -jar 就能連上。x9m28資訊網(wǎng)——每日最新資訊28at.com

其實吧,它這個直接啟動的 jar 包,是一個 boot 包,啟動之后把亂七八糟的 jar 都下載下來。接著動態(tài) attach 的方式,連接到本機指定進程號的 JVM,然后再為所欲為。x9m28資訊網(wǎng)——每日最新資訊28at.com

在 3.5 版本之后,Arthas 還新增了一個 vmtool 命令,這個命令可以直接獲取內(nèi)存中的指定對象實例。x9m28資訊網(wǎng)——每日最新資訊28at.com

$ vmtool --action getInstances --className java.lang.String --limit 10@String[][    @String[com/taobao/arthas/core/shell/session/Session],    @String[com.taobao.arthas.core.shell.session.Session],    @String[com/taobao/arthas/core/shell/session/Session],    @String[com/taobao/arthas/core/shell/session/Session],    @String[com/taobao/arthas/core/shell/session/Session.class],    @String[com/taobao/arthas/core/shell/session/Session.class],    @String[com/taobao/arthas/core/shell/session/Session.class],    @String[com/],    @String[java/util/concurrent/ConcurrentHashMap$ValueIterator],    @String[java/util/concurrent/locks/LockSupport],]

直接獲取內(nèi)存對象,這玩意只靠 Instrumentation API 可做不到。Arthas 搞了個騷操作,直接 JNI 調(diào)用自定義 lib,用過 cpp 直接調(diào)用了 JVMTI 的 API,融合了 Instrumentation 和 JVMTI 的能力,這下是真的為所欲為了!x9m28資訊網(wǎng)——每日最新資訊28at.com

#include <stdio.h>#include <jni.h>#include <jni_md.h>#include <jvmti.h>#include "arthas_VmTool.h" // under target/native/javah/static jvmtiEnv *jvmti;...extern "C"JNIEXPORT jobjectArray JNICALLJava_arthas_VmTool_getInstances0(JNIEnv *env, jclass thisClass, jclass klass, jint limit) {    jlong tag = getTag();    limitCounter.init(limit);    jvmtiError error = jvmti->IterateOverInstancesOfClass(klass, JVMTI_HEAP_OBJECT_EITHER,                                               HeapObjectCallback, &tag);    if (error) {        printf("ERROR: JVMTI IterateOverInstancesOfClass failed!%u/n", error);        return NULL;    }    jint count = 0;    jobject *instances;    error = jvmti->GetObjectsWithTags(1, &tag, &count, &instances, NULL);    if (error) {        printf("ERROR: JVMTI GetObjectsWithTags failed!%u/n", error);        return NULL;    }    jobjectArray array = env->NewObjectArray(count, klass, NULL);    //添加元素到數(shù)組    for (int i = 0; i < count; i++) {        env->SetObjectArrayElement(array, i, instances[i]);    }    jvmti->Deallocate(reinterpret_cast<unsigned char *>(instances));    return array;}

總結(jié)

  1. Debug 基于 JDPA 體系

IDE 直接接入 JDPA 體系中的 JDI 接口完成x9m28資訊網(wǎng)——每日最新資訊28at.com

JDI 通過 JDWP 協(xié)議,調(diào)用遠程 VM 的 JVMTI 接口x9m28資訊網(wǎng)——每日最新資訊28at.com

JDWP 是通過 agentlib 加載的,agentlib 算是一個 native 的靜態(tài)接口x9m28資訊網(wǎng)——每日最新資訊28at.com

  1. javaagent 是 JAVA 層面的接口,用過 Instrumentation API(Java)實現(xiàn)各種功能,主要用于APM、Profiler 工具
  2. 如果你想,在 javaagent 里調(diào)用功能更豐富的 JVMTI 也不是不行。

本文鏈接:http://www.www897cc.com/showinfo-26-56602-0.html反向 Debug 了解一下?揭秘 Java DEBUG 的基本原理

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 深入了解服務器 CPU 的型號、代際、片內(nèi)與片間互聯(lián)架構(gòu)

下一篇: Vue3問題:如何實現(xiàn)密碼加密登錄?前后端!

標簽:
  • 熱門焦點
  • 影音體驗是真的強 簡單聊聊iQOO Pad

    大公司的好處就是產(chǎn)品線豐富,非常細分化的東西也能給你做出來,例如早先我們看到了新的vivo Pad2,之后我們又在iQOO Neo8 Pro的發(fā)布會上看到了iQOO的首款平板產(chǎn)品iQOO Pad。雖
  • Golang 中的 io 包詳解:組合接口

    io.ReadWriter// ReadWriter is the interface that groups the basic Read and Write methods.type ReadWriter interface { Reader Writer}是對Reader和Writer接口的組合,
  • 一篇聊聊Go錯誤封裝機制

    %w 是用于錯誤包裝(Error Wrapping)的格式化動詞。它是用于 fmt.Errorf 和 fmt.Sprintf 函數(shù)中的一個特殊格式化動詞,用于將一個錯誤(或其他可打印的值)包裝在一個新的錯誤中。使
  • 多線程開發(fā)帶來的問題與解決方法

    使用多線程主要會帶來以下幾個問題:(一)線程安全問題  線程安全問題指的是在某一線程從開始訪問到結(jié)束訪問某一數(shù)據(jù)期間,該數(shù)據(jù)被其他的線程所修改,那么對于當前線程而言,該線程
  • 一文掌握 Golang 模糊測試(Fuzz Testing)

    模糊測試(Fuzz Testing)模糊測試(Fuzz Testing)是通過向目標系統(tǒng)提供非預期的輸入并監(jiān)視異常結(jié)果來發(fā)現(xiàn)軟件漏洞的方法。可以用來發(fā)現(xiàn)應用程序、操作系統(tǒng)和網(wǎng)絡協(xié)議等中的漏洞或
  • 國行版三星Galaxy Z Fold5/Z Flip5發(fā)布 售價7499元起

    2023年8月3日,三星電子舉行Galaxy新品中國發(fā)布會,正式在國內(nèi)推出了新一代折疊屏智能手機三星Galaxy Z Fold5與Galaxy Z Flip5,以及三星Galaxy Tab S9
  • iQOO Neo8系列新品發(fā)布會

    旗艦雙芯 更強更Pro
  • 與兆芯合作 聯(lián)想推出全新旗艦版筆記本電腦開天N7系列

    聯(lián)想與兆芯合作推出全新聯(lián)想旗艦版筆記本電腦開天 N7系列。這個系列采用兆芯KX-6640MA處理器平臺,KX-6640MA 處理器是采用了陸家嘴架構(gòu),16nm 工藝,4 核 4 線
  • 利用職權(quán)私自解除被封帳號 Meta開除20多名員工

    11月18日消息,據(jù)外媒援引知情人士表示,過去一年時間內(nèi),F(xiàn)acebook母公司Meta解雇或處罰了20多名員工以及合同工,指控這些人通過內(nèi)部系統(tǒng)以不當方式重置用戶帳號,其
Top 主站蜘蛛池模板: 剑川县| 聂荣县| 大兴区| 邯郸市| 宜州市| 宜城市| 浮梁县| 准格尔旗| 宕昌县| 双鸭山市| 家居| 黑河市| 巢湖市| 台山市| 惠安县| 聂荣县| 会泽县| 汶川县| 鹤壁市| 延庆县| 长宁区| 客服| 克东县| 铜山县| 武宣县| 栾川县| 旬邑县| 蒲江县| 浦江县| 海兴县| 三穗县| 莱阳市| 宝坻区| 崇阳县| 嘉禾县| 太康县| 阿坝| 白城市| 三明市| 保亭| 鱼台县|