coredump 堆棧被寫壞問題定位


coredump 堆棧被寫壞問題定位

獨家號 ftom 作者 ftom原文鏈接

問題描述

游戲后台有一個導號工具,主要是把外網玩家賬號數據導入到內部環境供調試使用。 但是在導到有家族的賬號的時候,腳本會core掉並且退出。 腳本運行是每次請求的時候拉起,執行完畢之后釋放資源,無法在線進行gdb attach 上去斷點看問題。


查問題第一步當然是盡可能的收集遇到的問題。 查看coredump 文件,bt堆棧如下所示:發生了Segment Fault 段錯誤,但是函數堆棧被寫壞了 沒有進一步可以幫助到的信息。


不過方法總比問題多。 我們可以在編譯新的可執行文件時開啟以下gcc 編譯選項

  • -fstack-protector-all (https://www.ibm.com/developerworks/cn/linux/l-cn-gccstack/index.html) 該選項旨在通過Canaries檢測來判斷棧是否被破壞,在破壞前讓程序拋異常退出。 當然還有另外一個目的是提高棧溢出攻擊的成本。有興趣的可以了解下原理。通過這種方式來進行堆棧保護

  • -g 加上g選項后編譯器會做如下額外操作
    • 創建符號表,生成的文件包含符號表內容。生成的core文件也會附帶符號表相關內容
    • 關閉優化機制,程序嚴格按照原來的代碼執行,避免定位問題對應代碼帶來的偏移干擾
  • 開啟-O0 選項避免參數和函數inline。 生產環境建議開啟為-O2 。這里為了方便定位問題,臨時調整成該選項。

執行完上述步驟之后,采用新的二進制文件執行,程序coredump文件堆棧 如下所示:

出現_stack_chk_fail 毫無疑問是棧空間被寫壞了。bt查看函數棧楨底部丟失,第#6函數楨丟失, 可以推斷是上一楨函數把自己的返回地址搞丟了。可以重點排查下SaveTbFamily上 申請的棧變量以及內存拷貝賦值相關的代碼


如果邏輯比較復雜,可以把該函數內申請的所有棧變量【主要是自定義類型】替換成堆變量。 再編一個版本出去,棧溢出可以肯定也能把對應的堆變量整溢出,堆溢出不至於把函數棧弄壞。

重新修改一個版本之后,重新執行獲取到的core文件如下:這里終於借助堆溢出把完整的函數棧打印出來了。 接下來的事情就是常規的coredump問題定位了。


當然上述步驟僅限於在內網操作,如果是現網,最好隔離出一台機子,放少量流量進來復現。 定位問題不以要影響現網服務為首要原則 目前僅遇到上述場景,有其他好的方法,歡迎交流

擴展閱讀:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM