Felsökning av Apache Segmentation Fault

"[core:notice] [pid 30552:tid AH00052: child pid 13416 exit signal Segmentation fault (11)" betyder dåliga nyheter. Så här kan man göra för att försöka hitta källan till problemet.

Kraschade Apache-processer kan bete sig på flera sätt. Ibland tar de mycket minne, men ibland dör de bara och slutar svara på inkommande anrop. När alla Apache-processer hamnat i det läget slutar servern svara på anrop och webbplatsen blir otillgänglig. Om du kollar cpu-användningen på servern och ser att den är nästan overksam har du förmodligen fått en hängning i Apache. En annan vanlig orsak till hängningar är utgående anrop från PHP, men det kommer bli ett annat blogginlägg.

Den vanligaste åtgärden är att starta om Apache-tjänsten, och allting kommer förmodligen börja fungera igen. På Cloudnet anser vi inte att vi därmed löst problemet, eftersom det inte finns någon anledning till att det händer i en välskriven webbapplikation på en rätt konfigurerad server.

De hänga processerna avslöjar sig i Apaches error-log när man startar om tjänsten. Så här kan det ser ut:
[Tue Aug 15 15:01:42.671469 2017] c0000.cloudnet.se [core:notice] [pid 4589:tid AH00052: child pid 5782 exit signal Segmentation fault (11)
[Tue Aug 15 15:01:53.691438 2017] c0000.cloudnet.se [core:notice] [pid 4589:tid AH00052: child pid 6016 exit signal Segmentation fault (11)
[Tue Aug 15 15:01:56.694414 2017] c0000.cloudnet.se [core:notice] [pid 4589:tid AH00052: child pid 6124 exit signal Segmentation fault (11)
[Tue Aug 15 15:01:57.695543 2017] c0000.cloudnet.se [core:notice] [pid 4589:tid AH00052: child pid 6036 exit signal Segmentation fault (11)
[Tue Aug 15 15:02:06.737529 2017] c0000.cloudnet.se [core:notice] [pid 4589:tid AH00052: child pid 6035 exit signal Segmentation fault (11)
[Tue Aug 15 15:02:20.754995 2017] c0000.cloudnet.se [core:notice] [pid 4589:tid AH00052: child pid 6126 exit signal Segmentation fault (11)
[Tue Aug 15 15:02:25.759932 2017] c0000.cloudnet.se [core:notice] [pid 4589:tid AH00052: child pid 6034 exit signal Segmentation fault (11)
[Tue Aug 15 15:02:51.786406 2017] c0000.cloudnet.se [core:notice] [pid 4589:tid AH00052: child pid 6160 exit signal Segmentation fault (11)
[Tue Aug 15 15:03:00.796517 2017] c0000.cloudnet.se [core:notice] [pid 4589:tid AH00052: child pid 6292 exit signal Segmentation fault (11)

Börja med att aktivera coredumps i Apache så den sparar information om kraschen.

Lägg till följande i Apache-konfigurationen
CoreDumpDirectory /tmp/coredump

Skapa mappen och sätt rätt rättigheter
mkdir /tmp/coredump
chmod 777 /tmp/coredump
chown www-data:www-data /tmp/coredump

Ställ in sökväg och filnamn i kerneln
echo '/tmp/coredump/core-%e.%p' > /proc/sys/kernel/core_pattern

Aktivera coredump med ulimit och kolla att det slagit igenom
#ulimit -c unlimited
# ulimit -a|grep core
core file size (blocks, -c) unlimited

Starta om Apache och kolla så den tillåts köra coredump
# service apache2 restart
# cat /proc/$(pidof -s apache2)/limits|grep -e Limit -e core
Limit Soft Limit Hard Limit Units
Max core file size unlimited unlimited bytes

Testa att trigga en coredump
# kill -3 `pidof -s apache2`
# grep coredump /var/log/apache2/error.log
[Fri Aug 18 11:56:31.716861 2017] c0000.cloudnet.se [core:notice] [pid 27312:tid AH00051: child pid 28120 exit signal Quit (3), possible coredump in /tmp/coredump
# ls -al /tmp/coredump
total 955408
drwxrwxrwx 2 www-data www-data 4096 Aug 18 11:56 .
drwxrwxrwt 9 root root 4096 Aug 18 11:58 ..
-rw------- 1 www-data www-data 300879872 Aug 18 11:56 core-apache2.28120

Nu har vi allt som behövs så det är bara att vänta på att det kommer en äkta dumpfil i mappen. När den kommit så kör vi gdb på den:

# gdb /usr/sbin/apache2 /tmp/coredump/core-apache2.21660
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/sbin/apache2...(no debugging symbols found)...done.
[New LWP 21660]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `/usr/sbin/apache2 -k start'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007fca76e571b0 in gc_remove_zval_from_buffer () from /usr/lib/apache2/modules/libphp5.so
(gdb)

Här ser vi att kraschen orsakades av funktionen gc_remove_zval_from_buffer i libphp5.so som är PHP-tolken som är laddad som en modul i Apache. Att det är PHP som orsakat en kraschen vid garbage collection är ganska vanligt. Ibland går det att se mer genom att göra en backtrace i gdb:

(gdb) bt
#0 0x00007fca76e571b0 in gc_remove_zval_from_buffer () from /usr/lib/apache2/modules/libphp5.so
#1 0x00007fca76e28a28 in _zval_ptr_dtor () from /usr/lib/apache2/modules/libphp5.so
#2 0x00007fca76e46118 in zend_hash_destroy () from /usr/lib/apache2/modules/libphp5.so
#3 0x00007fca76e2dbc5 in destroy_op_array () from /usr/lib/apache2/modules/libphp5.so
#4 0x00007fca76e57f97 in ?? () from /usr/lib/apache2/modules/libphp5.so
#5 0x00007fca76e60487 in zend_objects_store_free_object_storage () from /usr/lib/apache2/modules/libphp5.so
#6 0x00007fca76e29123 in shutdown_executor () from /usr/lib/apache2/modules/libphp5.so
#7 0x00007fca76e38502 in zend_deactivate () from /usr/lib/apache2/modules/libphp5.so
#8 0x00007fca76dd92bd in php_request_shutdown () from /usr/lib/apache2/modules/libphp5.so
#9 0x00007fca76ee987f in ?? () from /usr/lib/apache2/modules/libphp5.so
#10 0x000056141b2f1100 in ap_run_handler ()
#11 0x000056141b2f1649 in ap_invoke_handler ()
#12 0x000056141b3066dc in ap_internal_redirect ()
#13 0x00007fca74fdfcfc in ?? () from /usr/lib/apache2/modules/mod_rewrite.so
#14 0x000056141b2f1100 in ap_run_handler ()
#15 0x000056141b2f1649 in ap_invoke_handler ()
#16 0x000056141b306c1a in ap_process_async_request ()
#17 0x000056141b306ef4 in ap_process_request ()
#18 0x000056141b303992 in ?? ()
#19 0x000056141b2fa770 in ap_run_process_connection ()
#20 0x00007fca77809767 in ?? () from /usr/lib/apache2/modules/mod_mpm_prefork.so
#21 0x00007fca778099a6 in ?? () from /usr/lib/apache2/modules/mod_mpm_prefork.so
#22 0x00007fca7780a0f9 in ?? () from /usr/lib/apache2/modules/mod_mpm_prefork.so
#23 0x000056141b2d628e in ap_run_mpm ()
#24 0x000056141b2cf2e6 in main ()

Ibland går det att gissa vad som kan vara orsak och ibland är det bara att sätta igång och googla. I det här fallet kommer vi göra en uppgradering av Ubuntu så det blir ny PHP-version som förhoppningsvis inte innehåller samma bugg.