BTrace系列之一:簡介

What is Btrace?

Java進程診斷分析工具

安全的工具

         無侵入性

         不修改應用任何應用數據

         限制跟蹤行爲,沒能有循環

依賴組件

         使用OjbectWeb ASM組件來完成字節碼層面上的跟蹤分析

開源組件

         項目主頁:http://btrace.dev.java.net

GPLv2 + CLASSPATH Exception

VisualVM 插件和開發時插件

 

 

 

 

         BTrace應用較爲廣泛的原因應該是其安全性和無侵入性,已經熱交互技術,使得我們無需啓動Agent的情況下動態跟蹤分析,其安全性不會導致對目標Java進程的任何破壞性影響,使得BTrace成爲我們線上產品問題定位的利器。無侵入性無需我們對原有代碼做任何修改,降低上線風險和測試成本,並且無需重啓啓動目標Java進程進行Agent加載即可動態分析和跟蹤目標程序,可以說BTrace可以滿足大部分的應用場景。

Probes and Actions

通過註解來完成跟蹤類型的支持

l  方法調用

l  方法返回

l  捕捉方法異常

l  行號

l  字段get/set

l  方法調用/返回(在指定的方法中)

l  異常拋出前後

l  同步進入/退出

l  定時器

BTrace腳本

爲了保證trace語句只讀, BTrace對trace腳本有一些限制(比如不能改變被trace代碼中的狀態),跟蹤類中必須要有一個靜態方法,主要是通過調用BTraceUtils類來完成一些動作,並且這些動作是安全的,是BTrace規定的一個子集,詳見如下描述:

l  BTrace禁止new類、數組,、拋異常、捕獲異常

l  禁止調用除com.sun.btrace.BTraceUtil類的其他實例方法以及靜態方法

l  BTrace1.2前不能有實例字段和方法,只能有無返回值的靜態方法,所有字段也都必須是靜態的。

l  禁止定義外部、內部、匿名, 本地類

l  禁止有同步塊和同步方法

l  禁止有循環(for, while, do..while)

l  禁止實現接口, 不能擴展類,直接超類必須是java.lang.Object

l  禁止使用assert語句, 不能使用class字面值

l  禁止使用class字節碼

 

BTrace Class

方法上的註解 

l  @ OnMethod  用來指定trace的目標類和方法以及具體位置, 被註解的方法在匹配的方法執行到指定的位置會被調用。"clazz"屬性用來指定目標類名, 可以指定全限定類名, 比如"java.awt.Component", 也可以是正則表達式(表達式必須寫在"//"中, 比如"/java\\.awt\\..+/")。"method"屬性用來指定被trace的方法. 表達式可以參考自帶的例子(NewComponent.java 和 Classload.java, 關於方法的註解可以參考MultiClass.java). 有時候被trace的類和方法可能也使用了註解. 用法參考自帶例子WebServiceTracker.java. 針對註解也是可以使用正則表達式, 比如像這個"@/com\\.acme\\..+/ ",也可以通過指定超類來匹配多個類, 比如"+java.lang.Runnable"可以匹配所有實現了java.lang.Runnable接口的類. 具體參考自帶例子SubtypeTracer.java。

l  @OnTimer定時觸發Trace,時間可以指定,單位爲毫秒,具體參考自帶例子 Histogram.java。

l  @OnError 當trace代碼拋異常或者錯誤時,該註解的方法會被執行. 如果同一個trace腳本中其他方法拋異常, 該註解方法也會被執行。

l  @OnExit 當trace方法調用內置exit(int)方法(用來結束整個trace程序)時, 該註解的方法會被執行. 參考自帶例子ProbeExit.java。

l  @OnEvent 用來截獲"外部"btrace client觸發的事件, 比如按Ctrl-C 中斷btrace執行時,並且選擇2,或者輸入事件名稱,將執行使用了該註解的方法, 該註解的value值爲具體事件名稱。具體參考例子HistoOnEvent.java

l  @OnLowMemory 當內存超過某個設定值將觸發該註解的方法, 具體參考MemAlerter.java

