有趣的問題。答案是:在Linux(在這裏我假設你跑你的程序)這樣的:
(gdb) call calloc(1, 32)
不會libc.so.6
調用calloc
。
寧可叫calloc
從ld-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
優秀的答案。他們說堆棧溢出的下降... – Dan
雖然解釋是有道理的,我沒有在「info func calloc」的輸出中看到ld-linux版本。我已經嘗試在它所做的所有事情上列出斷點,但gdb內的調用仍然沒有觸及其中的任何一個。 – Dan
@丹我更新了答案。 –