分析乙個bug,竟然還被誤導

2021-06-29 00:40:57 字數 1623 閱讀 3053

現象:

線上乙個應用在使用css掃瞄時經常出現cpu被吃掉的情況 ,一會吃掉乙個核,一會吃掉乙個核 。分析肯定是某種條件下觸發了死迴圈或大量耗時cpu操作。

於是用jstack拿到執行緒棧:

直接定位到270行:

第一印象是迴圈問題,但是進入this.nextchar()後發現,有乙個buf是動態擴容的:

public int nextchar() throws ioexception 

if (position == buffer.length)

return buffer[position++] = (char) current;

}

如果有種特殊情況,如在html中,只有那麼從開始到結束就都作為的內容送進來來掃瞄,而這些內容又不是真正的css,所以可能一直找不到  :和;這些分隔,那麼需要的buffer就會很大,而初始只有128的陣列就會不斷擴容和system.arraycopy。

所以第一時間優化這段程式,加大buffer初始值,減少copy,但沒有效果,上去還是很快就將cpu吃掉。

一直把buffer設定為10240,並判斷position >= 10240就丟擲異常,不產生一次擴容和copy,仍然沒有解決問題。

重新審視問題,準備拿樣本,在出現部分cpu核 被吃掉時拿dump:

也以為是很長,後面的**是省略了。

於是直接寫程式讀這一段位址開始的20k欄位,然後再開啟發面原來就是"font-sizt:20**", 我去,也沒去注意那個48位元組的說明。

直接拿這個樣本去除錯,果然死迴圈了:

原來while (cssscannerutilities.iscssnamecharacter((char) current)) 這裡,在20**表示式出錯以後,為了容錯會去讀";",之前的跳過,從:開始繼續解析。這樣是為了能盡量多解析一些正確的內容出來,可是這裡 20** 這個表示式出錯後,就到讀了-1。

(char)-1變成了65535,cssscannerutilities.iscssnamecharacter(65535)返回true,一直讀到-1,一直迴圈下去。

修復當然容易了:

while (current != -1 && cssscannerutilities.iscssnamecharacter((char) current))

果然,一切都安靜了。

這個案子被誤導的第乙個地方是死迴圈出現時進入nextchar方法中,假想了乙個內容很長情況,就去優化buffer,雖然這個情況有可能存在,但卻不是真實的。

第二個誤導被第乙個誤導先入了,是看到**就覺得這個樣本應該是很長很長,**是省略顯示,沒想到樣本就是 "font-sizt:20**",造成異常而觸發bug。

C 過載函式的乙個誤導

首先用typedef定義兩個float陣列型別 typedef float math3dvector2f 2 typedef float math3dvector3f 3 再分別用上面兩個型別變數過載乙個函式normalizevectorf void normalizevectorf math3dv...

記錄乙個BUG

vm版本 kali版本 centos 8 版本 vmtool版本 新裝的centos8 因為無法拖拽檔案到虛擬機器中,就重新裝了一下vmtool,安裝之後還是不行,開啟kali發現原本裝好的vmtool,現在也不能拖拽檔案了,就又在kali重灌了一次,還是不能拖拽,上網查了一下,在執行.vmware...

微軟的乙個BUG

各位,我不知道我的這個發現屬不屬於微軟的乙個bug round 1.225,2 1.23 round 1.245,2 1.25 round 1.265,2 1.26 round 1.285,2 1.28 按照技術文章上說的,vb中round 函式屬於四捨五入函式,但實際執行當中,其實round 函式...