【发布时间】:2021-09-02 15:58:13
【问题描述】:
我在最近的工作面试中遇到了多个简单的问题。
起初,我被要求编写一个简单的程序,从用户那里获取输入 x 并在内存中分配(使用 malloc)x 个字节。
我只是写了:
void main()
{
int x;
scanf("%d",&x);
malloc(x);
}
然后我被告知要显示在运行我的可执行文件时调用的所有系统调用,所以我去了终端并输入:
strace ./my_program.o
这很好,直到他问了这样的问题:
在程序上运行 strace 得到的输出是 可能很乱。而且没有办法知道哪个系统调用是 在 malloc 执行期间使用。你能建议一个简单的补充吗 到您的 C 代码,这样您就可以发现系统调用 无论如何在执行 malloc 期间使用。顺便说一句,你不允许 将标志添加到 strace 并且您的更改必须在 C 代码中进行。
我在这里失去了他。可以对 C 代码进行哪些补充?
您的建议的输出示例(仍然没有帮助,因为奇怪的原因只有一次写入,而不是 2,因为我将 C 代码更改为在 malloc 之前有一个,而在 malloc 之后有一个)
execve("./a.out", ["./a.out"], 0x7ffc38701620 /* 50 vars */) = 0
brk(NULL) = 0x55df6cc1b000
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) = 0x7fb9d4900000
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, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb9d48fe000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fb9d42fe000
mprotect(0x7fb9d44e5000, 2097152, PROT_NONE) = 0
mmap(0x7fb9d46e5000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7fb9d46e5000
mmap(0x7fb9d46eb000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fb9d46eb000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7fb9d48ff500) = 0
mprotect(0x7fb9d46e5000, 16384, PROT_READ) = 0
mprotect(0x55df6b542000, 4096, PROT_READ) = 0
mprotect(0x7fb9d4918000, 4096, PROT_READ) = 0
munmap(0x7fb9d4900000, 96020) = 0
fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
brk(NULL) = 0x55df6cc1b000
brk(0x55df6cc3c000) = 0x55df6cc3c000
read(0,
"\n", 1024) = 1
read(0, 5
"5\n", 1024) = 2
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
write(1, "__________________________", 26__________________________) = 26
lseek(0, -1, SEEK_CUR) = -1 ESPIPE (Illegal seek)
exit_group(0) = ?
+++ exited with 0 +++
【问题讨论】:
-
在对
malloc()的调用周围添加一些printf()(或类似的东西),这样strace 日志就会被它们夹在中间。 -
@Frank 但 printf 将有多个系统调用,这会导致更多的混乱,因为我相信,我想调用一些虚拟系统调用(如果有这样的系统调用)只是为了让事情像我一样清楚(0 ) 之前和之后,但如果例如 malloc 也使用它们,那也无济于事
-
@Frank 尝试了你的建议,但仍然没有帮助我发现代码,因为它们是在一次写入中组合在一起的
-
所有使用
void main()的人都注定要失败。 -
@wildplasser 为什么它有什么问题?
标签: c linux malloc system-calls strace