linux2021
contributed by < >
開啟 Address Sanitizer
根據錯誤訊息可得知
console.c:308
的 do_help_cmd
函式echo
發生 global-buffer-overflow追蹤 do_help_cmd
函式:
看到 307 呼叫了 report
這個 function 後發生了問題,但同樣的 301 卻沒有問題,所以推估是 plist
所指向變數發生錯誤。
而plist
和 param_list
有關,所以在 console.c
尋找 param_list
。可以得知 param_list
是 global varible 以及找到主要兩個對 param_list
作用的 function (init_cmd
,add_parameter
)
可以看到 init_cmd
中的add_param
有使用 echo
並轉形成int *
當作輸入,而原本的 echo
是static bool
。
因為原本 bool
和 int
的大小不同,所以在 console.c:308
中對 plist->valp
做 dereference 發生錯誤 global-buffer-overflow
可以透過將 echo
原本的型別改成 static int
而 simulation
也有相似問題,所以也將在 console.[ch]
中 simulation
改為 int
,即可消除錯誤。
成功執行如下:
會執行 Makefile
裡面valgrind
的部份
會產生以下相關錯誤訊息
錯誤訊息告訴我們記憶體 still reachable
,代表程式結束時仍有記憶體未釋放。
那麼依照錯誤訊息查看相關程式碼
它做的事情是將 HISTORY_FILE = .cmd_history
的資料載入到在 linenoise.c:132
的 static char **history
。
註: HISTORY_FILE 可以用
grep -r HISTORY_FILE
找到在console.c
定義
可以發現無相關釋放記憶體的程式碼在其中。所以嘗試在程式碼中搜尋 free
關鍵字可以找到 freeHistory
。以 freeHistory
為關鍵字搜尋可以找到在 linenoiseAtExit
被使用,而 linenoiseAtExit
在 enableRawMode
被使用 …
最後可以發現這樣的關係, linenosie() -> linenoiseRaw() -> enableRawMode() -> atexit(linenoiseAtExit())-> freeHistory(), linenosie() 則是在 run_console() 被呼叫。
而 run_console() 則是在 qtest.c
使用到
查看 run_console
在 console.c:650
的程式碼,發現到只有在 has_infile = false
的時候才會呼叫到 linenoise
,而 has_infile
這個變數則會在 push_file()
中被修改 console.c:443
。如果有 infile 則為 ture,反之亦然。
所以在有 infile 的情況下,不會正常釋放 history 的記憶體。因此,可將qtest.c:777
改成如下,必有在有 infile 的情況下載入 history
可以查找 Valgrind manual #massif 搜尋相關資訊
執行 Valgrind tool=massif,會產生 visualize 檔,需要透過 sudo apt-get install
安裝 massif-visualizer
。接著使用 massif-visualizer
開啟
testfile 則是使用如下
用 massif-visualizer 開啟輸出檔之後畫面如下
註:default max-snapshots = 100
可以看到程式在運行時所使用到的 heap memory 的使用量。
將 max-snapshots 改為 1000 觀察更細緻的 heap memory 變化
觀察圖表之後可以發現到 heap memory 的使用變化量相當大,推估是在使用 simulation 來測量程式的 malloc 記憶體量變化很大。
在 dudect/constant.c
找到相對應程式碼如下
在 65~67 行中,插入 string 在 0~9999次之間。將次數固定為 10 來做觀察。可以發現到 heap memory 的使用量和變化量都變小了
將次數固定為 10000,在 heap memory 的使用量上仍有極大的變化,但與原本相比則有比較固定的 pattern, 推測造成變化量的原因為 get_random_string()
console.c:665
jasonmatobo-lab0 note
XDEv11-lab0 note #VALGRIND
jhan1998-lab0 #Massif
如何寫好 git commit message
C 語言 setjmp 與 longjmp 函數用法教學
coroutine:link0, link1, link2