Wprowadzenie do GDB:
GDB to potężne narzędzie do debugowania programów UNIX, wydane przez GNU Open Source Organization. Jeśli pracujesz na platformie UNIX, przekonasz się, że GDB to narzędzie do debugowania, które oferuje potężniejsze funkcje niż graficzne debugery VC i BCB.
problem
Środowisko: Linux/PHP v5.5.7
Gdy telefon komórkowy wchodzi do tła tej strony, kliknij na kilka stron, a pojawi się błąd 502 i chcesz dowiedzieć się, jaka jest jego konkretna przyczyna.
Lognik błędów php-fpm wygląda następująco:
WARNING: [pool www] child 11274 exited on signal 11 (SIGSEGV) after 0.089068 seconds from start
Plik rdzeniowy
Plik rdzeniowy to w rzeczywistości obraz pamięci, który przechowuje odpowiednie informacje o pamięci w momencie awarii programu i służy głównie do debugowania programu. Gdy program się zawiesza, generowany jest plik rdzeniowy, w rzeczywistości należy powiedzieć, że jest to plik zrzutu rdzenia, domyślna lokalizacja generowania znajduje się w tym samym katalogu co program wykonywalny, a nazwa pliku to core.***, gdzie *** to określona liczba.
Polecenie:
Rozmiar pliku rdzeniowego (bloki, -c) 0 Rozmiar danych (kB, -D) Nieograniczony Priorytet planowania (-e) 0 Rozmiar pliku (bloki, -f) nieograniczony Sygnały oczekujące (-i) 7271 Maksymalna pamięć zablokowana (Kbyte, -L) 64 Maksymalny rozmiar pamięci (kByte, -m) Nieograniczony Open Files (-n) 65535 Rozmiar rury (512 bajtów, -p) 8 Kolejki wiadomości POSIX (bajty, -q) 819200 priorytet czasu rzeczywistego (-r) 0 Rozmiar stosu (kbajtów, -s) 8192 Czas CPU (sekundy, -t) nieograniczony Max User Processes (-u) 7271 Pamięć wirtualna (kbajtów, -v) Nieograniczona Blokady plików (-x) Unlimited Jeśli rozmiar pliku core wynosi 0, pliku core nie może zostać wygenerowany i musimy go ustawić.
ULIMIT -C Unlimited, oznacza, że rozmiar pliku rdzeniowego jest nieograniczony
Przygotowanie zakończone, pamiętajZrestartuj usługę php-fpm, polecenie brzmi następująco:
Sprawdź ponownie log błędów, w następujący sposób:
[23-maj-2020 14:39:14] UWAGA: [pool www] dziecko 2220 wyjechało na sygnalizacji 11 (SIGSEGV - zrzut rdzenia) po 7.255225 sekundach od startu [23-maj-2020 14:39:14] UWAGA: [pool www] dziecko 2231 rozpoczęte Jeśli log zawiera słowa "SIGSEGV – core dumped", oznacza to, że plik rore został pomyślnie wygenerowany.
Plik rdzeniowy zostanie wygenerowany w katalogu strony internetowej, jeśli nie wiesz, możesz też znaleźć plik główny za pomocą następującego polecenia:
Adres generowany przez rdzeń mojego serwera to: /alidata/www/itsvse_web/core.2220
Instalacja gdb
Polecenie brzmi następująco:
GDB Debug PHP-FPM
Przygotuj plik .gdbinit
Plik .gdbinit znajduje się pod kodem źródłowym PHP i musi być spójny z wersją PHP, którą używasz!
Mój adres pliku: /root/sh-1.5.5/php-5.5.7/.gdbinit
Adres pobrania najnowszej wersji PHP pliku .gdbinit:
Logowanie do linku jest widoczne.
gdb, aby otworzyć plik core
W katalogu plików core wykonaj następujące polecenie:
[root@o itsvse_web]# gdb php-fpm -c core.2220 GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-119.el7 Copyright (C) 2013 Free Software Foundation, Inc. Licencja GPLv3+: GNU GPL wersja 3 lub nowsza <Logowanie do linku jest widoczne. To jest wolne oprogramowanie: możesz je zmieniać i rozpowszechniać. NIE MA GWARANCJI, na ile pozwala prawo. Wpisz "pokazuj kopiowanie" oraz "pokaż gwarancję" dla szczegółów. Ten GDB był skonfigurowany jako "x86_64-redhat-linux-gnu". Aby uzyskać instrukcje zgłaszania błędów, zobacz: <Logowanie do linku jest widoczne. Odczyt symboli z /alidata/server/php-5.5.7/sbin/php-fpm... Załatwione. [Nowy LWP 2220] [Debugowanie wątków przy użyciu libthread_db włączone] Używając biblioteki host libthread_db "/lib64/libthread_db.so.1". Core został wygenerowany przez 'php-fpm: pool www'. Program zakończony sygnałem 11, Błąd segmentacji. #0 tsrm_realpath_r ( path=path@entry=0x7ffdd9ebf100 "/alidata/www/itsvse_web/./source/language/mobile/lang_template.php", start=start@entry=1, len=66, ll=ll@entry=0x7ffdd9ebf0f4, t=t@entry=0x7ffdd9ebf0f8, use_realpath=use_realpath@entry=2, is_dir=is_dir@entry=0, link_is_dir=link_is_dir@entry=0x0) na /root/sh-1.5.5/php-5.5.7/TSRM/tsrm_virtual_cwd.c:751 751 { Brakuje osobnych informacji debugowych, użyj: debuginfo-install cyrus-sasl-lib-2.1.26-23.el7.x86_64 glibc-2.17-307.el7.1.x86_64 keyutils-libs-1.5.8-3.el7.x86_64 Krb5-libs-1.15.1-46.el7.x86_64 libcom_err-1.42.9-17.el7.x86_64 libcurl-7.29.0-57.el7.x86_64 libgcc-4.8.5-39.el7.x86_64 libidn-1.28-4.el7.x86_64 libselinux-2.5-15.el7.x86_ 64 libssh2-1.8.0-3.el7.x86_64 libstdc++-4.8.5-39.el7.x86_64 libxml2-2.9.1-6.el7.4.x86_64 NSPR-4.21.0-1.el7.x86_64 NSS-3.44.0-7.el7_7.x86_64 NSS-softokn-freebl-3.44.0-8.el7_ 7.x86_64 nss-util-3.44.0-4.el7_7.x86_64 OpenLDAP-2.4.44-21.el7_6.x86_64 Openssl-libs-1.0.2k-19.el7.x86_64 PCRE-8.32-17.el7.x86_64 XZ-libs-5.2.2-1.el7.x86_64 zlib-1.2.7-18.el7.x86_64 Można zobaczyć coś w rodzaju następujących słów:
Core został wygenerowany przez 'php-fpm: pool www'. Program zakończony sygnałem 11, Błąd segmentacji. bt(backtrace): Lista stosu wywołań
(GDB) BT #0 tsrm_realpath_r ( path=path@entry=0x7ffdd9ebf100 "/alidata/www/itsvse_web/./source/language/mobile/lang_template.php", start=start@entry=1, len=66, ll=ll@entry=0x7ffdd9ebf0f4, t=t@entry=0x7ffdd9ebf0f8, use_realpath=use_realpath@entry=2, is_dir=is_dir@entry=0, link_is_dir=link_is_dir@entry=0x0) na /root/sh-1.5.5/php-5.5.7/TSRM/tsrm_virtual_cwd.c:751 #1 0x000000000075209a w virtual_file_ex (stan=state@entry=0x7ffdd9ec0140, path=path@entry=0xed3a4d8 "/alidata/www/itsvse_web/./source/language/mobile/lang_template.php", verify_path=verify_path@entry=0x0, use_realpath=use_realpath@entry=2) na /root/sh-1.5.5/php-5.5.7/TSRM/tsrm_virtual_cwd.c:1292 #2 0x000000000075308c w tsrm_realpath ( path=path@entry=0xed3a4d8 "/alidata/www/itsvse_web/./source/language/mobile/lang_template.php", real_path=real_path@entry=0x7ffdd9ec1250 "vse_web/./source/plugin/dsu_amupper/pper.class.p\300\023\354\331\375\177") na /root/sh-1.5.5/php-5.5.7/TSRM/tsrm_virtual_cwd.c :1954
Sprawdź wątek wyjścia
Przedstawiamy .gdbinit (skrypty poleceń gdb) udostępnione w kodzie źródłowym PHP
Spójrz na zbacktrace i wartości zmiennych
(gdb) zbacktrace [0xed9f8f0] lang() /alidata/www/itsvse_web/source/function/function_core.php:444 [0xed9e2e8] lang("core", "title_board_message") /alidata/www/itsvse_web/source/function/function_message.php:43 [0xed9a988] dshowmessage("mobile_template_no_found", "", array(1)[0xec46a28], array(0)[0xec46bc0], 0) /alidata/www/itsvse_web/source/function/function_core.php:1426 [0xed9a6d8] showmessage("mobile_template_no_found", "", array(1)[0xec46a28]) /alidata/www/itsvse_web/source/function/function_core.php:618 [0xed97638] szablon("dsu_amupper:pper_foot") /alidata/www/itsvse_web/source/plugin/dsu_amupper/pper.class.php:82 [0x7ffdd9ec3e50] plugin_dsu_amupper->global_footer(array(0)[0xec40028]) [0xed97080] call_user_func(array(2)[0xed6b8b0], array(0)[0xec40028]) /alidata/www/itsvse_web/source/function/function_core.php:1177 [0xed954b8] hookscript("globalny", "globalny") /alidata/www/itsvse_web/source/function/function_core.php:1214 [0xed95218] hookscriptoutput("showmessage") /alidata/www/itsvse_web/data/template/8_8_touch_common_showmessage.tpl.php:1 [0xed949e8] ??? /alidata/www/itsvse_web/source/function/function_message.php:237 [0xed91088] dshowmessage("mobile_template_no_found", "", array(1)[0xec40c10], array(0)[0xec76d40], 0) /alidata/www/itsvse_web/source/function/function_core.php:1426 [0xed90dd8] showmessage("mobile_template_no_found", "", array(1)[0xec40c10]) /alidata/www/itsvse_web/source/function/function_core.php:618 [0xed8dd38] szablon("dsu_amupper:pper_foot") /alidata/www/itsvse_web/source/plugin/dsu_amupper/pper.class.php:82 [0x7ffdd9ec49a0] plugin_dsu_amupper->global_footer(array(0)[0xec39ab0]) [0xed8d780] call_user_func(array(2)[0xeb833e8], array(0)[0xec39ab0]) /alidata/www/itsvse_web/source/function/function_core.php:1177 [0xed8bbb8] hookscript("globalny", "globalny") /alidata/www/itsvse_web/source/function/function_core.php:1214 [0xed8b918] hookscriptoutput("showmessage") /alidata/www/itsvse_web/data/template/8_8_touch_common_showmessage.tpl.php:1 [0xed8b0e8] ??? /alidata/www/itsvse_web/source/function/function_message.php:237 [0xed651b0] dshowmessage("mobile_template_no_found", "", array(1)[0xecc0fe0], array(0)[0xec76718], 0) /alidata/www/itsvse_web/source/function/function_core.php:1426 [0xed64f00] showmessage("mobile_template_no_found", "", array(1)[0xecc0fe0]) /alidata/www/itsvse_web/source/function/function_core.php:618 [0xed61e60] szablon("dsu_amupper:pper_foot") /alidata/www/itsvse_web/source/plugin/dsu_amupper/pper.class.php:82 [0x7ffdd9ec54f0] plugin_dsu_amupper->global_footer(array(0)[0xeb834f8])
(gdb) druk ((zval *)0xec46a28) $1 = (zval *) 0xec46a28 (gdb) printzv $1 [0xec46a28] (refcount=5) array(1): { "url\0" => [0xecb2fb0] (refcount=2) string(33): "/admin.php?action=index&mobile=no" } (GDB) Rozwiązanie
Nie zauważyłem żadnych błędów, ale z logów było oczywiste, że jest problem z dostępem mobilnym, a po testach okazało się, że to faktycznie błąd 502 tylko w przypadku dostępu mobilnego.
Ponieważ w tle nie ma wersji mobilnej, bezpośrednio zmodyfikowałem kod źródłowy admin.php i dodałem następujący kod na pierwszej linii:
W ten sposób program zawsze otrzymuje żądanie dostępu z przeglądarki PC i nie przejdzie przez kod logiczny wersji na telefon komórkowy – rozwiązano!
|