開發工具系列(一):Btrace——線上Debug工具
阿新 • • 發佈:2019-01-30
Btrace
Btrace用於除錯正在執行的系統,並且在除錯時不會暫停系統。特別適用於跟蹤線上問題。你可以實時監控一個系統中任何一個方法的呼叫,你可以知道這些方法的引數、返回值是什麼,還可以知道方法呼叫消耗了多少時間。
Btrace不需要安裝,只要下載一個包,解壓即可。
Btrace用法為bin/btrace <pid> <trace-script>
。其中pid
是正在執行的java程序,trace-script
是跟蹤指令碼,它其實就是一段java程式碼。
Hello World
首先我們模擬一個正在執行的程式,它僅有一個迴圈。
}
然後開啟這個程式: java com.caipeichao.NullApp
通過jps命令得到這個程式的PID,這裡為13348。
> jps3034 RemoteMavenServer2902 Main15147 Jps13348 NullApp準備工作做完了,現在編寫最重要的跟蹤指令碼。
@BTrace}執行btrace,得到如下輸出。
> btrace 13348 HelloBtrace.javaHello worldHello worldHello worldHello worldHello worldHello world常用註解
名稱 | 作用域 | 作用 |
---|---|---|
@BTrace |
類 | 宣告跟蹤指令碼 |
@OnMethod(clazz,method,location) |
方法 | 當指定方法被呼叫時 |
@OnMethod(method="<init>") |
方法 | 當建構函式被呼叫時 |
@OnMethod(clazz="/java\\.io\\..*Input/")) |
方法 | 方法名稱正則匹配 |
@Location(kind) |
@OnMethod |
指定監控方法呼叫前還是呼叫後 |
@Location(value=Kind.NEWARRAY, clazz="char") |
@OnMethod |
監控新增陣列 |
@Self |
引數 | 表示被監控的物件 |
@ProbeMethodName |
引數 | 被監控的方法名稱 |
@ProbeClassName |
引數 | 被監控的類名 |
@OnTimer(interval) |
方法 | 定時呼叫某個方法 |
@OnLowMemory(pool,threshold) |
方法 | 當記憶體不足時 |
@OnExit |
方法 | 當程式退出時 |
@OnProbe(namespace="java.net.socket",name="bind") |
方法 | 監控socket中的bind方法 |
常用方法
方法 | 作用 |
---|---|
println |
在本地控制檯輸出一行 |
print |
在本地控制檯輸出 |
printArray |
在本地控制檯輸出陣列 |
jstack |
列印遠端方法的呼叫呼叫棧 |
jstackAll |
輸出所有執行緒的呼叫棧 |
exit |
退出跟蹤指令碼 |
Strings.strcat |
連線字串 |
Reflactive.name |
獲取類名 |
Threads.name |
執行緒名 |
Threads.currentThread |
當前執行緒 |
deadlocks |
打出死鎖執行緒 |
sizeof |
獲取物件的大小,比如List 物件就返回List.size() |
Sys.Env.property |
獲取系統變數 |
原理
BTrace利用了java.lang.instrument
包實現程式碼注入。首先通過VirtualMachine.attach(pid)
連線遠端JVM,然後通過VirtualMachine.loadAgent("*.jar")
載入一個btrace的jar包。這個jar包最重要的程式碼如下。
一句話總結,btrace利用instrument工具修改JVM記憶體中的類位元組碼,達到注入程式碼的目的。