问题描述
在 ubuntu 18.04 上,我编写了以下 c 程序并以 100 的输入运行它
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int x;
scanf("%d",&x);
usleep(1);
void *tmp = malloc(x);
usleep(1);
free(tmp);
return 0;
}
终端的输出是:(带strace)
strace ./a.out
execve("./a.out",["./a.out"],0x7ffd69236c10 /* 50 vars */) = 0
brk(NULL) = 0x55a719717000
access("/etc/ld.so.nohwcap",F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload",R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD,"/etc/ld.so.cache",O_RDONLY|O_CLOEXEC) = 3
fstat(3,{st_mode=S_IFREG|0644,st_size=96020,...}) = 0
mmap(NULL,96020,PROT_READ,MAP_PRIVATE,3,0) = 0x7f7acb879000
close(3) = 0
access("/etc/ld.so.nohwcap",F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD,"/lib/x86_64-linux-gnu/libc.so.6",O_RDONLY|O_CLOEXEC) = 3
read(3,"\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\35\2\0\0\0\0\0"...,832) = 832
fstat(3,{st_mode=S_IFREG|0755,st_size=2030928,8192,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x7f7acb877000
mmap(NULL,4131552,PROT_READ|PROT_EXEC,MAP_PRIVATE|MAP_DENYWRITE,0) = 0x7f7acb277000
mprotect(0x7f7acb45e000,2097152,PROT_NONE) = 0
mmap(0x7f7acb65e000,24576,MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE,0x1e7000) = 0x7f7acb65e000
mmap(0x7f7acb664000,15072,MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,0) = 0x7f7acb664000
close(3) = 0
arch_prctl(ARCH_SET_FS,0x7f7acb8784c0) = 0
mprotect(0x7f7acb65e000,16384,PROT_READ) = 0
mprotect(0x55a718d34000,4096,PROT_READ) = 0
mprotect(0x7f7acb891000,PROT_READ) = 0
munmap(0x7f7acb879000,96020) = 0
fstat(0,{st_mode=S_IFCHR|0620,st_rdev=makedev(136,0),...}) = 0
brk(NULL) = 0x55a719717000
brk(0x55a719738000) = 0x55a719738000
read(0,100
"100\n",1024) = 4
nanosleep({tv_sec=0,tv_nsec=1000},NULL) = 0
nanosleep({tv_sec=0,NULL) = 0
lseek(0,SEEK_CUR) = -1 ESPIPE (Illegal seek)
exit_group(0) = ?
+++ exited with 0 +++
这不是很奇怪吗?为什么 malloc 没有使用 brk
或 mmap
来分配内存(在 nanosleep()
的 2 次调用之间)。
这种奇怪行为的原因是什么?
如果我将输入更改为 200000,我会在两者之间看到对 mmap 的调用。
解决方法
这不奇怪吗?
没有
为什么 malloc 不使用 brk 或 mmap 来分配内存(在两次调用 nanosleep() 之间)。
场景 1:您启用了优化,并且优化器发现忽略对 malloc
的调用是不可观察的,因此它从未被调用过。
场景 2:调用了 malloc
,但在那时它大概不需要调用 brk
或 mmap
。 brk
和 mmap
之前都被调用过,可能是为了 malloc
。