En/xdebug

Welcome to Simone Giustetti's wiki pages.


Languages: English - Italiano


Introduction

PHP is a mature programming language maintained by an active community for the past two decades. In spite of its widespread use for dynamic web site development, PHP lacks some features adopted by lesser known languages for quite some time. An evident lack consisting in the absence of a default integrated debugger. The term Debugging summarizes the analysis and bug correction activities that occupy a considerable part of every developer working time. Availability of powerful advanced easy to configure and use tools grants an increased productivity and evident gains for both developers and end users.
PHP release 5.6 introduced a largely anticipated new feature: PHPDbg the integrated debugger. Given the short age of the release and the large diffusion earlier ones still have in production environments, I'll present some available alternatives to PHPDbg:

A first attempt at a PHP debugger designed as a Zend engine extension. ADP development seems to have met a stop long ago: the last official release dates back to 2004.
A commercial product. A free version of DBG with reduced functionality and no support is available for download. The commercial version works with all of modern PHP releases up to 5.5 while the open source one, whose latest release dates back to 2007, is restricted to PHP 5.2.
Seems to be the only software still actively developed. The next major release 2.4 was announced in January 2016. Xdebug is a free and open source product whose source code can be freely downloaded, studied, modified and redistributed.


In this paper I'll try to explain you how to install, configure and use Xdebug on a Linux host running Slackware Linux.


Xdebug

Xdebug is designed as a plug-in module that extends the PHP Zend engine adding useful functionality for debugging and profiling of source code. Xdebug uses the standard DBGp debugging protocol and can:

  • Dump the flow of function calls and stack traces.
  • Dump all of the parameter values passed to functions.
  • Monitor memory usage.
  • Execute interactive debugging of source code when used together with a graphical debugging program.

Installing

Xdebug is distributed as a PECL (PHP Extension Community Library) extension, but it is still possible to build and install it as a standard Linux package. I chose the latter method even if it requires some extra work because it allows to remove, reinstall and update the software recurring to standard operating system commands. A step by step procedure to install Xdebug from source code is described below. All the steps other than file download should be executed by an user with administrator privileges as root.

  • Download the source code archive from the Xdebug official web site into a directory of choice. I'll use /tmp.
  • Download the SlackBuild file used to build a Slackware Linux package in a directory of your choice. I'll use /tmp again.
  • Decompress the xdebug.tar.gz archive containing the xdebug.SlackBuild build script:
  root@darkstar_5:/tmp# tar -zxf xdebug.tar.gz 
  root@darkstar_5:/tmp# ls -la xdebug
  total 36
  drwxr-xr-x  2 1016 users 4096 Dec 25  2014 .
  drwxrwxrwt 15 root root  4096 Feb  2 18:53 ..
  -rw-r--r--  1 1016 users  974 Nov 26  2013 README
  -rw-r--r--  1 1016 users  507 Nov 26  2013 doinst.sh
  -rw-r--r--  1 1016 users 1093 Nov 26  2013 slack-desc
  -rwxr-xr-x  1 1016 users 4157 Dec 25  2014 xdebug.SlackBuild
  -rw-r--r--  1 1016 users  266 Dec 25  2014 xdebug.info
  -rw-r--r--  1 1016 users 1270 Nov 26  2013 xdebug.ini
  • Edit the script assigning the right release number to the VERSION variable. While I write these lines Xdebug 2.4 has not been released yet therefore I'll use release 2.3.3. Load the xdebug.SlackBuild file in your text editor of choice; mine is vim:
  root@darkstar_5:/tmp# vim xdebug/xdebug.SlackBuild

Search for variable VERSION and update the assigned value to match the Xdebug version string:

   PRGNAM=xdebug
   VERSION=${VERSION:-2.2.6}
   BUILD=${BUILD:-1}

Should became:

   PRGNAM=xdebug
   VERSION=${VERSION:-2.3.3}
   BUILD=${BUILD:-1}

The updated script will suffice to build a working package, but if you wish to produce a package in the txz format, the last one adopted by Slackware, instead of the old and usual tgz you'll have to modify one more line: the one that invokes the package generation command.

   cd $PKG
   /sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.${PKGTYPE:-tgz}

Should be updated in:

   cd $PKG
   /sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.${PKGTYPE:-txz}

