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.
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.
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.
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.
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.