今天遇到一個神奇的 bug, 程式掛掉後, 從 backtrace 看到其中一個函式名稱為 __cxa_pure_virtual, 從字面上的意思來看, 我呼叫了一個 pure virtual function, 所以程式掛了。但是 compiler 應該能抓到在 C++ 內呼叫 pure virtual function (Btw, Objective C++ 則否), 沒道理在 runtime 遇到這情況。
google 了一陣子, 看到這篇說有可能是呼叫 dangling pointer 的 virtual function, "Pure Virtual Function Called": An Explanation 則解釋各種可能的觸發原因。最後抓到兇手, 確實是呼叫 dangling pointer 的 virtual function。
依文章的解釋, destructor 會改變 virtual method table pointer 指向的位置, 最後會指向 abstract base class 的 virtual table, 裡面的 virtual function 則指向某個表示 pure virtual function 的指標 (gcc 用__cxa_pure_virtual)。所以, 若刪除指標後剛好記憶體內容保持原樣, 執行後就會呼叫到 __cxa_pure_virtual。
依管理記憶體的方式, 刪除指標時可能會保留原狀, 也可能填入特殊值故意觸發 crash。呼叫 dangling 可能會有不同結果。
沒有留言:
張貼留言