Rumah >pembangunan bahagian belakang >tutorial php >Pemahaman mendalam tentang PHP: menyahpepijat kod sumber dengan gdb
Artikel ini membawa anda pengetahuan yang berkaitan tentang PHP, yang terutamanya memperkenalkan kandungan yang berkaitan tentang penggunaan gdb untuk menyahpepijat kod sumber Mari kita lihat bersama-sama.
Kajian yang disyorkan: "Tutorial Video PHP"
Terdapat mod nyahpepijat semasa menyusun PHP, yang akan mematikan pengoptimuman memori . Kebocoran memori segera, pengoptimuman tindanan panggilan yang melindungi membolehkan kami melihat timbunan panggilan peringkat C PHP yang lengkap.
Biasanya saya menyusun dua versi php (satu biasa, satu dengan nyahpepijat didayakan) dalam direktori berbeza dan memutuskan yang mana satu untuk digunakan melalui eksport.
Anda boleh melihat configure-options melalui arahan php-config, ubah suai awalan dan dengan-config-file-path ke direktori baharu, dan kemudian tambah arahan --enable-debug
yongkbmaster ➜ ~ php-config Usage: /data/env/runtime/php-7.1.33-debug/bin/php-config [OPTION] Options: --prefix [/data/env/runtime/php-7.1.33-debug] --includes [-I/data/env/runtime/php-7.1.33-debug/include/php -I/data/env/runtime/php-7.1.33-debug/include/php/main -I/data/env/runtime/php-7.1.33-debug/include/php/TSRM -I/data/env/runtime/php-7.1.33-debug/include/php/Zend -I/data/env/runtime/php-7.1.33-debug/include/php/ext -I/data/env/runtime/php-7.1.33-debug/include/php/ext/date/lib] --ldflags [] --libs [-lcrypt -lz -lexslt -lresolv -lcrypt -lrt -lldap -llber -lpng -lz -ljpeg -lcurl -lbz2 -lz -lrt -lm -ldl -lnsl -lxml2 -lz -lm -ldl -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lssl -lcrypto -lcurl -lxml2 -lz -lm -ldl -lfreetype -lxml2 -lz -lm -ldl -lxml2 -lz -lm -ldl -lcrypt -lxml2 -lz -lm -ldl -lxml2 -lz -lm -ldl -lxml2 -lz -lm -ldl -lxml2 -lz -lm -ldl -lxslt -lxml2 -lz -ldl -lm -lssl -lcrypto -lcrypt ] --extension-dir [/data/env/runtime/php-7.1.33-debug/lib/php/extensions/debug-non-zts-20160303] --include-dir [/data/env/runtime/php-7.1.33-debug/include/php] --man-dir [/data/env/runtime/php-7.1.33-debug/php/man] --php-binary [/data/env/runtime/php-7.1.33-debug/bin/php] --php-sapis [ cli fpm phpdbg cgi] --configure-options [--prefix=/data/env/runtime/php-7.1.33-debug --enable-debug --enable-phpdbg-debug --with-config-file-path=/data/env/runtime/php-7.1.33-debug/etc --with-curl --with-freetype-dir --with-gd --with-gettext --with-iconv-dir --with-kerberos --with-libdir=lib64 --with-libxml-dir --with-mysqli --with-openssl --with-pcre-regex --with-pdo-mysql --with-pdo-sqlite --with-pear --with-png-dir --with-jpeg-dir --with-xmlrpc --with-xsl --with-zlib --with-bz2 --with-mhash --enable-fpm --enable-bcmath --enable-libxml --enable-inline-optimization --enable-gd-native-ttf --enable-mbregex --enable-mbstring --enable-opcache --enable-pcntl --enable-shmop --enable-soap --enable-sockets --enable-sysvsem --enable-sysvshm --enable-xml --enable-zip --with-ldap] --version [7.1.33] --vernum [70133]
Selepas pengubahsuaian, ia mungkin akan kelihatan seperti ini, kemudian susun dan pasang untuk mendapatkan versi nyahpepijat
--prefix=/data/env/runtime/php-7.1.33-debug --enable-debug --enable-phpdbg-debug --with-config-file-path=/data/env/runtime/php-7.1.33-debug/etc --with-curl --with-freetype-dir --with-gd --with-gettext --with-iconv-dir --with-kerberos --with-libdir=lib64 --with-libxml-dir --with-mysqli --with-openssl --with-pcre-regex --with-pdo-mysql --with-pdo-sqlite --with-pear --with-png-dir --with-jpeg-dir --with-xmlrpc --with-xsl --with-zlib --with-bz2 --with-mhash --enable-fpm --enable-bcmath --enable-libxml --enable-inline-optimization --enable-gd-native-ttf --enable-mbregex --enable-mbstring --enable-opcache --enable-pcntl --enable-shmop --enable-soap --enable-sockets --enable-sysvsem --enable-sysvshm --enable-xml --enable-zip --with-ldap
Lihat sahaja DEBUG dalam php --version
yongkbmaster ➜ ~ /data/env/runtime/php-7.1.33-debug/bin/php --version PHP 7.1.33 (cli) (built: Dec 29 2020 19:16:50) ( NTS DEBUG ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologie
Nota. : Nyahpepijat Versi sambungan perlu dikompilasi dan dipasang semula Versi biasa supaya tidak boleh disalin. Jika anda perlu menyahpepijat sambungan seperti swoole, anda perlu menetapkan parameter nyahpepijat sambungan Anda boleh merujuk kepada ./configure huraian fail sambungan.
Berikut adalah pengenalan ringkas tentang penggunaan asas gdb Untuk penggunaan yang lebih terperinci, anda boleh google sendiri.
Mulakan gdb
Proses tangkap
gdb -p {pid}
jalankan kaedah mula
gdb php run test3.php
Lulus fail teras
gdb -c core.8451
titik putus
break n: Tetapkan titik putus pada baris n (anda boleh membawa laluan kod dan Nama kod)
//注意:这里只能断点c代码,php文件不行的,var.c:201在php-7.1.33是var_dump的入口 break var.c:201
b fn1 jika a>b: Tetapan titik putus bersyarat
fungsi putus (putus disingkatkan b): Tetapkan titik putus di pintu masuk fungsi func()
maklumat b (titik putus maklumat): paparkan tetapan titik putus program semasapadam titik putus: Kosongkan semua titik putus
Lain-lain
senarai (disingkat l), fungsinya adalah untuk menyenaraikan program Kod sumber memaparkan 10 baris pada satu masa secara lalai. nombor baris senarai: akan memaparkan 10 baris kod sebelum dan selepas fail semasa berpusat pada "nombor baris",
cetak a: akan memaparkan nilai
terus (disingkatkan sebagai c): teruskan pelaksanaan ke titik putus seterusnya (atau tamat larian). Anda perlu menekan ini selepas menetapkan titik putus.
seterusnya (singkatan n): fungsi semasa, baris seterusnya
langkah (singkatan s): lompat ke dalam fungsi
di mana/bt: sedang menjalankan senarai tindanan;
alat gdb php
Untuk demonstrasi yang lebih baik, saya akan menyediakan fail php di sini.
Mulakan gdb dan tetapkan 2 titik putus. Kemudian muatkan alat
<?php const A = 'test const'; const B = 'test const B'; class B { public $a = 'test'; public function funB() { var_dump('test funB'); } } class C extends B { public function funC() { var_dump('test funC'); } } $a = 'test'; $b = ['a1' => 1, 'a2' => 2]; $c = new B(); $d = [A, B]; $e = new C(); $f = $b; var_dump($a, $b, $c, $d, $e, $f); get_object_vars($e);
Gunakan
gdb php //注意这里要用debug版本的 (gdb) break var.c:211 Breakpoint 1 at 0x76e717: file /data/env/runtime/php-7.1.33-src/ext/standard/var.c, line 211. (gdb) break zend_object_handlers.c:492 Breakpoint 2 at 0x86ce9d: file /data/env/runtime/php-7.1.33-src/Zend/zend_object_handlers.c, line 492. (gdb) r test4.phpzbacktrace untuk memaparkan timbunan panggilan php semasa
source /data/env/runtime/php-7.1.33-src/.gdbinit
dump_bt Lihat tindanan panggilan semasa dan zbacktrace yang serupa dengan printzv output nilai zend
print_global_vars output global variable(gdb) zbacktrace [0x7ffff1614200] var_dump("test", array(2)[0x7ffff1614260], object[0x7ffff1614270], array(2)[0x7ffff1614280], object[0x7ffff1614290], array(2)[0x7ffff16142a0]) [internal function] [0x7ffff1614030] (main) /root/test4.php:26print_const_table mengeluarkan pemalar yang ditakrifkan
(gdb) dump_bt executor_globals.current_execute_data [0x7ffff1614200] var_dump("test", array(2)[0x7ffff1614260], object[0x7ffff1614270], array(2)[0x7ffff1614280], object[0x7ffff1614290], array(2)[0x7ffff16142a0]) [internal function] [0x7ffff1614030] (main) /root/test4.php:26
print_zstr mengeluarkan rentetan zend
(gdb) printzv &args[0] [0x7ffff1614250] (refcount=0) string: test
print_cvs mencetak pembolehubah yang disusun dan nilainya Ia perlu menghantar nilai jenis zend_execute_data. Anda boleh melihat timbunan panggilan dahulu.
(gdb) print_global_vars Hash(13)[0x11bf0d0]: { [0] _GET => [0x7ffff1657100] (refcount=2) array: [1] _POST => [0x7ffff1657120] (refcount=2) array: [2] _COOKIE => [0x7ffff1657140] (refcount=2) array: [3] _FILES => [0x7ffff1657160] (refcount=2) array: [4] argv => [0x7ffff1657180] (refcount=2) array: [5] argc => [0x7ffff16571a0] long: 1 [6] _SERVER => [0x7ffff16571c0] (refcount=2) array: [7] a => [0x7ffff16571e0] indirect: [0x7ffff1613080] (refcount=0) string: test [8] b => [0x7ffff1657200] indirect: [0x7ffff1613090] (refcount=5) array: [9] c => [0x7ffff1657220] indirect: [0x7ffff16130a0] (refcount=2) object(B) #2 [10] d => [0x7ffff1657240] indirect: [0x7ffff16130b0] (refcount=2) array: [11] e => [0x7ffff1657260] indirect: [0x7ffff16130c0] (refcount=2) object(C) #3 [12] f => [0x7ffff1657280] indirect: [0x7ffff16130d0] (refcount=5) array:
print_ht output HashTable ialah struktur data yang penting di bahagian bawah PHP. Anda boleh memahaminya sebagai tatasusunan PHP peringkat C dalam kod sumber PHP untuk menyimpan pelbagai item Kelas k v struktur atau struktur tatasusunan.
(gdb) print_const_table executor_globals.zend_constants [0x14e8380] { Hash(2340)[0x14e8380]: { [0] E_ERROR => [0x14fd660] long: 1 [1] E_RECOVERABLE_ERROR => [0x14fe8a0] long: 4096 [2] E_WARNING => [0x14fe900] long: 2 [3] E_PARSE => [0x14fe960] long: 4 [4] E_NOTICE => [0x14fe9c0] long: 8 [5] E_STRICT => [0x14fea20] long: 2048 [6] E_DEPRECATED => [0x14fea80] long: 8192 [7] E_CORE_ERROR => [0x14feae0] long: 16 [8] E_CORE_WARNING => [0x14feb40] long: 32 [9] E_COMPILE_ERROR => [0x14feba0] long: 64 [10] E_COMPILE_WARNING => [0x14fec10] long: 128 [11] E_USER_ERROR => [0x14fec70] long: 256 [12] E_USER_WARNING => [0x14fecd0] long: 512 [13] E_USER_NOTICE => [0x14fed30] long: 1024 [14] E_USER_DEPRECATED => [0x14feda0] long: 16384 [15] E_ALL => [0x14fee00] long: 32767 [16] DEBUG_BACKTRACE_PROVIDE_OBJECT => [0x14fee70] long: 1 [17] DEBUG_BACKTRACE_IGNORE_ARGS => [0x14feee0] long: 2 [18] true => [0x14fef70] bool: true [19] false => [0x14ff000] bool: false [20] ZEND_THREAD_SAFE => [0x14ff070] bool: false [21] ZEND_DEBUG_BUILD => [0x14ff0e0] bool: true [22] null => [0x14ff170] NULL [23] PHP_VERSION => [0x1500380] (refcount=1) string: 7.1.33 ......
print_htptr serupa dengan print_ht, ia mengeluarkan alamat zval, bukan nilai zval
(gdb) print_zstr args[0] string(4) "test" (gdb) print_zstr args[0] 2 string(4) "te..." (gdb) print_zstr args[0] 4 string(4) "test"
print_htstr serupa dengan print_ht, kecuali HashTable menyimpan c char. bukannya zval , tetapi keadaan ini nampaknya jarang berlaku dalam kod sumber Dalam kebanyakan kes menyimpan rentetan, rentetan zend akan digunakan secara langsung dan menemui tempat dalam php_cli_server_mime_type_ctor di mana
(gdb) bt //这里看到 #2 层这里是 zend_vm_execute 的执行入口,这里有zend_execute_data 类型的值。 #0 zif_var_dump (execute_data=0x7ffff1614120, return_value=0x7fffffffa9b0) at /data/env/runtime/php-7.1.33-src/ext/standard/var.c:209 #1 0x0000000000ab08d4 in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER () at /data/env/runtime/php-7.1.33-src/Zend/zend_vm_execute.h:628 #2 0x0000000000ab01c3 in execute_ex (ex=0x7ffff1614030) at /data/env/runtime/php-7.1.33-src/Zend/zend_vm_execute.h:429 #3 0x0000000000ab02d5 in zend_execute (op_array=0x7ffff1672d00, return_value=0x0) at /data/env/runtime/php-7.1.33-src/Zend/zend_vm_execute.h:474 #4 0x0000000000a510f9 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /data/env/runtime/php-7.1.33-src/Zend/zend.c:1482 #5 0x00000000009c02f4 in php_execute_script (primary_file=0x7fffffffdf30) at /data/env/runtime/php-7.1.33-src/main/main.c:2577 #6 0x0000000000b31387 in do_cli (argc=2, argv=0x14e7f30) at /data/env/runtime/php-7.1.33-src/sapi/cli/php_cli.c:993 #7 0x0000000000b32346 in main (argc=2, argv=0x14e7f30) at /data/env/runtime/php-7.1.33-src/sapi/cli/php_cli.c:1381 (gdb) f 2 //跳到#2 这一层 #2 0x0000000000ab01c3 in execute_ex (ex=0x7ffff1614030) at /data/env/runtime/php-7.1.33-src/Zend/zend_vm_execute.h:429 429 ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); (gdb) print_cvs ex //输出 Compiled variables count: 6 [0] 'a' [0x7ffff1614080] (refcount=0) string: test [1] 'b' [0x7ffff1614090] (refcount=5) array: Hash(2)[0x7ffff170e300]: { [0] a1 => [0x7ffff1793e20] long: 1 [1] a2 => [0x7ffff1793e40] long: 2 } [2] 'c' [0x7ffff16140a0] (refcount=2) object(B) #2 Properties Hash(1)[0x7ffff170e480]: { [0] a => [0x7ffff1793f60] indirect: [0x7ffff170e388] (refcount=4) string: test } [3] 'd' [0x7ffff16140b0] (refcount=2) array: Packed(2)[0x7ffff170e3c0]: { [0] 0 => [0x7ffff1793688] (refcount=1) string: test const [1] 1 => [0x7ffff17936a8] (refcount=1) string: test const B } [4] 'e' [0x7ffff16140c0] (refcount=2) object(C) #3 Properties Hash(1)[0x7ffff170e4e0]: { [0] a => [0x7ffff17940a0] indirect: [0x7ffff170e448] (refcount=4) string: test } [5] 'f' [0x7ffff16140d0] (refcount=5) array: Hash(2)[0x7ffff170e300]: { [0] a1 => [0x7ffff1793e20] long: 1 [1] a2 => [0x7ffff1793e40] long: 2 }
print_ft adalah serupa dengan print_ht , kecuali alamat zend_function disimpan dalam HashTable
(gdb) print_ht args[1].value Hash(2)[0x7ffff170e300]: { [0] a1 => [0x7ffff1793e20] long: 1 [1] a2 => [0x7ffff1793e40] long: 2 } (gdb) print_ht args[3].value Packed(2)[0x7ffff170e3c0]: { [0] 0 => [0x7ffff1793688] (refcount=1) string: test const [1] 1 => [0x7ffff17936a8] (refcount=1) string: test const B }
print_inh output maklumat berkaitan kelas
(gdb) print_htptr args[1].value Hash(2)[0x7ffff170e300]: { [0] a1 => 0x7ffff1793e20 [1] a2 => 0x7ffff1793e40 }
print_pi mengeluarkan maklumat berkaitan atribut dalam objek, ia perlu memasukkan alamat jenis zend_property_info , digunakan dalam zend_object_handlers.c:492, dan boleh dicetuskan oleh get_object_vars($e) dalam PHP.
(gdb) print_htstr &server->extension_mime_types Hash(2)[0x11b9228]: { [0] ez => application/andrew-inset [1] aw => application/applixware }
Pembelajaran yang disyorkan: "
Tutorial Video PHP(gdb) print_ft &args[2].value.obj.ce.function_table Hash(1)[0x7ffff1783210]: { [0] funb => "funB" }"
Atas ialah kandungan terperinci Pemahaman mendalam tentang PHP: menyahpepijat kod sumber dengan gdb. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!