[文檔筆記]GDB偵錯進階觀念Memory Layout And The Stack

191 views
Skip to first unread message

cpyi

unread,
Mar 29, 2013, 3:31:19 PM3/29/13
to code_fellow...@googlegroups.com
我想大家應該也還都不常用Debugger來偵錯,我自己也不常用,只有一些使用GDB的經驗,不過一旦碰到函式的偵錯時,一些GDB的術語就讓人頭昏眼花,我想應該是一些基礎觀念不足的緣故。
我找到了一個不錯的文章,而且我想這跟GDB也沒有直接的關聯性,是一個很General的東西,應該對於程式底層的運作理解非常有幫助。
我就簡單為這個文章做一些節錄跟註記。
為什麼要理解程式的記憶體堆疊架構
  • 要確實的使用GDB這類symbolic debugger一定要具備這個知識。
  • 了解segment fault發生的原因與偵錯。
    • 最簡單的segment fault比如你存取超過陣列範圍的記憶體,就會造成segment fault。
虛擬記憶體
  • 這裡談的虛擬記憶體,並不是指當ram耗盡的時候,作業系統會用硬碟充當記憶體的那個虛擬記憶體,而是指在程式執行的時候,這些指令會被map到一段實體記憶體空間,但程式本身不需要自己實體記憶體的位置,他只需要他被分配到的這塊空間最初的地方就是零,這就是虛擬記憶體。
  • 也就是說,每次程式要存取記憶體的空間時,都必須將這個虛擬記憶體位址轉換為實體記憶體位址(physical memory address),這非常頻繁的發生,所以很多CPU會有一個專門處理這個部分的單元,叫做MMU(memory management unit)。
記憶體配置

  • 記憶體空間配置圖
    • High           Arguments and Environment Variables               參數以及環境變數
    •                   Stack                                                              堆疊(往下延伸),跟function call有很大的關聯。
    •                   Unused Memory                                               未使用的記憶體空間
    •                   Heap                                                               佇列(往上延伸),用以動態記憶體分配,比如C的malloc或C++的new。
    •                   Uninitialized Data Segment (bss)                                     未初始化資料區(由exec初始化為0)
    •                         Initialized Data Segment                                                   已初始化資料區(由exec讀取程式資料來初始化)
    •                         Text Segment                                                                      程式碼區段(由exec讀取程式資料來初始化),實際執行的程式碼就在這裡。 read-only(程式不應該被更改指令資料)。
  • 以hello.c為例,看每段記憶體的大小
    • 程式碼:
      • #include <stdio.h>
      • int main()
      • {
      • printf("Hello World\n");
      • return 0;
      • }
    • 用gcc編譯:
      •     gcc -W -Wall -c hello_world-1.c , gcc -o hello_world-1 hello_world-1.o
    • 用size指令看每段的大小:
    • size hello_world-1 hello_world-1.o 
    •    text data bss dec hex filename
    •    916 256 4 1176 498 hello_world-1
    •    48 0 0 48 30 hello_world-1.o
      • text是指令部分
      • data包含初始及未初始資料
      • dec hex是整個檔案大小,用十進位或十六進未表示
    • 也可以用objdump -h" or "objdump -x"指令檢查每段的大小
    • 習題:
      • The size command didn't list a stack or heap segment for hello_world or hello_world.o. Why do you think that is?
        • stack或heap是程式執行時才決定大小的,現在用size指令檢查檔案,當然沒有stack跟heap的大小資訊。
      • There are no global variables in hello_world-1.c. Give an explanation for why size reports that the data and bss segments have zero length for the object file but non-zero length for the executable.
        • 應該跟環境變數有關。
      • size and objdump report different sizes for the text segment. Can you guess where the discrepancy comes from? Hint: How big is the discrepancy? See anything of that length in the source code?
        • 不知道。
//以下懶得打字,直接貼上...。
Reply all
Reply to author
Forward
0 new messages