Blog

Segmentation fault + docker + gdb

Poniższy scenariusz zdarzył mi się dwukrotnie po podniesieniu wersji Symfony. Kontener z aplikacją kończył żywot z błędem „Segmentation fault”.
Oznacza to, że proces próbował odwołać się do pamięci, do której nie ma dostępu. To nie jest błąd logiczny, tylko coś poważniejszego – błąd na poziomie systemowym lub core – i jest trudny do zdiagnozowania.
Trudność polega na tym, że nie można go przechwycić wyjątkiem i sprawdzić backtrace.
Jeżeli nasza aplikacja dodatkowo jest uruchamiana z kontenera dockerowego, poziom trudności wzrasta.

Ten wpis jest notatką na przyszłość, jeżeli znowu zdarzy się podobna sytuacja. Założeniem tego posta jest korzystanie z linuxowego kontenera.
Do rozwiązania problemu użyj polecenia gdb.

gdb to skrót od GNU Debugger. Instrukcje instalacji znajdziesz w internecie.

Jeżeli Twój problem nie dotyczy runtime możesz zacząć od punktu trzeciego.

Po pierwsze dodaj go do systemu lub zainstaluj tymczasowo w Dockerfile i przebuduj kontener.
Po drugie skopiuj plik runtime.

cp index.php test.php
echo '<?php sleep(3600) > index.php'

Ma to na celu poprawne uruchomienie kontenera.
Po trzecie wejdź na kontener przy użyciu polecenia exec. Możesz też wykorzystać polecenie run.

gdb php test.php
// or standalone script
gdb php bin/console app:troubles

W gdb użyj poleceń:
  • bt (backtrace) wyświetla stos
  • list: pokazuje fragmenty kodu, wokół miejsca, gdzie wystąpił błąd 

Teraz wystarczy przejść do swojego ulubionego IDE i wstawić tuż przed tym miejscem breakpoint. Wiele wskazuje na to, że po ponownym uruchomieniu będziemy mieli jakiś ślad.
Na przykład wyjątek po przechwyceniu wyjątku.