我今天在服务器上遇到了一些问题,现在将其归结为它无法摆脱导致段错误的进程。进程出现段故障后,该进程将继续挂起,而不会被杀死。测试应该会导致错误Segmentation fault (core dumped)。#include <stdio.h>#include <stdlib.h>int main(int argc, char **argv){ char *buf; buf = malloc(1<<31); fgets(buf, 1024, stdin); printf("%s\n", buf); return 1;}使用gcc segfault.c -o segfault && chmod +x segfault编译和设置权限。在有问题的服务器上运行此命令(并按Enter 1次)会导致其挂起。我还在具有相同内核版本(和大多数相同软件包)的另一台服务器上运行了此命令,它得到了seg-fault然后退出。这是在两个服务器上都运行strace ./segfault之后的最后几行。 服务器错误"\n", 1024) = 1--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0} ---# It hangs here.... 工作服务器"\n", 1024) = 1--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0} ---+++ killed by SIGSEGV (core dumped) +++Segmentation fault (core dumped)root@server { ~ }# echo $?139当进程挂起(分段隔离后)时,它就是这样。 无法^ c它root@server { ~ }# ./segfault^C^C^C 来自ps aux 的条目root 22944 0.0 0.0 69700 444 pts/18 S+ 15:39 0:00 ./segfault 猫/proc/22944/stack [<ffffffff81223ca8>] do_coredump+0x978/0xb10[<ffffffff810850c7>] get_signal_to_deliver+0x1c7/0x6d0[<ffffffff81013407>] do_signal+0x57/0x6c0[<ffffffff81013ad9>] do_notify_resume+0x69/0xb0[<ffffffff8160bbfc>] retint_signal+0x48/0x8c[<ffffffffffffffff>] 0xffffffffffffffff另一个有趣的事情是,我无法将strace附加到悬挂的段故障处理过程中。这样做实际上会使它被杀死。root@server { ~ }# strace -p 1234Process 1234 attached+++ killed by SIGSEGV (core dumped) +++ulimit -c 0是sat,ulimit -c,ulimit -H -c和ulimit -S -c都显示值0内核版本:3.10.0-229.14.1.el7.x86_64 发行版:Red Hat Enterprise Linux Server release 7.1 (Maipo) 在vmware中运行服务器正在其他所有设备上正常工作。 更新关闭abrt(systemctl stop abrtd.service)解决了核心转储后已经挂起的进程以及新进程核心转储的问题。再次启动abrt并没有带来问题。 更新2016-01-26 我们遇到了一个看起来相似但不完全相同的问题。用于测试的初始代码:#include <stdio.h>#include <stdlib.h>int main(int argc, char **argv){ char *buf; buf = malloc(1<<31); fgets(buf, 1024, stdin); printf("%s\n", buf); return 1;}挂了。 cat /proc/<pid>/maps的输出是00400000-00401000 r-xp 00000000 fd:00 13143328 /root/segfault00600000-00601000 r--p 00000000 fd:00 13143328 /root/segfault00601000-00602000 rw-p 00001000 fd:00 13143328 /root/segfault7f6c08000000-7f6c08021000 rw-p 00000000 00:00 07f6c08021000-7f6c0c000000 ---p 00000000 00:00 07f6c0fd5b000-7f6c0ff11000 r-xp 00000000 fd:00 14284 /usr/lib64/libc-2.17.so7f6c0ff11000-7f6c10111000 ---p 001b6000 fd:00 14284 /usr/lib64/libc-2.17.so7f6c10111000-7f6c10115000 r--p 001b6000 fd:00 14284 /usr/lib64/libc-2.17.so7f6c10115000-7f6c10117000 rw-p 001ba000 fd:00 14284 /usr/lib64/libc-2.17.so7f6c10117000-7f6c1011c000 rw-p 00000000 00:00 07f6c1011c000-7f6c1013d000 r-xp 00000000 fd:00 14274 /usr/lib64/ld-2.17.so7f6c10330000-7f6c10333000 rw-p 00000000 00:00 07f6c1033b000-7f6c1033d000 rw-p 00000000 00:00 07f6c1033d000-7f6c1033e000 r--p 00021000 fd:00 14274 /usr/lib64/ld-2.17.so7f6c1033e000-7f6c1033f000 rw-p 00022000 fd:00 14274 /usr/lib64/ld-2.17.so7f6c1033f000-7f6c10340000 rw-p 00000000 00:00 07ffc13b5b000-7ffc13b7c000 rw-p 00000000 00:00 0 [stack]7ffc13bad000-7ffc13baf000 r-xp 00000000 00:00 0 [vdso]ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]但是,较小的C代码(int main(void){*(volatile char*)0=0;})触发段错误确实导致段错误并且没有挂起... 最佳答案 警告-此答案包含一些基于不完整信息的假设。希望它仍然有用!为什么段错误似乎挂起?如堆栈跟踪所示,内核正忙于创建崩溃进程的核心转储。但是,为什么要花这么长时间?可能的解释是,您用于创建段的方法导致该进程具有大量的虚拟地址空间。正如MM的评论所指出的那样,C标准未定义表达式1 请注意,要使malloc成功,您实际上不必在系统中拥有这么多的RAM-内核将扩展进程的虚拟大小,但仅在程序实际访问此RAM时才分配实际的RAM。我相信对malloc的调用成功,或者至少返回了,因为您声明在按回车键之后,即在对fgets调用之后,它会出现段错误。无论如何,segfault都会导致内核执行核心转储。如果该进程具有较大的虚拟大小,则可能要花费很长时间,尤其是如果内核决定转储所有页面,甚至那些从未被该进程触及的页面时,尤其如此。我不确定是否会这样做,但是如果这样做,并且系统中没有足够的RAM,则必须开始将页面换入和换出内存才能将其转储到核心转储中。这将产生很高的IO负载,这可能导致该进程似乎没有响应(并且整个系统性能会下降)。您可以通过在abrtd转储目录(可能是/var/tmp/abrt或check /etc/abrt/abrt.conf)中查找来验证其中的某些内容,在该目录中您可以找到已创建的核心转储(或部分核心转储)。如果您能够重现该行为,则可以检查: /proc/[pid]/maps查看进程的地址空间映射,并查看它是否真的很大使用vmstat之类的工具来查看系统是否正在交换,正在进行的I/O数量以及正在经历多少IO等待状态如果正在运行sar,那么即使在重新启动abrtd之前的一段时间内,您也可能会看到类似的信息。 为什么即使ulimit -c为0,也要创建核心转储?根据this bug report,无论ulimit设置如何,abrtd都会触发核心转储的收集。为什么在再次启动arbtd时又没有再次发生这种情况?有两种可能的解释。一方面,这取决于系统中的可用RAM数量。如果有足够的可用RAM并且不插入系统进行交换,则大型进程的单个核心转储可能不会花费那么长时间,也不会被视为挂起。如果在最初的实验中您处于这种状态下有多个过程,那么症状将比仅使单个过程不当行为时的情况严重得多。另一个可能性是abrtd的配置已更改,但服务尚未重新加载,因此,当您重新启动它时,它开始使用新配置,也许会更改其行为。yum更新也可能已经更新了abrtd,但没有重新启动,因此,当您重新启动它时,新版本正在运行。关于c++ - 段错误本身正在挂起,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33673592/
10-12 21:41