gpt4 book ai didi

c - 为什么在 gdb 中调用 calloc 似乎不会将内存归零?

转载 作者:行者123 更新时间:2023-12-04 12:35:08 25 4
gpt4 key购买 nike

我正在做一些实验,在它运行时编辑进程内存,我注意到当我在 gdb 进程中调用 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

最佳答案

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

(gdb) call calloc(1, 32)

不从 libc.so.6 调用 calloc

而是从 ld-linux.so.2 调用 calloc。并且 that calloc 非常少。它预计只能从 ld-linux.so.2 本身调用,并且假定它可以访问的任何页面都是“干净的”和 do not require 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 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;

请注意,断点#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。

更新:

I don't see the ld-linux version in the output of "info func calloc"

我认为您在 info func 中看到的内容取决于您是否安装了调试符号。对于(64 位)glibc with 调试符号,这是我看到的:

(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 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

关于c - 为什么在 gdb 中调用 calloc 似乎不会将内存归零?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39760479/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com