l  @OnProbe 使用外部文件XML來定義trace方法以及具體的位置,具體參考示例SocketTracker1.java和java.net.socket.xml。

參數上的註解 

l  @Self 用來指定被trace方法的this,可參考例子AWTEventTracer.java 和 AllCalls1.java

l  @Return 用來指定被trace方法的返回值,可參考例子Classload.java

l  @ProbeClassName (since 1.1) 用來指定被trace的類名, 可參考例子AllMethods.java

l  @ProbeMethodName (since 1.1) 用來指定被trace的方法名, 可參考例子WebServiceTracker.java。

l  @TargetInstance (since 1.1) 用來指定被trace方法內部被調用到的實例, 可參考例子AllCalls2.java

l  @TargetMethodOrField (since 1.1) 用來指定被trace方法內部被調用的方法名, 可參考例子AllCalls1.java 和 AllCalls2.java。

 非註解的方法參數 

未使用註解的方法參數一般都是用來做方法簽名匹配用的, 他們一般和被trace方法中參數出現的順序一致. 不過他們也可以與註解方法交錯使用, 如果一個參數類型聲明爲*AnyType[]*, 則表明它按順序"通吃"方法所有參數. 未註解方法需要與*Location*結合使用: 

l  Kind.ENTRY-被trace方法參數

l  Kind.RETURN- 被trace方法返回值

l  Kind.THROW - 拋異常

l  Kind.ARRAY_SET, Kind.ARRAY_GET - 數組索引

l  Kind.CATCH - 捕獲異常

l  Kind.FIELD_SET - 屬性值

l  Kind.LINE - 行號

l  Kind.NEW - 類名

l  Kind.ERROR - 拋異常

 

屬性上的註解 

l  @Export 該註解的靜態屬性主要用來與jvmstat計數器做關聯. 使用該註解之後, btrace程序就可以向jvmstat客戶端(可以用來統計jvm堆中的內存使用量)暴露trace程序的執行次數, 具體可參考例子ThreadCounter.java

l  @Property 使用了該註解的trace腳本將作爲MBean的一個屬性, 一旦使用該註解, trace腳本就會創建一個MBean並向MBean服務器註冊, 這樣JMX客戶端比如VisualVM, jconsole就可以看到這些BTrace MBean. 如果這些被註解的屬性與被trace程序的屬性關聯, 那麼就可以通過VisualVM 和jconsole來查看這些屬性了. 具體可參考例子ThreadCounterBean.java 和 HistogramBean.java。

l  @TLS 用來將一個腳本變量與一個ThreadLocal變量關聯. 因爲ThreadLocal變量是跟線程相關的, 一般用來檢查在同一個線程調用中是否執行到了被trace的方法. 具體可參考例子OnThrow.java 和 WebServiceTracker.java

類上的註解 

l  @com.sun.btrace.annotations.DTrace 用來指定btrace腳本與內置在其腳本中的D語言腳本關聯, 具體參考例子DTraceInline.java.

l  @com.sun.btrace.annotations.DTraceRef 用來指定btrace腳本與另一個D語言腳本文件關聯. 具體參考例子DTraceRefDemo.java.

l  @com.sun.btrace.annotations.BTrace 用來指定該java類爲一個btrace腳本文件.

BTrace Samples

相關實例說明

BTrace自帶的sample是學習BTrace的最後資料,熟練使用BTrace中提供的sample並且能夠手動進行驗證,可以快速的熟悉BTrace並加載應用,自帶的sample也有很大一部分可以直接或者稍加修改就可以成爲我們的定位腳本,方便使用。

l  AWTEventTracer.java - 演示了對EventQueue.dispatchEvent()事件進行trace的做法, 可以通過instanceof來對事件進行過濾, 比如這裏只針對focus事件trace.

l  AllLines.java - 演示瞭如何在被trace的程序到達probe指定的類和指定的行號時執行指定的操作(例子中指定的行號是-1表示任意行).

l  AllSync.java - 演示瞭如何在進入/退出同步塊進行trace.