Once all of the desired SlackBuild script lines are updated you are ready to run the script thus starting the build procedure.

  • Copy the source code tarball into the directory containing script xdebug.SlackBuild:
  root@darkstar_5:/tmp# cp xdebug-2.3.3.tgz xdebug
  • Run the script:
  root@darkstar_5:/tmp# cd xdebug
  root@darkstar_5:/tmp/xdebug# sh ./xdebug.SlackBuild 

The script will execute each step in autonomy calling the /usr/bin/phpize command, configuring the source code and compiling it to produce a working package in directory /tmp. The produced binaries include both the Xdebug server layer and the client one debugclient. Invoke the installpkg command to install the newly generated package as in the example below:

  root@darkstar_5:/tmp/xdebug# cd /tmp
  root@darkstar_5:/tmp# installpkg xdebug-2.3.3-x86_64-1_SBo.txz

Configuration

The package is successfully installed. It is time to configure PHP in order for Xdebug to be correctly detected and loaded by the Zend engine. A line for the newly added extension and its parameters should be added in the /etc/httpd/php.ini configuration file. The line should include the exact location of the xdebug.so binary and its full path: /usr/lib64/php/extensions/xdebug.so for a 64 bit Slackware Linux system.

  ; StudioSG - Enable xdebug
  zend_extension="/usr/lib64/php/extensions/xdebug.so"
  ; StudioSG - Limit recursive calls to 10000 (Avoids starvation)
  xdebug.max_nesting_level = 10000
  ; StudioSG - Xdebug configuration end

In addition to the file location I set an upper limit to the number of times a script can be called while in a loop in order to avoid resource starvation and the resulting server issues.

The configuration is now concluded restart the web server to be able to use Xdebug. To check that the extension is loaded and running write a PHP page that calls function phpinfo() and load it in a web browser. An simple example of such a page is:


phpinfo.php: The page dumps the PHP and Zend engine configuration.

   <?php phpinfo(); ?>

If everything works fine a Xdebug dedicated configuration section will appear and its content will look similar to the example below:

xdebug
xdebug support enabled
Version 2.3.3
IDE Key root

There is yet another way to test for the extension to be successfully loaded and running: Invoke the php command to list all of its active modules:

  root@darkstar_5:~# php -m
  [PHP Modules]
  bcmath
  bz2
  calendar
  Core
  ctype
  curl
  date
  dba
  dom
  enchant
  ereg
  exif
  fileinfo
  filter
  ftp
  gd
  gettext
  gmp
  hash
  iconv
  imap
  intl
  json
  ldap
  libxml
  mbstring
  mcrypt
  mysql
  mysqli
  mysqlnd
  openssl
  pcntl
  pcre
  PDO
  pdo_mysql
  pdo_sqlite
  Phar
  posix
  pspell
  Reflection
  session
  shmop
  SimpleXML
  snmp
  soap
  sockets
  SPL
  sqlite3
  standard
  sysvmsg
  sysvsem
  sysvshm
  tokenizer
  wddx
  xdebug
  xml
  xmlreader
  xmlwriter
  xsl
  zip
  zlib
  
  [Zend Modules]
  Xdebug


Integrating Xdebug with Third Party Editors / IDEs

A base Xdebug installation may not seem much help for developers as it requires to update the source code adding extra lines to have PHP dump useful information when debugging errors. It would probably be preferable to execute unaltered code step by step: a common debugger feature available for many other programming languages. Actually Xdebug does export all of the needed information to follow code flow during execution, but it does not provide a standard environment to view it. The main advantage of Xdebug consists of the use of a standard debugging protocol, which allows to interface the debugging service to a multitude of third party developer tools through specific modules and plug-ins. It is therefore possible to add code debug and profiling functionality to your development environment of choice.

A list of supported clients that can be used to check and debug remote code is available in the Xdebug web site pages. The list includes plug-ins for Eclipse, Kdevelop, NetBeans and many more. Moreover a quick search of the web will provide extensions for Firefox / Seamonkey, Chrome and many other web browsers. If you'd prefer a stand alone program take a look at Pugdebug which is covered by an open source license and whose source code is freely available.

Some modules to extend text editor exist too. Not so striking graphically, but really helpful for debugging servers where, because of security or performance concerns, a graphical interface is often unavailable and command line tools represent your only choice. The Vim extension proved to be really useful whenever there was no way to use a graphic environment. Vim is one of the more widespread adopted text editors in Linux / Unix because of its versatility and nearly infinite feature list.

