 |
The most difficult bugs to fix are the ones that don’t exist. |
qe 是類似 dos pe2 或是
漢書的文字編輯器。在 google 搜尋已經找不到這個軟體的資訊, 所以想寫一篇來紀錄。
原作者是 Jiann-Ching Liu,
https://github.com/descent/qe 忘記從那個地方 clone 來, readme 提到的網址 http://www.cc.ncu.edu.tw/~center5/product/qe/ 已經無法連上, 所以只貼我 clone 的 source code。
readme 提到的網站
http://www.cc.ncu.edu.tw/~center5/product/qe/ 當然已經連不上。
按下2次 ESC, 會切到下方的命令列, 打 quit 可以離開 qe。在剛從 dos 轉到 linux 時, 還不太會用 vi 時, 短暫用過 qe。
目前的版本在 gcc 14 編譯會有 double free 的問題, 無法正常執行, 我嚇傻了, 之前用還好好的, 加上 sanitizer -fsanitize=undefined -fsanitize=address 後可以正常執行, 參考 fig 1。
身為軟體工程師, 看到這棘手的問題, 很想找出問題, 用了 valgrind, sanitizer 來查 double free, 不過沒什麼進展。由於是用 ncurses 寫的, 在除錯印出 debug message 上會有點麻煩, 增加點除錯困擾。
追了一下 code, 這應該是早期的 c++, 還沒有容器和 std::string, 要不然應該不會自己寫 linked list 和 string。
 |
fig 1. qe |
找了很久, 本來以為是 linebuffer 的 linked list 出問題, 結果是 qeString 引發, 並不是 linebuffer 這個 class, qeString 是類似 std::string 的東西, 我把動態 malloc 改成固定 array。
char str[10000];
就解決這個問題。
class qeString {
protected:
- char *str;
+ char str[10000];
有點奇怪, 感覺還是沒找到關鍵問題。
20251014 終於找到原因了, 的確和 qeString 有關。qe.cc 是簡化的版本, 這個就會得到 free(): double free detected in tcache 2 錯誤訊息。
原因是 qe.cc L15, linebuffer 繼承 qeString, 當手動喚起 linebuffer 解構函式時, 一併發動 qeString::~qeString(), 會 delete [] str, 而 qe.cc L17, delete current 會再次發動 qeString::~qeString(), 所以又再一次 delete [] str, 造成 double free。
delete current; 其實就會執行 current->~linebuffer();
是不是早期 c++ delete current 不會執行 current->~linebuffer();
參考 qe_df.log L9, L12, str 被重複 delete。
可是為什麼會這樣, qestring.cc L3 在 delete 之後有把 str 設定為 NULL, 照理來說 delete NULL 是不會有問題的, 後來發現是 -O2 影響的, 把 -O2 拿掉就正常。
list 6 沒有 -O2, 就沒遇到 delete 同個位址 str 的問題, 看來是 -O2 最佳化引起的。
gcc 7 也會編譯出有問題的 code, 一樣要拿掉 -O2。
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。