l  ArgArray.java - 演示了打印java.io包下所有類的readXXX方法的輸入參數.

l  Classload.java - 演示打印成功加載指定類以及堆棧信息.

l  CommandArg.java - 演示如何獲取btrace命令行參數.

l  Deadlock.java - 演示了@OnTimer註解和內置deadlock()方法的用法

l  DTraceInline.java - 演示@DTrace註解的用法

l  DTraceDemoRef.java - 演示@DTraceRef 註解的用法.

l  FileTracker.java - 演示瞭如何對File{Input/Output}Stream構造函數中初始化打開文件的讀寫文件操作進行trace.

l  FinalizeTracker.java - 演示瞭如何打印一個類所有的屬性, 這個在調試和故障分析中非常有用. 這裏的例子是打印FileInputStream類的close() /finalize() 方法被調用時的信息.

l  Histogram.java - 演示了統計javax.swing.JComponent在一個應用中被創建了多少次.

l  HistogramBean.java - 同上例, 只不過演示瞭如何與JMX集成, 這裏的map屬性通過使用@Property註解被暴露成一個MBean.

l  HistoOnEvent.java - 同上例, 只不過演示瞭如何在通過按ctrl+c中斷當前腳本時打印出創建次數, 而不是定時打印.

l  JdbcQueries.java - 演示了聚合(aggregation)功能. 關於聚合功能可參考DTrace.

l  JInfo.java - 演示了內置方法printVmArguments(), printProperties() 和printEnv() 的用法

l  JMap.java - 演示了內置方法dumpHeap()的用法. 即將目標應用的堆信息以二進制的形式dump出來

l  JStack.java - 演示了內置方法jstackAll()的用法, 即打印所有線程的堆棧信息.

l  LogTracer.java - 演示瞭如何深入實例方法(Logger.log)並調用內置方法(field() )打印私有屬性內容.

l  MemAlerter.java - 演示了使用@OnLowMememory 註解監控內存使用情況. 即堆內存中的年老代達到指定值時打印出內存信息.

l  Memory.java - 演示每隔4s打印一次內存統計信息.

l  MultiClass.java - 演示了通過使用正則表達式對多個類的多個方法進行trace.

l  NewComponent.java - 使用計數器每隔一段時間檢查當前應用中創建java.awt.Component的個數.

l  OnThrow.java - 當拋出異常時, 打印出異常堆棧信息.

l  ProbeExit.java - 演示@OnExit註解和內置exit(int)方法的用法

l  Profiling.java - 演示了對profile的支持.  // 我執行沒成功, BTrace內部有異常

l  Sizeof.java - 演示了內置的sizeof方法的使用.

l  SocketTracker.java - 演示了對socket的creation/bind方法的trace.

l  SocketTracker1.java - 同上, 只不過使用了@OnProbe.

l  SysProp.java - 演示了使用內置方法獲取系統屬性, 這裏是對 java.lang.System的getProperty方法進行trace.

l  SubtypeTracer.java - 演示瞭如何對指定超類的所有子類的指定方法進行trace.

l  ThreadCounter.java - 演示了在腳本中如何使用jvmstat 計數器. (jstat -J-Djstat.showUnsupported=true -name btrace.com.sun.btrace.samples.ThreadCounter.count 需要這樣來從外部通過jstat來訪問)

l  ThreadCounterBean.java - 同上, 只不過使用了JMX.

l  ThreadBean.java - 演示了對預編譯器的使用(並結合了JMX).

l  ThreadStart.java - 演示了腳本中DTrace的用法.

l  Timers.java - 演示了在一個腳本中同時使用多個@OnTimer

l  URLTracker.java - 演示了在每次URL.openConnection成功返回時打印出url. 這裏也使用了D語言腳本.

l  WebServiceTracker.java - 演示瞭如何根據註解進行trace.

 

其他相關博文
BTrace系列之一:簡介

BTrace系列之二:簡單示例

BTrace系列之三:實際案例

BTrace系列之四:破解


發佈了0 篇原創文章 · 獲贊 1 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章