記一次除錯

2021-09-06 16:33:27 字數 1750 閱讀 6299

這是我最近幾個月來遇到的最棘手的乙個問題:

* 昨天花了4個小時找出第一層次的原因

這個糾結啊,本來和老婆說好準時下班回家吃飯的,結果被這個問題拖了老久。

這是乙個gradle的plugin,用來resolve公司內部的dependency的,弄完了跑測試專案的,拋乙個npe,而且npe還不在自己的**裡面。好吧,把gradle的源**翻出來看,如果是自己傳進去的乙個值是null,解決起來也還ok了。結果到裡面一看,那是乙個loop裡面,迭代map的時候出的錯 - 可以算是npe中的最壞情況了把。仔細檢視一下**,好吧,是迭代環境變數的。那行,在自己的**裡把環境變數都打出來誰是null吧。結果全ok,看來是順序問題,在我打出來的時候,那個null的還是設上呢。既然是環境變數被設,那就在自己的**裡搜搜看有沒有可疑點吧,還真找到個地方,一print還是真是在那個地方把path設成了null。

照理犯罪現場找到了,解決也就三下兩下的事了,於是我打算解決完,發完code review再走。結果發現那個null是被這麼設上的:

env_path = plugin_ext.getcompiletimejni(jnipaths)

這是groovy語言,plugin_ext是乙個gradle的plugin的extension,getcompiletimejni是定義在extension中的乙個closure,我死活檢查getcompiletimejni,他也絕對不可能返回null,如果有exception的話,也應該丟擲來,而不是返回null。

仔細檢查**,理清邏輯,列印結果,還是毫無頭緒,無奈已經7:30多了,還是先回去吧。

* 今天早上大概也兩個小時吧,找出的根本原因

週六早上起來, 多少還惦記著這件事,再看看吧。

終於,在觀察列印出來的結果時,我注意到乙個細節:在列印plugin_ext.getcompiletimejni的時候:

第一次是closure的位址

然後呼叫closure:plugin_ext.getcompiletimejni(jnipaths)

第二次就是乙個set了

這說明這個closure的呼叫有點蹊蹺,我已經檢查過了closure的實現本身沒有問題,那麼問題就在這簡簡單單的一句closure的呼叫上。 這花了我很長的時間去發現並相信著其實不是乙個函式呼叫,而是乙個賦值:

plugin_ext.getcompiletimejni(jnipaths)

就是plugin_ext.getcompiletimejni = jnipaths

我不知道為什麼gradle要發明這麼坑爹的語法 - 這絕對是編碼質量與效率的殺手,但是不管怎樣,根源問題是找到了:

env_path = plugin_ext.getcompiletimejni(jnipaths)

這個賦值語句永遠返回null

* 暫時有了乙個workaround,還沒有比較official的解決方案(if there is one)

你當然可以plugin_ext.getcompiletimejni,call,這是這改變了原有api的呼叫方式,是個breaking change,而且巨醜無比。

我覺得這是設計有點問題,也在諮詢gradle官方:

目前的workaround,還是基於gradle對extension的奇葩設計:

* 如果你的closure是定義在extension裡面的,呼叫即賦值,掛

* 如果你的closure沒在extension定義中,而是在後面使用時加上去的,呼叫還是呼叫,ok

所有workaround就是把getcompiletimejni移出extension的定義,在外面加。

記一次除錯

這是我最近幾個月來遇到的最棘手的乙個問題 昨天花了4個小時找出第一層次的原因 這個糾結啊,本來和老婆說好準時下班回家吃飯的,結果被這個問題拖了老久。這是乙個gradle的plugin,用來resolve公司內部的dependency的,弄完了跑測試專案的,拋乙個npe,而且npe還不在自己的 裡面。...

記一次nginx module 除錯

參考了 先進入nginx工作目錄 usr local nginx sbin 使用gdb q tui q選項是以安靜模式啟動,不顯示gdb版本等資訊。tui選項可以顯示 介面 然後在gdb中啟動nginx shell nginx 啟動之後,可以檢視當前nginx中的程序號 shell pidof ng...

記一次gpio喚醒除錯

使用tp的irq腳做手勢喚醒。雙擊螢幕後,從log看cpu已經被喚醒了,但很快又睡下去,通過log分析,發現沒有進入中斷處理函式。這裡使用的電平中斷。以前已分析過電平 邊沿喚醒cpu流程列印發現handle level irq只跑了一遍,第二次的handle level irq沒有過來導致無法進入中...