安全堆疊(堆疊損壞)
堆疊損壞是令人煩惱的 bug。由於堆疊已損壞,偵錯程式通常無法為你提供良好的堆疊跟蹤,指出你的位置以及如何到達目的地。
這就是安全堆疊發揮作用的地方。它不使用單個堆疊用於你的執行緒,而是使用兩個:安全堆疊和危險堆疊。安全堆疊的工作原理與之前完全相同,只是某些部件被移動到危險的堆疊中。
堆疊的哪些部分被移動?
每一個有可能破壞堆疊的部分都會被移出安全堆疊。一旦堆疊上的變數通過引用傳遞或者獲取此變數的地址,編譯器將決定在第二個堆疊而不是安全堆疊上分配它。
因此,對這些指標執行的任何操作,對記憶體進行的任何修改(基於那些指標/引用)都只能影響第二個堆疊中的記憶體。由於永遠不會得到一個靠近安全堆疊的指標,堆疊不能破壞堆疊,偵錯程式仍然可以讀取堆疊上的所有函式以提供良好的跟蹤。
實際使用的是什麼?
安全堆疊不是為了給你更好的除錯體驗而發明的,但是,這對於討厭的 bug 來說是一個很好的副作用。它的最初目的是作為程式碼指標完整性(CPI)專案的一部分 ,在該專案中,它們試圖阻止覆蓋返回地址以防止程式碼注入。換句話說,他們試圖阻止執行黑客程式碼。
出於這個原因,該功能已在 Chrome 上啟用,據報道其 CPU 開銷<1%。
如何啟用它?
現在,該選項僅在 clang 編譯器中可用,其中可以將 -fsanitize=safe-stack
傳遞給編譯器。一個建議是為了實現在 GCC 相同的特徵。
結論
啟用安全堆疊時,堆疊損壞可以變得更容易除錯。由於效能開銷較低,你甚至可以在構建配置中預設啟用。