我正在使用 strace 命令运行可执行文件(c 程序)并得到以下输出。请帮我看看为什么它在访问时出错并且整个过程最后都被终止了?
请告诉我这背后的潜在原因是什么。
答案1
您的程序调用了brk(2)
如此多的次数 (8843),这让我认为您的代码向系统请求了太多内存。通常在 Linux 上,当程序请求了太多内存时,它会被终止SIGKILL
。
更多细节
brk(2)
是程序请求内存的两种方式之一。另一种方式是mmap(2)
。GNU malloc(3)
C 库提供的和相关实现混合使用了这两种方式。
一般来说,无论你的程序以何种方式分配内存,Linux 都不会抱怨。即使没有可用的内存,内核仍有可能返回有效的地址。
这是因为 Linux 分配内存懒洋洋,即直到您开始使用内存时,内存才被“物理分配”。这是一项很棒的性能优化。
现在,当您尝试使用一些内存,但系统的 RAM 和交换空间已满时,会发生什么情况?如果 Linux 已物理分配了您的内存,则不会出现问题。否则,名为OOM 杀手开始终止消耗大部分内存的进程,以保持系统可用。
关于访问
您注意到strace -c
报告了 4 次access(2)
失败。这肯定不是问题的征兆。系统调用失败是完全正常的。当您的程序不处理失败时,就会出现问题。
一个例子:
$ strace -e trace=stat -- ls /abc
stat("/abc", 0x1df2e30) = -1 ENOENT (No such file or directory)
ls: cannot access /abc: No such file or directory
+++ exited with 2 +++
我已告知ls
列出不存在的目录的内容 ( /abc
),因此对 的调用stat(2)
失败并显示ENOENT
。这本身不是问题ls
:它已检测到失败并显示错误消息。
ls
如果不检查的返回值,就会出现问题stat(2)
。
关于您的具体问题:很难知道访问失败的原因。strace -e trace=access
或 的输出strace -C
会给你一些提示。 然而我坚信这样的失败对你来说不是问题,因为它们可能来自 GNU C 库:
$ strace -e trace=access -- ls
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)
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
...