У меня были некоторые проблемы с сервером сегодня, и теперь я откидывал его до того, что он не может избавиться от процессов, которые получают segfault.
После того, как процесс получает seg-fault, процесс просто держится, а не убивается.
Тест, который должен вызвать ошибку 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
.
Запуск этого (и нажатия на ввод 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)
[email protected] { ~ }# echo $?
139
Когда процесс зависает (после его устранения), это выглядит так.
Невозможно
[email protected] { ~ }# ./segfault
^C^C^C
Запись из ps aux
root 22944 0.0 0.0 69700 444 pts/18 S+ 15:39 0:00 ./segfault
cat/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
к висящему процессу segfault. Фактически это убивает.
[email protected] { ~ }# strace -p 1234
Process 1234 attached
+++ killed by SIGSEGV (core dumped) +++
ulimit -c 0
сидит и ulimit -c
, ulimit -H -c
, а ulimit -S -c
показывает значение 0
- Версия ядра:
3.10.0-229.14.1.el7.x86_64
- Distro-version:
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/segfault
00600000-00601000 r--p 00000000 fd:00 13143328 /root/segfault
00601000-00602000 rw-p 00001000 fd:00 13143328 /root/segfault
7f6c08000000-7f6c08021000 rw-p 00000000 00:00 0
7f6c08021000-7f6c0c000000 ---p 00000000 00:00 0
7f6c0fd5b000-7f6c0ff11000 r-xp 00000000 fd:00 14284 /usr/lib64/libc-2.17.so
7f6c0ff11000-7f6c10111000 ---p 001b6000 fd:00 14284 /usr/lib64/libc-2.17.so
7f6c10111000-7f6c10115000 r--p 001b6000 fd:00 14284 /usr/lib64/libc-2.17.so
7f6c10115000-7f6c10117000 rw-p 001ba000 fd:00 14284 /usr/lib64/libc-2.17.so
7f6c10117000-7f6c1011c000 rw-p 00000000 00:00 0
7f6c1011c000-7f6c1013d000 r-xp 00000000 fd:00 14274 /usr/lib64/ld-2.17.so
7f6c10330000-7f6c10333000 rw-p 00000000 00:00 0
7f6c1033b000-7f6c1033d000 rw-p 00000000 00:00 0
7f6c1033d000-7f6c1033e000 r--p 00021000 fd:00 14274 /usr/lib64/ld-2.17.so
7f6c1033e000-7f6c1033f000 rw-p 00022000 fd:00 14274 /usr/lib64/ld-2.17.so
7f6c1033f000-7f6c10340000 rw-p 00000000 00:00 0
7ffc13b5b000-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;}
), чтобы вызвать segfault, вызвал segfault и не зависал...