Table of Contents
gdb usage
php gdb gadget
Home Backend Development PHP Tutorial Deep understanding of PHP: debugging source code with gdb

Deep understanding of PHP: debugging source code with gdb

Dec 28, 2022 pm 06:12 PM
php

This article brings you relevant knowledge about PHP, which mainly introduces the relevant content about using gdb to debug source code. Let’s take a look at it together. I hope it will be helpful to everyone.

Deep understanding of PHP: debugging source code with gdb

Recommended study: "PHP Video Tutorial"

There is a debug mode when php is compiled, this mode will turn off memory optimization. Prompt memory leaks, shielding call stack optimization allows us to see the complete PHP C-level call stack.

Usually I compile two php versions (one normal, one with debug enabled) in different directories, and decide which one to use through export.

You can see configure-options through the php-config command, modify the prefix and with-config-file-path to the new directory, and then add the --enable-debug command

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]
Copy after login

After modification, it will probably look like this. Then compile and install to get the debug version.

--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
Copy after login

Just see DEBUG in 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
Copy after login

Note: The debug version of the extension needs to be compiled again. During installation, you cannot copy the normal version of so. The installation method is the same as that of ordinary extensions. Generally, there is no need to open additional debug parameters. If you need to debug an extension such as swoole, you need to set the debug parameters of the extension. You can refer to the ./configure file description of the extension.

gdb usage

Here is a brief introduction to the basic use of gdb. For more detailed usage, you can google it yourself.

Start gdb

Capture process

gdb -p {pid}
Copy after login

run method starts

gdb php
run test3.php
Copy after login

Through core file

gdb -c core.8451
Copy after login

Breakpoint

break n: Set a breakpoint at line n (you can bring the code path and code name)

//注意:这里只能断点c代码,php文件不行的,var.c:201在php-7.1.33是var_dump的入口
break var.c:201
Copy after login

b fn1 if a>b: Conditional breakpoint setting

break func (break is abbreviated as b): Set a breakpoint at the entrance of function func()

//大部分php的方法在c层面的方法名都是zif_ + php方法名。 例如 var_dump 在c的方法名叫zif_var_dump
break zif_var_dump
Copy after login

delete breakpoint Number n: Delete the nth breakpoint

disable Breakpoint number n: Pause the nth breakpoint

enable Breakpoint number n: Enable the nth breakpoint

clear line number n: Clear the breakpoint on line n

info b (info breakpoints): Display the breakpoint settings of the current program

delete breakpoints: Clear all breakpoints

Others

  • list (abbreviated as l), its function is to list the source code of the program. By default, 10 lines are displayed at a time .

  • list line number: will display the 10 lines of code before and after the current file centered on the "line number",

  • print a: will display The value of a

  • continue (abbreviated as c): Continue execution to the next breakpoint (or end of the run). You need to press this after setting a breakpoint.

  • next (abbreviation n): current function, next line

  • step (abbreviation s): jump into the function

  • where/bt: currently running stack list;

php gdb gadget

This is the focus of this article. PHP provides gdb A set of small tools, in the .gdbinit file in the source code directory, which can help us make better gdb php source code.

Preparation

For a better demonstration, I will prepare a php file here.

<?php
const A = &#39;test const&#39;;
const B = &#39;test const B&#39;;
class B {
        public $a = &#39;test&#39;;
        public function funB() {
                var_dump(&#39;test funB&#39;);
        }
}
class C extends B {
        public function funC() {
                var_dump(&#39;test funC&#39;);
        }
}
$a = &#39;test&#39;;
$b = [&#39;a1&#39; => 1, &#39;a2&#39; => 2];
$c = new B();
$d = [A, B];
$e = new C();
$f = $b;
var_dump($a, $b, $c, $d, $e, $f);
get_object_vars($e);
Copy after login

Start gdb and set 2 breakpoints.

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
Copy after login

Then load the gadget

source /data/env/runtime/php-7.1.33-src/.gdbinit
Copy after login

Use

zbacktrace to display the current php call stack

(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
Copy after login

dump_bt View the current call stack and zbacktrace similar to

(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
Copy after login

printzv output zend value

(gdb) printzv &args[0]
[0x7ffff1614250] (refcount=0) string: test
Copy after login

print_global_vars output global variables

(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:
Copy after login

print_const_table output defined constants

(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
 ......
Copy after login

print_zstr Output zend string

(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"
Copy after login

print_cvs Print compiled variables and their values ​​It needs to pass in a zend_execute_data type value. You can take a look at the call stack first.

(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] &#39;a&#39;
[0x7ffff1614080] (refcount=0) string: test
[1] &#39;b&#39;
[0x7ffff1614090] (refcount=5) array:     Hash(2)[0x7ffff170e300]: {
      [0] a1 => [0x7ffff1793e20] long: 1
      [1] a2 => [0x7ffff1793e40] long: 2
}
[2] &#39;c&#39;
[0x7ffff16140a0] (refcount=2) object(B) #2
Properties     Hash(1)[0x7ffff170e480]: {
      [0] a => [0x7ffff1793f60] indirect: [0x7ffff170e388] (refcount=4) string: test
}
[3] &#39;d&#39;
[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] &#39;e&#39;
[0x7ffff16140c0] (refcount=2) object(C) #3
Properties     Hash(1)[0x7ffff170e4e0]: {
      [0] a => [0x7ffff17940a0] indirect: [0x7ffff170e448] (refcount=4) string: test
}
[5] &#39;f&#39;
[0x7ffff16140d0] (refcount=5) array:     Hash(2)[0x7ffff170e300]: {
      [0] a1 => [0x7ffff1793e20] long: 1
      [1] a2 => [0x7ffff1793e40] long: 2
}
Copy after login

print_ht Output HashTable. HashTable is an important data structure at the bottom of PHP. It is the implementation of PHP array. You can understand it as C-level PHP array. HashTable is also widely used in PHP source code to store various k v structure or array structure.

(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
}
Copy after login

print_htptr is similar to print_ht, it outputs the address of zval instead of the value of zval

(gdb) print_htptr args[1].value
Hash(2)[0x7ffff170e300]: {
  [0] a1 => 0x7ffff1793e20
  [1] a2 => 0x7ffff1793e40
}
Copy after login

print_htstr is similar to print_ht, except that the HashTable stores c char instead of zval, but this This situation seems to be rare in the source code. In most cases of storing strings, zend string will be used directly. I searched around and found a place in php_cli_server_mime_type_ctor where

(gdb) print_htstr &server->extension_mime_types
Hash(2)[0x11b9228]: {
  [0] ez => application/andrew-inset
  [1] aw => application/applixware
}
Copy after login

print_ft is similar to print_ht, but it is stored in HashTable. Is the address of zend_function

(gdb) print_ft &args[2].value.obj.ce.function_table
Hash(1)[0x7ffff1783210]: {
  [0] funb => "funB"
}
Copy after login

print_inh Outputs class-related information

(gdb) print_inh &args[4].value.obj.ce
class C extends B {
 class B {
 }
}
Copy after login

print_pi Outputs attribute-related information in the object. It needs to pass in an address of zend_property_info type, which is used in zend_object_handlers.c:492 , it can be triggered by get_object_vars($e) in PHP.

(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
}
Copy after login

Recommended learning: "PHP Video Tutorial"

The above is the detailed content of Deep understanding of PHP: debugging source code with gdb. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

PHP 8.4 Installation and Upgrade guide for Ubuntu and Debian PHP 8.4 Installation and Upgrade guide for Ubuntu and Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

How To Set Up Visual Studio Code (VS Code) for PHP Development How To Set Up Visual Studio Code (VS Code) for PHP Development Dec 20, 2024 am 11:31 AM

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

7 PHP Functions I Regret I Didn't Know Before 7 PHP Functions I Regret I Didn't Know Before Nov 13, 2024 am 09:42 AM

If you are an experienced PHP developer, you might have the feeling that you’ve been there and done that already.You have developed a significant number of applications, debugged millions of lines of code, and tweaked a bunch of scripts to achieve op

How do you parse and process HTML/XML in PHP? How do you parse and process HTML/XML in PHP? Feb 07, 2025 am 11:57 AM

This tutorial demonstrates how to efficiently process XML documents using PHP. XML (eXtensible Markup Language) is a versatile text-based markup language designed for both human readability and machine parsing. It's commonly used for data storage an

Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Apr 05, 2025 am 12:04 AM

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

PHP Program to Count Vowels in a String PHP Program to Count Vowels in a String Feb 07, 2025 pm 12:12 PM

A string is a sequence of characters, including letters, numbers, and symbols. This tutorial will learn how to calculate the number of vowels in a given string in PHP using different methods. The vowels in English are a, e, i, o, u, and they can be uppercase or lowercase. What is a vowel? Vowels are alphabetic characters that represent a specific pronunciation. There are five vowels in English, including uppercase and lowercase: a, e, i, o, u Example 1 Input: String = "Tutorialspoint" Output: 6 explain The vowels in the string "Tutorialspoint" are u, o, i, a, o, i. There are 6 yuan in total

Explain late static binding in PHP (static::). Explain late static binding in PHP (static::). Apr 03, 2025 am 12:04 AM

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? Apr 03, 2025 am 12:03 AM

What are the magic methods of PHP? PHP's magic methods include: 1.\_\_construct, used to initialize objects; 2.\_\_destruct, used to clean up resources; 3.\_\_call, handle non-existent method calls; 4.\_\_get, implement dynamic attribute access; 5.\_\_set, implement dynamic attribute settings. These methods are automatically called in certain situations, improving code flexibility and efficiency.

See all articles