PHP에 대한 깊은 이해: gdb를 사용하여 소스 코드 디버깅
이 기사는 PHP에 대한 관련 지식을 제공하며, 주로 gdb를 사용하여 소스 코드를 디버깅하는 것과 관련된 내용을 소개합니다. 모두에게 도움이 되기를 바랍니다.
추천 연구: "PHP 비디오 튜토리얼"
PHP에는 컴파일 시 디버그 모드가 있습니다. 이 모드는 전체 PHP를 볼 수 있도록 메모리 최적화, 프롬프트 메모리 누수 및 보호 호출 스택 최적화를 끕니다. C 레벨 호출 스택.
보통 저는 서로 다른 디렉토리에 두 개의 PHP 버전(하나는 일반, 하나는 디버그 활성화)을 컴파일하고 내보내기를 통해 어떤 버전을 사용할지 결정합니다.
php-config 명령을 통해 구성 옵션을 볼 수 있으며, 접두사와 with-config-file-path를 새 디렉터리로 수정한 다음 --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]
수정 후 모습 그런 다음 디버그 버전을 얻으려면 컴파일하고 설치하세요
--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
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
에서 DEBUG를 참조하세요. 참고: 확장 프로그램의 디버그 버전은 다시 컴파일하고 설치해야 하며 일반 버전은 그럴 수 없습니다. 설치 방법은 일반 확장과 동일합니다. 일반적으로 추가 디버그 매개변수를 열 필요가 없습니다. swoole과 같은 확장을 디버그해야 하는 경우 확장의 디버그 매개변수를 설정해야 합니다. 확장의 ./configure 파일 설명을 참조할 수 있습니다.
Gdb 사용하기
여기서 gdb의 기본 사용법에 대해 간략하게 소개합니다. 더 자세한 사용법은 직접 구글링해보시면 됩니다. start gdbartcapture process
gdb -p {pid}
run 메소드 startgdb php
run test3.php
gdb -c core.8451
breakspointingbreak n : line n에서 중단 점을 설정합니다 (코드 경로를 가져올 수 있습니다. 코드명)
//注意:这里只能断点c代码,php文件不行的,var.c:201在php-7.1.33是var_dump的入口 break var.c:201
b fn1 if a>b: 조건부 중단점 설정
break func (break는 b로 축약됨): 함수 func() 입구에 중단점 설정
//大部分php的方法在c层面的方法名都是zif_ + php方法名。 例如 var_dump 在c的方法名叫zif_var_dump break zif_var_dump
delete 중단점 번호 n: n번째 삭제 breakpointdisable 중단점 번호 n: n번째 중단점 일시 중지enable 중단점 번호 n: n번째 중단점 활성화
clear 줄 번호 n: n번째 줄의 중단점 지우기
info b(정보 중단점): 중단점 설정을 표시합니다. 현재 프로그램
delete breakpoints: 모든 중단점을 지웁니다.
Others
list(약어로 l), 해당 기능은 프로그램 코드의 소스를 나열하는 것입니다. 한 번에 10줄이 표시됩니다. 기본.
list line number: "line number"를 중심으로 현재 파일 앞뒤 10줄의 코드를 표시합니다. print a: a
continue(약어 c) 값을 표시합니다. ): 실행을 계속하고 다음 중단점(또는 실행 끝)으로 이동합니다. 중단점을 설정한 후 이 버튼을 눌러야 합니다.
next(약어 n): 현재 함수, 다음 줄
step(약어 s): 함수 내부로 점프
where/bt: 현재 실행 중인 스택 목록
php; gdb 작은 도구
이 기사의 초점은 PHP가 gdb용 작은 도구 세트를 제공한다는 것입니다. 소스 코드 디렉토리의 .gdbinit 파일은 gdb PHP 소스 코드를 더 잘 이해하는 데 도움이 될 수 있습니다. - 준비
- 더 나은 시연을 위해 여기에 PHP 파일을 준비하겠습니다.
<?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);
gdb를 시작하고 2개의 중단점을 설정하세요.
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.php
그런 다음 가젯을 로드하고
source /data/env/runtime/php-7.1.33-src/.gdbinit
zbacktrace를 사용하여 현재 PHP 호출 스택을 표시하고
(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:26
dump_bt를 사용하여 현재 호출 스택 및
(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
printzv 출력 zend 값
(gdb) printzv &args[0] [0x7ffff1614250] (refcount=0) string: test
print_global_vars 출력 전역 변수(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:
(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
......
(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_cvs 컴파일된 변수 및 해당 값 인쇄 zend_execute_data 유형 값을 전달해야 합니다. 먼저 호출 스택을 살펴볼 수 있습니다.
(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_ht는 HashTable을 출력합니다. HashTable은 PHP 배열의 구현입니다. HashTable은 PHP 소스 코드에서도 널리 사용되어 다양한 내용을 저장합니다. k v 구조 또는 배열 구조.
(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_htptr은 zval의 값이 아닌 zval의 주소를 출력합니다.
(gdb) print_htptr args[1].value Hash(2)[0x7ffff170e300]: { [0] a1 => 0x7ffff1793e20 [1] a2 => 0x7ffff1793e40 }
print_htstr은 HashTable이 zval 대신 c char을 저장한다는 점을 제외하면 print_ht와 유사합니다. 대부분 문자열을 저장할 때 zend string을 직접 사용하게 되는데, php_cli_server_mime_type_ctor를 사용하는 곳을 찾았습니다.
(gdb) print_htstr &server->extension_mime_types Hash(2)[0x11b9228]: { [0] ez => application/andrew-inset [1] aw => application/applixware }
print_ft는 zend_function의 주소가 저장되어 있다는 점만 빼고는 비슷합니다. HashTable.
(gdb) print_ft &args[2].value.obj.ce.function_table Hash(1)[0x7ffff1783210]: { [0] funb => "funB" }
print_inh는 클래스 관련 정보를 출력합니다.
(gdb) print_inh &args[4].value.obj.ce class C extends B { class B { } }
print_pi는 객체의 속성과 관련된 정보를 출력하며 zend_object_handlers.c:492에서 사용되는 형식의 주소를 전달해야 합니다. PHP의 get_object_vars($e).
(gdb) c Continuing. Breakpoint 2, zend_check_property_access (zobj=0x7ffff170e420, prop_info_name=0x7ffff173c2c0) at /data/env/runtime/php-7.1.33-src/Zend/zend_object_handlers.c:492 492 zend_string_release(member); (gdb) print_pi property_info [0x7ffff17833c8] { offset = 0x28 ce = [0x7ffff17831d0] B flags = 0x100 (ZEND_ACC_PUBLIC) name = string(1) "a" default value: [0x7ffff17690c0] (refcount=4) string: test }
추천 학습: "
PHP 비디오 튜토리얼"
위 내용은 PHP에 대한 깊은 이해: gdb를 사용하여 소스 코드 디버깅의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

PHP 8.4는 상당한 양의 기능 중단 및 제거를 통해 몇 가지 새로운 기능, 보안 개선 및 성능 개선을 제공합니다. 이 가이드에서는 Ubuntu, Debian 또는 해당 파생 제품에서 PHP 8.4를 설치하거나 PHP 8.4로 업그레이드하는 방법을 설명합니다.

JWT는 주로 신분증 인증 및 정보 교환을 위해 당사자간에 정보를 안전하게 전송하는 데 사용되는 JSON을 기반으로 한 개방형 표준입니다. 1. JWT는 헤더, 페이로드 및 서명의 세 부분으로 구성됩니다. 2. JWT의 작업 원칙에는 세 가지 단계가 포함됩니다. JWT 생성, JWT 확인 및 Parsing Payload. 3. PHP에서 인증에 JWT를 사용하면 JWT를 생성하고 확인할 수 있으며 사용자 역할 및 권한 정보가 고급 사용에 포함될 수 있습니다. 4. 일반적인 오류에는 서명 검증 실패, 토큰 만료 및 대형 페이로드가 포함됩니다. 디버깅 기술에는 디버깅 도구 및 로깅 사용이 포함됩니다. 5. 성능 최적화 및 모범 사례에는 적절한 시그니처 알고리즘 사용, 타당성 기간 설정 합리적,

이 튜토리얼은 PHP를 사용하여 XML 문서를 효율적으로 처리하는 방법을 보여줍니다. XML (Extensible Markup Language)은 인간의 가독성과 기계 구문 분석을 위해 설계된 다목적 텍스트 기반 마크 업 언어입니다. 일반적으로 데이터 저장 AN에 사용됩니다

정적 바인딩 (정적 : :)는 PHP에서 늦은 정적 바인딩 (LSB)을 구현하여 클래스를 정의하는 대신 정적 컨텍스트에서 호출 클래스를 참조 할 수 있습니다. 1) 구문 분석 프로세스는 런타임에 수행됩니다. 2) 상속 관계에서 통화 클래스를 찾아보십시오. 3) 성능 오버 헤드를 가져올 수 있습니다.

문자열은 문자, 숫자 및 기호를 포함하여 일련의 문자입니다. 이 튜토리얼은 다른 방법을 사용하여 PHP의 주어진 문자열의 모음 수를 계산하는 방법을 배웁니다. 영어의 모음은 A, E, I, O, U이며 대문자 또는 소문자 일 수 있습니다. 모음이란 무엇입니까? 모음은 특정 발음을 나타내는 알파벳 문자입니다. 대문자와 소문자를 포함하여 영어에는 5 개의 모음이 있습니다. a, e, i, o, u 예 1 입력 : String = "Tutorialspoint" 출력 : 6 설명하다 문자열의 "Tutorialspoint"의 모음은 u, o, i, a, o, i입니다. 총 6 개의 위안이 있습니다

PHP와 Python은 각각 고유 한 장점이 있으며 프로젝트 요구 사항에 따라 선택합니다. 1.PHP는 웹 개발, 특히 웹 사이트의 빠른 개발 및 유지 보수에 적합합니다. 2. Python은 간결한 구문을 가진 데이터 과학, 기계 학습 및 인공 지능에 적합하며 초보자에게 적합합니다.

PHP의 마법 방법은 무엇입니까? PHP의 마법 방법은 다음과 같습니다. 1. \ _ \ _ Construct, 객체를 초기화하는 데 사용됩니다. 2. \ _ \ _ 파괴, 자원을 정리하는 데 사용됩니다. 3. \ _ \ _ 호출, 존재하지 않는 메소드 호출을 처리하십시오. 4. \ _ \ _ get, 동적 속성 액세스를 구현하십시오. 5. \ _ \ _ Set, 동적 속성 설정을 구현하십시오. 이러한 방법은 특정 상황에서 자동으로 호출되어 코드 유연성과 효율성을 향상시킵니다.

PHP는 서버 측에서 널리 사용되는 스크립팅 언어이며 특히 웹 개발에 적합합니다. 1.PHP는 HTML을 포함하고 HTTP 요청 및 응답을 처리 할 수 있으며 다양한 데이터베이스를 지원할 수 있습니다. 2.PHP는 강력한 커뮤니티 지원 및 오픈 소스 리소스를 통해 동적 웹 컨텐츠, 프로세스 양식 데이터, 액세스 데이터베이스 등을 생성하는 데 사용됩니다. 3. PHP는 해석 된 언어이며, 실행 프로세스에는 어휘 분석, 문법 분석, 편집 및 실행이 포함됩니다. 4. PHP는 사용자 등록 시스템과 같은 고급 응용 프로그램을 위해 MySQL과 결합 할 수 있습니다. 5. PHP를 디버깅 할 때 error_reporting () 및 var_dump ()와 같은 함수를 사용할 수 있습니다. 6. 캐싱 메커니즘을 사용하여 PHP 코드를 최적화하고 데이터베이스 쿼리를 최적화하며 내장 기능을 사용하십시오. 7
