为什么在gdb中调用calloc似乎没有将内存清零?

时间:2016-09-29 02:35:54

标签: c gdb

我正在做一些在运行过程中编辑进程内存的实验,我注意到当我在gdb'd进程中调用calloc时,调用似乎工作并返回原始传递的指针,但是内存似乎未初始化为0

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

但是,如果我在结果指针上调用memset,则初始化工作正常:

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

1 个答案:

答案 0 :(得分:8)

有趣的问题。答案是:在Linux上(我假设你运行你的程序):

calloc

不会从ld-linux.so.2致电calloc

而是从ld-linux.so.2调用memset。并且 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); 本身调用,它假定它可以访问的任何页面都是“干净”而do not requirecalloc。 (也就是说,我无法使用glibc-2.19重现不洁(gdb) n 5 return p == 0; (gdb) call calloc(1,32) $1 = 134524952

您可以这样确认:

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

Non-debugging symbols:
0x08048310  calloc@plt
0xf7fdc820  calloc@plt
0xf7ff16a0  calloc
0xf7e25450  calloc@plt
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;

注意从程序到__libc_calloc的调用如何命中断点#2。

(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

请注意,上面的GDB调用命中断点#2。

让我们再试一次:

info func

请注意,断点#3上面没有 ,因为调用了“真正的”(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 calloc@plt 0x00007ffff7ddaab0 calloc@plt 0x00007ffff7a344e0 calloc@plt

calloc

QED。

<强>更新

  

我没有在“info func calloc”

的输出中看到ld-linux版本

我认为您在(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

这是另一种方法,可以找出GDB认为它应该调用的std::list

std::list

或者,对于completness,使用64位glibc和调试符号:

std::list::iterator