2016-09-29 37 views
2

我正在做一些編輯進程內存的實驗,當它運行時,我注意到當我在gdb'd進程中調用calloc時,調用似乎工作並返回原始傳遞的指針,但內存似乎不被初始化爲0:如果我叫memset的結果指針爲什麼在gdb中調用calloc不會將內存清零?

(gdb) call calloc(1, 32) 
$88 = (void *) 0x8d9d50 
(gdb) x/8xw 0x8d9d50 
0x8d9d50:  0xf74a87d8  0x00007fff  0xf74a87d8  0x00007fff 
0x8d9d60:  0xfbfbfbfb  0xfbfbfbfb  0x00000000  0x9b510000 

,但是,初始化工作得很好:

(gdb) call memset(0x8d9d50, 0, 32) 
$89 = 9280848 
(gdb) x/8xw 0x8d9d50 
0x8d9d50:  0x00000000  0x00000000  0x00000000  0x00000000 
0x8d9d60:  0x00000000  0x00000000  0x00000000  0x00000000 

回答

7

有趣的問題。答案是:在Linux(在這裏我假設你跑你的程序)這樣的:

(gdb) call calloc(1, 32) 

不會libc.so.6調用calloc

寧可叫callocld-linux.so.2。而calloc是非常小的。它預計僅從ld-linux.so.2本身被調用,並且它假設它訪問的任何頁面都是「乾淨的」並且do not require a memset。 (也就是說,我無法使用glibc-2.19重現不清晰的calloc)。

可以證實這一點,像這樣:

#include <stdlib.h> 
int main() 
{ 
    void *p = calloc(1, 10); 
    return p == 0; 
} 

gcc -g foo.c -m32 && gdb -q ./a.out 

Reading symbols from ./a.out...done. 
(gdb) start 
Temporary breakpoint 1 at 0x8048426: file foo.c, line 4. 
Starting program: /tmp/a.out 

Temporary breakpoint 1, main() at foo.c:4 
warning: Source file is more recent than executable. 
4   void *p = calloc(1, 10); 
(gdb) b __libc_calloc 
Breakpoint 2 at 0xf7e845a0 
(gdb) n 

Breakpoint 2, 0xf7e845a0 in calloc() from /lib32/libc.so.6 
(gdb) fin 
Run till exit from #0 0xf7e845a0 in calloc() from /lib32/libc.so.6 
0x0804843a in main() at foo.c:4 
4   void *p = calloc(1, 10); 

說明如何從程序calloc命中斷點#2呼叫。

(gdb) n 
5   return p == 0; 
(gdb) call calloc(1,32) 
$1 = 134524952 

注意,從上面的GDB調用沒有命中斷點#2。

讓我們再試一次:

(gdb) info func calloc 
All functions matching regular expression "calloc": 

Non-debugging symbols: 
0x08048310 [email protected] 
0xf7fdc820 [email protected] 
0xf7ff16a0 calloc 
0xf7e25450 [email protected] 
0xf7e845a0 __libc_calloc 
0xf7e845a0 calloc 

(gdb) info sym 0xf7ff16a0 
calloc in section .text of /lib/ld-linux.so.2 ## this is the wrong one! 

(gdb) break *0xf7ff16a0 
Breakpoint 3, 0xf7ff16a0 in calloc() from /lib/ld-linux.so.2 

(gdb) disable  
(gdb) start 
Temporary breakpoint 7 at 0x8048426: file foo.c, line 4. 
Starting program: /tmp/a.out 

Temporary breakpoint 7, main() at foo.c:4 
4   void *p = calloc(1, 10); 
(gdb) ena 3 
(gdb) n 
5   return p == 0; 

注意,斷點#3做上述火(因爲 「真正的」 __libc_calloc叫)。

(gdb) call calloc(1,32) 

Breakpoint 3, 0xf7ff16a0 in calloc() from /lib/ld-linux.so.2 
The program being debugged stopped while in a function called from GDB. 
Evaluation of the expression containing the function 
(calloc) will be abandoned. 
When the function is done executing, GDB will silently stop. 
(gdb) bt 
#0 0xf7ff16a0 in calloc() from /lib/ld-linux.so.2 
#1 <function called from gdb> 
#2 main() at foo.c:5 

QED。

更新:

我沒有看到 「信息FUNC釋放calloc」

的輸出LD-Linux版本,我認爲你在info func看取決於你是否安裝了調試符號。對於(64位)的glibc 調試符號,這裏是我所看到的:

(gdb) info func calloc 
All functions matching regular expression "calloc": 

File dl-minimal.c: 
void *calloc(size_t, size_t);   <<< this is the wrong one! 

File malloc.c: 
void *__libc_calloc(size_t, size_t); <<< this is the one you want! 

Non-debugging symbols: 
0x0000000000400440 [email protected] 
0x00007ffff7ddaab0 [email protected] 
0x00007ffff7a344e0 [email protected] 

這裏是另一種方式來弄清楚什麼calloc GDB認爲它應該叫:

(gdb) start 
Temporary breakpoint 1 at 0x8048426: file foo.c, line 4. 
Starting program: /tmp/a.out 

Temporary breakpoint 1, main() at foo.c:4 
warning: Source file is more recent than executable. 
4  void *p = calloc(1, 10); 
(gdb) p &calloc 
$1 = (<text variable, no debug info> *) 0xf7ff16a0 <calloc> 
(gdb) info sym 0xf7ff16a0 
calloc in section .text of /lib/ld-linux.so.2 

或者,爲了完整性,使用帶調試符號的64位glibc:

(gdb) start 
Temporary breakpoint 1 at 0x400555: file foo.c, line 4. 
Starting program: /tmp/a.out 

Temporary breakpoint 1, main() at foo.c:4 
4  void *p = calloc(1, 10); 
(gdb) p &calloc 
$1 = (void *(*)(size_t, size_t)) 0x7ffff7df1bc0 <calloc> 
(gdb) info sym 0x7ffff7df1bc0 
calloc in section .text of /lib64/ld-linux-x86-64.so.2 
+0

優秀的答案。他們說堆棧溢出的下降... – Dan

+0

雖然解釋是有道理的,我沒有在「info func calloc」的輸出中看到ld-linux版本。我已經嘗試在它所做的所有事情上列出斷點,但gdb內的調用仍然沒有觸及其中的任何一個。 – Dan

+0

@丹我更新了答案。 –

相關問題