Xdebug - Vdebug Integration

Two plug-ins exist to integrate Xdebug and Vim. I'll use Vdebug: the newer one which essentially replaced the old Debugger. Vdebug is a multi-language debug client able to interface any debugger or language that uses the DBGP protocol. Among others:

  • NodeJS
  • Perl
  • PHP
  • Python
  • Ruby
  • Tcl

Vdebug requires a working Python language interpreter to function properly.

I'll describe the procedure to install Vdebug on a computer running Slackware Linux 14.1 below.

  • Download the latest available source code archive from the Vdebug git repository into a local directory. For example: /tmp.
  • Create directories doc, plugin, syntax and tests in the Vim root directory in your user home. Vim files are usually located in ~/.vim or $HOME/.vim:
  sviluppo@darkstar_5:~$ mkdir ~/.vim/doc
  sviluppo@darkstar_5:~$ mkdir ~/.vim/plugin
  sviluppo@darkstar_5:~$ mkdir ~/.vim/syntax
  sviluppo@darkstar_5:~$ mkdir ~/.vim/tests
  • Populate the newly created directories with files extracted from the install archive package (Please note: The actual file list varies between Vdebug releases therefore the one provided below could differ from yours).
  sviluppo@darkstar_5:~$ ls -la ~/.vim/*
  /home/sviluppo/.vim/doc:
  total 68
  drwxr-xr-x 2 sviluppo users  4096 Dec  5  2014 .
  drwxr-xr-x 6 sviluppo users  4096 Dec  5  2014 ..
  -rw-rw-r-- 1 sviluppo users 56210 May 15  2014 Vdebug.txt
  -rw-r--r-- 1 sviluppo users  3880 Dec  5  2014 tags
  
  /home/sviluppo/.vim/plugin:
  total 20
  drwxr-xr-x 3 sviluppo users 4096 Dec  5  2014 .
  drwxr-xr-x 6 sviluppo users 4096 Dec  5  2014 ..
  drwxr-xr-x 3 sviluppo users 4096 Feb 20  2014 python
  -rw-rw-r-- 1 sviluppo users 7158 May 15  2014 vdebug.vim
  
  /home/sviluppo/.vim/syntax:
  total 28
  drwxr-xr-x 2 sviluppo users 4096 Dec  5  2014 .
  drwxr-xr-x 6 sviluppo users 4096 Dec  5  2014 ..
  -rw-rw-r-- 1 sviluppo users  518 Oct 31  2012 debugger_breakpoint.vim
  -rw-rw-r-- 1 sviluppo users  541 Oct 31  2012 debugger_log.vim
  -rw-rw-r-- 1 sviluppo users  637 Oct 31  2012 debugger_stack.vim
  -rw-rw-r-- 1 sviluppo users  720 Oct 31  2012 debugger_status.vim
  -rw-rw-r-- 1 sviluppo users 1574 Nov 11  2013 debugger_watch.vim
  
  /home/sviluppo/.vim/tests:
  total 144
  drwxr-xr-x 2 sviluppo users  4096 Nov 11  2013 .
  drwxr-xr-x 6 sviluppo users  4096 Dec  5  2014 ..
  -rw-rw-r-- 1 sviluppo users   299 May  9  2013 helper.pyc
  -rw-rw-r-- 1 sviluppo users  7376 May  9  2013 test_breakpoint_breakpoint.py
  -rw-rw-r-- 1 sviluppo users 10691 May  9  2013 test_breakpoint_breakpoint.pyc
  -rw-rw-r-- 1 sviluppo users  7336 May  9  2013 test_dbgp_api.py
  -rw-rw-r-- 1 sviluppo users  9267 May  9  2013 test_dbgp_api.pyc
  -rw-rw-r-- 1 sviluppo users  2354 May  9  2013 test_dbgp_connection.py
  -rw-rw-r-- 1 sviluppo users  3821 May  9  2013 test_dbgp_connection.pyc
  -rw-rw-r-- 1 sviluppo users  5822 May  9  2013 test_dbgp_context_property.py
  -rw-rw-r-- 1 sviluppo users  7104 May  9  2013 test_dbgp_context_property.pyc
  -rw-rw-r-- 1 sviluppo users  9134 May  9  2013 test_dbgp_response.py
  -rw-rw-r-- 1 sviluppo users 12156 May  9  2013 test_dbgp_response.pyc
  -rw-rw-r-- 1 sviluppo users  1349 May  9  2013 test_opts_options.py
  -rw-rw-r-- 1 sviluppo users  3030 May  9  2013 test_opts_options.pyc
  -rw-rw-r-- 1 sviluppo users  9517 May  9  2013 test_ui_vimui_api.pyc
  -rw-rw-r-- 1 sviluppo users  4708 Nov 11  2013 test_util_filepath.py
  -rw-rw-r-- 1 sviluppo users  7186 Nov 11  2013 test_util_filepath.pyc
  -rw-rw-r-- 1 sviluppo users    25 Oct 31  2012 vim.py
  -rw-rw-r-- 1 sviluppo users   314 May  9  2013 vim.pyc
  • Create tags needed by the Vdebug documentation:
  sviluppo@darkstar_5:~$ vim
     :helptags $HOME/.vim/doc
  • Update the php.ini configuration file adding some lines:
  ; StudioSG - Add support for the vim debugger plug-in
  xdebug.remote_enable = on
  xdebug.remote_host = localhost
  xdebug.remote_port = 9000
  xdebug.remote_handler = dbgp
  ; StudioSG - vim debugger configuration end
  • restart the web server.

It will be possible to debug PHP scripts immediately after daemon restart.

Using Vim / Vdebug

The last part of this article about Xdebug will be devoted to describing the few easy steps required to start and execute a debugging session of a PHP script file. Some images were included to better explain the main steps. The images refer to the interface of gVim, the Vim GUI. GVim was used in place of plain Vim in order to take advantage of its wider window.

  • Open with Vim the file targeted for debug.
It is possible to pass the file name as a parameter in the command line:
     vim <path>/<file>
Or to start Vim then use the :e <path>/<file_name> command to load the file from within the editor interface.
  • Set a break point, that is a line of code where the execution will come to a halt and the debugging session will start.
Vdebug provides a new command to Vim: :Breakpoint

 

  • Start a web browser and load the URL of the desired page.
  • Add variable XDEBUG_SESSION_START=1 to the URL.
A simple example: http://example.com/index.php?XDEBUG_SESSION_START=1
A more complex example with an URL made of more than one variable: http://example.com/index.php?pg=11&XDEBUG_SESSION_START=1
  • Return to the Vim window and press F5.

 

  • Reload the URL within 20 seconds and the debug session will automatically start.

 

  • Return to the Vim window and press F4 to execute code till the first available break point is encountered.

 

The Vim window will be split in two columns. The left column shows the script source code and manages navigation commands. The right column is divided in boxes showing the local variables values, a list of open files in the order they were opened by the script and some more useful information that will help you decipher code behavior.
  • Press F2 to execute code and go to the next line. Note that when the line of code includes a function the function is evaluated, but its code will not be shown. Use the F3 key to follow program flow in and out of functions.
  • To dump the value of a variable move the cursor on it then press key F12

 

  • Once concluded you can exit debug mode pressing the F6 key.

Appendix - Vdebug Commands

The table below contains some common Vdebug commands. The list is incomplete, but the included commands are enough to perform a full debug session. Please read the official documentation for a full description of Vdebug features and commands.

Vdebug - Commands
Command Description
F2 Step forward
F3 Step in (Shows function source code)
F4 Step out
F5 Start debugging
F6 Stop debugging
F7 Detach script from debugger
F9 Go to cursor
F10 Toggle break point
F11 Dump environment variables
F12 Dump variable under cursor
:Breakpoint <type> <args> Add a break point
:help VdebugBreakpoints for more information
:VdebugEval Execute code and return results
<Leader>e Execute highlighted expression and return results
:VdebugOpt debug_file <file> Set a log file
:VdebugOpt debug_file_level 2 Set log verbosity


Conclusions

The procedure to install Xdebug on a Slackware Linux host was described in this paper. Then step by step installation instructions for Vdebug, a Vim extension enabling the text editor to interface with Xdebug, were provided and finally an example of a debug session was executed to show how Vim and Xdebug work together. The 5.6 release of PHP introduced a long awaited native debugger; its features and differences with Xdebug will be the subject of a later article.


For any feedback, questions, errors and such, please e-mail me at studiosg [at] giustetti [dot] net


External links





Languages: English - Italiano