使用btrace進行運行時異常原因分析

BTrace是Java的安全可靠的動態(tài)跟蹤工具。 他的工作原理是通過 instrument + asm 來對正在運行的java程序中的class類進行動態(tài)增強, 加入檢測代碼在運行時對應(yīng)用進行分析和跟蹤。

當線上應(yīng)用拋出一個異常柑爸,我們該如何使用btrace進行分析呢服球?

異常堆棧

java.io.NotSerializableException: com.xxx.UserServiceImpl
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    at de.javakaffee.web.msm.JavaSerializationTranscoder.writeAttributes(JavaSerializationTranscoder.java:139)
    at de.javakaffee.web.msm.JavaSerializationTranscoder.serializeAttributes(JavaSerializationTranscoder.java:100)
    at de.javakaffee.web.msm.TranscoderService.serializeAttributes(TranscoderService.java:151)
    at de.javakaffee.web.msm.BackupSessionTask.serializeAttributes(BackupSessionTask.java:179)
    at de.javakaffee.web.msm.BackupSessionTask.call(BackupSessionTask.java:109)
    at de.javakaffee.web.msm.BackupSessionTask.call(BackupSessionTask.java:50)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

使用btrace腳本進行運行時檢測

根據(jù)異常堆棧信息伐庭,對發(fā)生異常的代碼進行探測。location=@Location(Kind.ERROR) 表明 在發(fā)生未被捕獲的異常結(jié)束時執(zhí)行霸株。

import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

@BTrace public class WriteObjectErrDetect {

    @OnMethod(
        clazz="java.io.ObjectOutputStream",
        method="writeObject0",
     location=@Location(Kind.ERROR)
    )
    public static void detect(@ProbeClassName String probeClass, @ProbeMethodName String probeMethod,@TargetInstance Throwable err
,Object obj, boolean unshared) {
        print("#####1");
        println(str(obj));
    }

}

控制臺輸出:

#####org.springframework.security.core.context.SecurityContextImpl@29fefc4f
#####com.xxx.UserServiceImpl@10681811

從輸出看基本上可以斷定是SecurityContextImpl類的對象引用了UserServiceImpl對象去件,導(dǎo)致序列化失敗尤溜。因為UserServiceImpl對象不可序列化宫莱。

結(jié)合應(yīng)用代碼邏輯哩罪,輸出對象屬性看看:

import java.lang.reflect.Field;
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;


@BTrace public class WriteObjectErr {
    @OnMethod(
        clazz="java.io.ObjectOutputStream",
        method="writeObject",
     location=@Location(Kind.ERROR)
    )
    public static void detect(@ProbeClassName String probeClass, @ProbeMethodName String probeMethod,@TargetInstance Throwable err
,Object obj) {
        println("#####1");
        println(str(obj));
    printFields(obj);
        println("");
    Field field = field(classOf(obj), "authentication", false);
    if(field!=null) {
            println("#####2");
            Object auth = get(field, obj);
            printFields(auth);
        println("");
    }
    }
}

控制臺輸出

#####1

org.springframework.security.core.context.SecurityContextImpl@109497a3

{authentication=com.xxx.UserServiceImpl$3@4cdcf97c, }

#####2

{val$loginUser=com.xxx.User@2dc609e6, this$0=com.xxx.UserServiceImpl@10681811, }

從輸出可以看到际插,對象中屬性this$0引用了UserServiceImpl對象,證明了之前的猜想框弛。

this$0是什么屬性功咒? 它其實是匿名類或非靜態(tài)內(nèi)部類對外部對象的應(yīng)用。因此外部對象不可序列化力奋,導(dǎo)致了該序列化異常。

注意:在對線上環(huán)境進行分析的時候溅呢,最好在測試環(huán)境對btrace腳本進行驗證咐旧。btrace腳本有可能會導(dǎo)致線上jvm進程異常退出铣墨。此次就碰到了伊约, 在使用location=@Location(Kind.ERROR)的時候, 方法簽名上沒有@TargetInstance Throwable err腌逢,直接導(dǎo)致jvm進程退出了搏讶。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末媒惕,一起剝皮案震驚了整個濱河市吓笙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌巾腕,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,332評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尊搬,死亡現(xiàn)場離奇詭異,居然都是意外死亡佛寿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,508評論 3 385
  • 文/潘曉璐 我一進店門冀泻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蜡饵,你說我怎么就攤上這事弹渔。” “怎么了溯祸?”我有些...
    開封第一講書人閱讀 157,812評論 0 348
  • 文/不壞的土叔 我叫張陵舞肆,是天一觀的道長椿胯。 經(jīng)常有香客問我哩盲,道長廉油,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,607評論 1 284
  • 正文 為了忘掉前任娱两,我火速辦了婚禮十兢,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘摇庙。我一直安慰自己旱物,他們只是感情好,可當我...
    茶點故事閱讀 65,728評論 6 386
  • 文/花漫 我一把揭開白布卫袒。 她就那樣靜靜地躺著宵呛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪夕凝。 梳的紋絲不亂的頭發(fā)上宝穗,一...
    開封第一講書人閱讀 49,919評論 1 290
  • 那天,我揣著相機與錄音码秉,去河邊找鬼逮矛。 笑死,一個胖子當著我的面吹牛转砖,可吹牛的內(nèi)容都是我干的须鼎。 我是一名探鬼主播,決...
    沈念sama閱讀 39,071評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼府蔗,長吁一口氣:“原來是場噩夢啊……” “哼晋控!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起姓赤,我...
    開封第一講書人閱讀 37,802評論 0 268
  • 序言:老撾萬榮一對情侶失蹤赡译,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后模捂,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捶朵,經(jīng)...
    沈念sama閱讀 44,256評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蜘矢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,576評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了综看。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片品腹。...
    茶點故事閱讀 38,712評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖红碑,靈堂內(nèi)的尸體忽然破棺而出舞吭,到底是詐尸還是另有隱情,我是刑警寧澤析珊,帶...
    沈念sama閱讀 34,389評論 4 332
  • 正文 年R本政府宣布羡鸥,位于F島的核電站,受9級特大地震影響忠寻,放射性物質(zhì)發(fā)生泄漏惧浴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,032評論 3 316
  • 文/蒙蒙 一奕剃、第九天 我趴在偏房一處隱蔽的房頂上張望衷旅。 院中可真熱鬧,春花似錦纵朋、人聲如沸柿顶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嘁锯。三九已至,卻和暖如春聂薪,著一層夾襖步出監(jiān)牢的瞬間家乘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,026評論 1 266
  • 我被黑心中介騙來泰國打工藏澳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留烤低,地道東北人。 一個月前我還...
    沈念sama閱讀 46,473評論 2 360
  • 正文 我出身青樓笆载,卻偏偏與公主長得像,于是被迫代替她去往敵國和親涯呻。 傳聞我的和親對象是個殘疾皇子凉驻,可洞房花燭夜當晚...
    茶點故事閱讀 43,606評論 2 350

推薦閱讀更多精彩內(nèi)容