Php debugging - Segmentation fault error

 

Recent is Debian 10 uitgekomen en hoewel het niet verstandig is enkele dagen na een release een server-upgrade te doen, ging ik toch de uitdaging aan. De kans is namelijk groot dat je een van de eerste bent die tegen bugs aan loopt.

Na de installatie van Debian liep ik ook direct tegen issues aan. Zo startte MySQL-Server niet, omdat de standaard apparmor instellingen niet juist waren. Hoewel ik niet bekend ben met apparmor - had er zelfs tot toen nooit van gehoord - maar wel met SE Linux, was dit varkentje gelukkig snel gewassen door een aantal regels toe te voegen aan de configuratie in /etc/apparmor.d/usr.sbin.mysqld.

Een vervelender issue was een Php-script dat crashte. Het betrof een script dat vanaf de command-line wordt gestart en permanent een mailbox in de gaten houdt. Php-bugs an sich zijn in de regel erg snel op te lossen middels xdebug. Het wordt lastiger als de Php-runtime crasht en alleen de volgende foutmelding verschijnt,

    Segmentation fault.


Na een beetje Google'en kwam ik op een pagina terecht met een korte tutorial van de GNU Debugger. Door Php te starten in gnu debugger - gdb - is het mogelijk na de crash een backtrace op te vragen. In deze backtrace kan gezien worden welke statements voor de crash plaats vonden en welke API-call de crash veroorzaakte.

In de stacktrace - hieronder getoond - is te zien dat er calls vanuit de de Php-extensie phar.so worden uitgevoerd en het een aantal stappen verder crasht op de _emalloc()-call. Het eerste idee was om dus de phar-extensie te disablen. Na dit gedaan te hebben leek het even goed te gaan, maar crashte het op een later moment toch weer.


$ gdb php
GNU gdb (Debian 8.2.1-2) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
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:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from php...(no debugging symbols found)...done.
(gdb) run ./bin/webmail_connector.php itxplain
Starting program: /usr/bin/php ./bin/webmail_connector.php itxplain
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Starting monitor for: ......@itxplain.nl
Check it!
Saving e-mail to file: /.........../email/inbox/2019/07/16/14487e263190858d2062a4a1b987ea31
Applying filters
[Detaching after fork from child process 18281]
Importing mail, 1: Re: dit is een testbericht (Tue, 16 Jul 2019 14:14:03 +0000)

Program received signal SIGSEGV, Segmentation fault.
0x00005555557d664d in _emalloc ()
(gdb) bt
#0  0x00005555557d664d in _emalloc ()
#1  0x00005555557c804a in lex_scan ()
#2  0x00005555557db9ea in ?? ()
#3  0x00005555557c129e in zendparse ()
#4  0x00005555557c37aa in ?? ()
#5  0x00005555557c4f9a in compile_file ()
#6  0x00007ffff23f67a2 in ?? () from /usr/lib/php/20180731/phar.so
#7  0x000055555583eb65 in ?? ()
#8  0x000055555587586a in ?? ()
#9  0x000055555587a53d in execute_ex ()
#10 0x00005555557ed12e in zend_call_function ()
#11 0x00005555556f45cc in ?? ()
#12 0x00005555557ecfe8 in zend_call_function ()
#13 0x00005555557ed4be in zend_lookup_class_ex ()
#14 0x00005555558106d1 in ?? ()
#15 0x000055555587ff41 in execute_ex ()
#16 0x00005555557ed12e in zend_call_function ()
#17 0x000055555572f5a2 in ?? ()
#18 0x0000555555880d99 in execute_ex ()
#19 0x0000555555882087 in zend_execute ()
#20 0x00005555557fb053 in zend_execute_scripts ()
#21 0x000055555579bc08 in php_execute_script ()
#22 0x00005555558845ee in ?? ()
#23 0x000055555566196f in ?? ()
#24 0x00007ffff744309b in __libc_start_main (main=0x5555556614e0, argc=3, argv=0x7fffffffdee8, init=, fini=, 
    rtld_fini=, stack_end=0x7fffffffded8) at ../csu/libc-start.c:308
#25 0x0000555555661a6a in _start ()
(gdb) quit
A debugging session is active.

        Inferior 1 [process 18273] will be killed.

Quit anyway? (y or n) y
$ 


Met iets meer Google'n kwam ik op
stackoverflow uit. Middels xdebug is het mogelijk een trace-output te genereren dat continu bijhoudt welke functie-calls er worden aangeroepen op welk tijdstip + het geheugengebruik. Het commando hiervoor is,

     php -d xdebug.auto_trace=ON -d xdebug.trace_output_dir=mytracedir/ script.php

Uiteraard moet de xdebug-plugin hiervoor geïnstalleerd zijn. Bij het nalopen van de gegenereerde stacktrace viel mij op dat het script op een willekeurige functie-call crashte - strpos(). Toen ik echter naar het geheugengebruik keek zag ik dat dit overeen kwam met de ingestelde memory_limit. Op deze manier werd het dus duidelijk dat er een memory-leak in het script zit, waarschijnlijk door een bug in een Php-module.

Dit wetende kon er weer in de Php-code worden gedoken en gekeken worden waarom dit betreffende script crashte. De focus was op de Php-modules dat enkel door dit script werd gebruikt, andere scripts crashte namelijk niet. Het unieke van dit script was dat 'php-mailparse' werd gebruikt. Via pecl kon een nieuwe/andere versie van de mailparse.so-module worden gecompileerd en geinstalleerd. Hierna draaide het script weer als een zonnetje.


Zit u nu ook met een Php probleem? Of bent u opzoek naar een freelance Php programmeur voor issues? Neem dan contact op!



- Bent u opzoek naar een Php of Java programmeur voor uw website of applicatie? (freelance / detachering)
- Losse tickets, opdrachten, of gehele projecten in de planning?

Dan kom ik graag met u in contact! Meer informatie over mij vindt u hier.
Sitemap | Op alle producten & diensten zijn de algemene voorwaarden van toepassing