2011-06-11 153 views
0

我分析這個核心轉儲GDB:地址範圍映射

Program received signal SIGABRT, Aborted. 
    0xb7fff424 in __kernel_vsyscall() 
    (gdb) where 
    #0 0xb7fff424 in __kernel_vsyscall() 
    #1 0x0050cd71 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 
    #2 0x0050e64a in abort() at abort.c:92 
    #3 0x08083b3b in ??() 
    #4 0x08095461 in ??() 
    #5 0x0808bdea in ??() 
    #6 0x0808c4e2 in ??() 
    #7 0x080b683b in ??() 
    #8 0x0805d845 in ??() 
    #9 0x08083eb6 in ??() 
    #10 0x08061402 in ??() 
    #11 0x004f8cc6 in __libc_start_main (main=0x805f390, argc=15, ubp_av=0xbfffef64, init=0x825e220, fini=0x825e210, 
     rtld_fini=0x4cb220 <_dl_fini>, stack_end=0xbfffef5c) at libc-start.c:226 
    #12 0x0804e5d1 in ??() 

我無法知道哪些功能??地圖,或例如#10 0x08061402 in ??() 跌倒在地址範圍...

請幫我調試一下。

回答

2

你的程序有沒有調試符號。用-g重新編譯它。確保你還沒有剝離你的可執行文件,例如通過將-s傳遞給鏈接器。

+0

的標記的字段??不是從我已經用-g編譯的程序:這些符號來形成共享庫///哪一個?我想知道 ??以便我可以安裝debuginfo – KernelMonk 2011-06-11 15:58:54

+0

@ user794080:然後您的程序使用的庫之一缺少其調試符號。 – 2011-06-11 16:05:06

+0

@user:不,它們來自您的程序。 – ninjalj 2011-06-11 16:10:25

0

要知道庫映射到應用程序,記錄你的程序的PID,在gdb停止和其他控制檯運行

cat /proc/$pid/maps 

wher $ pid是停止進程的PID。地圖文件的格式在http://linux.die.net/man/5/proc描述 - 從開始「的/ proc/[數] /映射 一個包含當前映射存儲器區域和它們的訪問權限的文件」。

另外,如果您的操作系統不使用ASLR(地址空間佈局隨機化),或者是你的程序禁用,您可以使用

ldd ./program 

列出鏈接庫和他們的記憶範圍。但是,如果ASLR打開,您將無法獲得真實的內存映射範圍信息,因爲每次運行程序時它都會發生變化。但即使如此,你會知道,動態鏈接了哪些庫併爲它們安裝了調試信息。

+1

0x08xxx是可執行文件。 0x004xxx是庫。我瘦OP沒有運行exec-shield或PAX。 – ninjalj 2011-06-11 16:12:16

+0

它也可以是一個靜態庫。 – osgx 2011-06-11 16:14:19

+0

啊,是的,雖然我不希望'__libc_start_main'直接調用它。 – ninjalj 2011-06-11 16:15:16

2

即使@ user794080沒有這麼說,看來非常有可能,他的計劃是32位Linux可執行文件。

有從主可執行符號兩個可能的原因(我能想到的)(在該範圍內的堆棧跟蹤的所有符號[0x08040000,0x08100000)來自主可執行)沒有露面。

  1. 主要的可執行文件實際上已經被剝奪了(這是一樣的 ninjalj的答案),並經常當「-S」傳遞到連接器,也許在不經意間發生了。
  2. 可執行文件已經被編譯爲一個新的(er)GCC,但正在被一箇舊的(er)GDB調試,該GDB扼殺了一些較新的矮結構(應該有GDB的警告)。
0

堆棧可能已損壞。 「??」例如,如果堆棧上的返回地址被緩衝區溢出覆蓋,就會發生。