sidkshatriya / dontbug
- среда, 12 октября 2016 г. в 03:12:31
Go
Dontbug is a reverse debugger for PHP
Dontbug is a reverse debugger for PHP. It allows you to record the execution of PHP scripts (in command line mode or in the browser) and replay the same execution back in a PHP IDE debugger. During replay you may debug normally (forward mode debugging) or in reverse, which allows you to step over/out backwards, step backwards, run backwards, run to cursor backwards, set breakpoints in the past and so forth.
Debugging with the ability to run in reverse allows you to hunt down bugs much more easily. It also allows you to understand the runtime behavior of large PHP codebases more efficiently.
rand()/time()
etc. as during record. (However, PHP will not write/read to the network or database a second time during replay)Since Dontbug replays a saved PHP script execution trace, you cannot persistently modify a variable value in the debugger. All variables (and "state") in the PHP script is read-only. This limitation is fundamental in the current record/replay architecture. In practice, this is not such a big limitation as changing variable values while debugging is rarely needed.
Dontbug is pre-alpha quality. It works but is a bit rough around the edges. Please report any problems you encounter. Dontbug also does not have advanced debugging features like breaking on named exceptions, breaking on call to/return from a specifically named function, conditional breakpoints[*], watches etc. at the moment. Some of these are planned for future releases.
[*] You can always emulate conditional breakpoints by adding an if
statement for the breakpoint condition and a line breakpoint inside the if
statement.
dontbug record
dontbug replay
dontbug record
) to the IDESee below for more details.
See Installation Instructions on installing Dontbug on your machine.
If you're interested in how the Dontbug debugger works internally please read this document.
Standing on the shoulders of giants
Most open source projects are built with the help of other open source projects and Dontbug is no exception.
The Mozilla/RR, Xdebug and GDB projects are the most important open source projects that Dontbug depends on. The existence of these fantastic open source projects has allowed Dontbug to be built. The roles and contributions of these projects to the overall functionality of Dontbug is outlined in the "How the Dontbug Debugger works" document.
The Dontbug executable has been programmed in the golang programming language. It uses a number of open source golang libraries. Please consult the source code to know the specific ones used.
Dontbug is Copyright © 2016 Sidharth Kshatriya. Dontbug is licensed under the terms of the Apache License (Version 2.0).
Once you have installed dontbug
you have two commands available:
dontbug record
dontbug replay
See dontbug record --help
or dontbug replay --help
for more information or continue reading.
dontbug record
The dontbug record
command records the execution of PHP scripts in the PHP built-in webserver or in the PHP command line interpreter. This is used for later forward/reverse debugging in a PHP IDE. A typical workflow is to do a dontbug record
followed by dontbug replay
.
dontbug record <php-source-root-dir> [<docroot-dir>] [flags]
dontbug record <php-source-root-dir> <php-script> --php-cli-script [args-in-quotes] [flags]
dontbug record /var/www/fancy-site docroot
dontbug record /var/www/another-site
dontbug record ~/php-test/ list-supported-functions.php --php-cli-script
dontbug record ~/php-test/ math/calculate-factorial-min-max.php --php-cli-script --args "10 20"
The first example will spawn the PHP built-in webserver for recording the execution of "fancy-site" website (as the user navigates various URLs in a browser). The docroot of the fancy site will be /var/www/fancy-site/docroot
and the <php-source-dir>
will be /var/www/fancy-site
.
In general, dontbug will be able to handle any PHP framework/CMS as long you meet its minimum requirements and the framework/CMS runs in PHP's built in webserver (most of them should). Here the PHP built in webserver is substituting for Apache, Nginx etc.
The second example is like the first. Here the <docroot-dir>
is assumed to be the same as the <php-source-root-dir>
.
The third example will record the execution of ~/php-test/list-supported-functions.php
The fourth example will record the execution of a PHP script with two arguments 10 and 20 passed to it. Note the quotes to enclose the arguments. The script's full path is ~/php-test/math/calculate-factorial-min-max.php
.
As you have seen if you specify <docroot-dir>
or <php-script>
then it should specified as a relative path w.r.t to the <php-source-root-dir>
.
The <php-source-root-dir>
means the outermost directory of all possible PHP scripts that might be executed in this project by PHP sources in this project.
<php-source-root-dir>
would be the docroot in your PHP project or, sometimes its parent folder. <php-source-root-dir>
is not the same as <docroot-dir>
, sometimes, as scripts might be placed outside the docroot in some PHP projects e.g. vendor scripts installed by composer. Please keep this directory as specific as possible. For example, you could specify "/" (the root directory) as <php-source-root-dir>
as it contains all the possible PHP scripts on your system. But this would impact performance hugely.<php-source-root-dir>
to outside that dir, dontbug should be able to handle that (without you having to increase the scope of the <php-source-root-dir>
)You may record as many http page loads for later debugging when running the PHP built in webserver (unlike traditional PHP debugging which is usually one page load at a time). However be aware that recording too many page loads may degrade performance during debugging. Additionally, you may not pass arguments to the PHP built in server i.e. the --args
flag is ignored if not used in conjunction with --php-cli-script
.
If you find that you are frequently passing the same flags to dontbug
, you may provide custom config for various flags in a $HOME/.dontbug.yaml
file. Sample file:
server-port: 8003
install-location: /some-path/src/github.com/sidkshatriya/dontbug
Most of the parameters defaults should suffice and you will typically need a very minimal .dontbug.yaml
config file.
Flags passed via command line will always override any configuration in a .yaml
file. If the .yaml
file and user flags don't specify a particular parameter, the defaults mentioned in dontbug record --help
will apply.
See dontbug record --help
for more information on the various flags available for more customization options
dontbug replay
The dontbug replay
command replays a previously saved execution trace to a PHP IDE debugger. You may set breakpoints, step through code, inspect variable values etc. as you are used to. But more interestingly, dontbug allows you to reverse debug i.e. step over backwards, run backwards, hit breakpoints when running in reverse and so forth.
dontbug communicates with PHP IDEs by using the dbgp protocol which is the defacto standard for PHP IDEs so no special support is required for dontbug to work with them. As far as the IDEs are concerned they are talking with a normal PHP debug engine.
dontbug record
(see dontbug record --help
to know how to do this)dontbug replay
dontbug record
) to the IDESome PHP IDEs will try to open a browser window when they start listening for debug connections. Let them do that. The URL they access in the browser is likely to result in an error anyways. Ignore the error. This has absolutely no effect on dontbug as we're replaying a previously saved execution trace but the IDE does not know that.
The only important thing is to look for a message in green "dontbug: Connected to PHP IDE debugger" on the dontbug prompt. Once you see this message, you can start debugging in your PHP IDE as you normally would. Except you now have the ability to run in reverse when you want.
Remember that replays are frozen in time. If you change your PHP code after a replay, you will need to do dontbug record
again. If you don't do that dontbug replay
will replay a PHP execution corresponding to an earlier version of the source code while your PHP IDE will show the current PHP source code! This can lead to a lot of confusion (and weird behavior) as you may imagine.
Essentially, you need make sure that your PHP sources are not newer than the last recording. If they are, you should simply dontbug record
again. There is an advanced/experimental flag --take-snapshot
(see dontbug record --help
) which allows you to record an execution and take a source code snapshot so that the above issue can be dealt with in a more principled way. However, this feature is not fully documented yet and increases the complexity of your workflow. Therefore: simply do a dontbug record
again if your PHP sources have changed since the last recording!
See dontbug replay --help
for more information on the various flags available for more customization options
Upon running dontbug replay
you have a prompt available in which you can switch between forward and reverse modes. This prompt also has help. Press h
followed by <enter>
to get help.
(dontbug) h
h display this help text
q quit
r debug in reverse mode
f debug in forward (normal) mode
t toggle between reverse and forward modes
v toggle between verbose and quiet modes
n toggle between showing and not showing gdb notifications
<enter> will tell you whether you are in forward or reverse mode
The buttons in your PHP IDE debugger will have the following new (and opposite) meanings in reverse debugging mode: