Upload
ian-barber
View
6.766
Download
1
Tags:
Embed Size (px)
DESCRIPTION
Finding and fixing bugs is a major chunk of any developers time. This talk describes the basic rules for effective debugging in any language, but shows how the tools available in PHP can be used to find and fix even the most elusive error
Citation preview
DEBUGGINGR U L E S A N D T O O L Sian barber - http://phpir.com - @ianbarber
I did XI wanted YInstead I got Z
http://www.debuggingrules.com
UNDERSTAND THE SYSTEM
RULE 1
RTFM
Framework
Wiki
PHPDoc
php.net
BugTracker
$field = $document->getField($fieldName);
if ($field->storeTermVector) { /** * @todo term vector storing support */ require_once 'Zend/Search/Lucene/Exception.php'; throw new Zend_Search_Lucene_Exception ('Store term vector functionality is not supported yet.');}
TOOLS
Komodo
Eclipse Zend Studio
NetBeans
PHPStorm Text
Mate
MAKE IT FAIL
RULE 2
Recreate And AutomatePHP UnitSimpleTestSeleniumPHP SlimJMeterAb
CONTROL VARIABLES
LoadTime
DBStateSession
Request
ServerEnv
User
Client
Timing
class Test_User extends PHPUnit_Framework_TestCase {
public function testUpdate() { $r = ("a", "b"); try { $u = User::fetch($this->newName); $result = $u->update($r); } catch (Id_Exception $e) { $this->fail($e->getMessage()); } $this->assertEquals($r, $u->getRoles()); } }
[root@localhost ~]# pear channel-discover pear.phpunit.de[root@localhost ~]# pear install phpunit/PHPUnit
class Example extends PHPUnit_Extensions_SeleniumTestCase { protected function setUp() { $this->setBrowser("*chrome"); $this->setBrowserUrl("http://general.dev/"); }
public function testMyTestCase() { $this->open("/"); $this->select("locale", "label=de"); $this->waitForPageToLoad("30000"); $this->assertTrue($this->isTextPresent( "Datenbank-Einrichtung")); }}
http://jakarta.apache.org/jmeter/
QUIT THINKINGAND LOOK
RULE 3
if($this->hasRoles) { $this->deleteRoles(); }
try { foreach($submittedRoles as $role) { $this->addRole($role); } } catch(Identity_Exception $e) { $this->log->warn('Role add failed.'); throw new Service_Exception_BadRequest( 'Cannot add user role'); }
Instrumentation:Inspect or Report
Xdebughttp://www.xdebug.org
[root@localhost ~]# pecl install xdebug
zend_extension=/usr/lib64/php/modules/xdebug.so
xdebug.profiler_enable=1 xdebug.profiler_output_dir=/tmp
xdebug.auto_trace=1 xdebug.collect_params=4
Key
Key
Debugging Commands
Web Server
PHP Script
XDebugDebugging Client
xdebug.remote_enable=1 xdebug.remote_port=9000 xdebug.remote_host=192.168.192.1 #xdebug.remote_connect_back=1
[root@localhost ~]# lsof -p 4365 COMMAND USER FD TYPE DEVICE NAME httpd apache mem REG 253,0 /lib64/libssl.so.0.9.8e httpd apache mem REG 253,0 /usr/lib64/php/modules/xdebug.so httpd apache mem REG 253,0 /usr/lib64/libsqlite3.so.0.8.6
[root@localhost ~]# strace -cp 4365 Process 6910 attached - interrupt to quit Process 6910 detached % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ------------- 36.91 0.037307 466 80 getdents 30.07 0.030393 950 32 7 access 17.04 0.017224 154 112 10 open 5.08 0.005136 12 444 9 lstat 3.87 0.003910 18 213 1 read 3.04 0.003071 29 107 close 2.57 0.002598 1299 2 writev 0.78 0.000785 1 631 stat
[root@localhost ~]# strace -Tp 4365 Process 6910 attached - interrupt to quit epoll_wait(16, {{EPOLLIN, {u32=31389672, u64=47128707528680}}}, 2, 10000) = 1 <6.926140> accept(4, {sa_family=AF_INET6, sin6_port=htons(64930), inet_pton (AF_INET6, "::ffff:192.168.192.1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [47128676139036]) = 17 <0.000094> fcntl(17, F_SETFL, O_RDWR|O_NONBLOCK) = 0 <0.000035> read(17, "POST / HTTP/1.1\r\nHost: general.d"..., 8000) = 522 <0.000044> stat("/mnt/hgfs/habari/htdocs/", {st_mode=S_IFDIR|0755, st_size=408, ...}) = 0 <0.000527> open("/mnt/hgfs/habari/htdocs/.htaccess", O_RDONLY) = 18 <0.000457> fcntl(17, F_SETFL, O_RDWR|O_NONBLOCK) = 0 <0.000037>
[root@localhost ~]# strace -Tp 4365 Process 6910 attached - interrupt to quit epoll_wait(16, {{EPOLLIN, {u32=31389672, u64=47128707528680}}}, 2, 10000) = 1 <6.926140> accept(4, {sa_family=AF_INET6, sin6_port=htons(64930), inet_pton (AF_INET6, "::ffff:192.168.192.1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [47128676139036]) = 17 <0.000094> fcntl(17, F_SETFL, O_RDWR|O_NONBLOCK) = 0 <0.000035>
read(17, "POST / HTTP/1.1\r\nHost: general.d"..., 8000) = 522 <0.000044> stat("/mnt/hgfs/habari/htdocs/", {st_mode=S_IFDIR|0755, st_size=408, ...}) = 0 <0.000527>
open("/mnt/hgfs/habari/htdocs/.htaccess", O_RDONLY) = 18 <0.000457>
error_log("Message for the PHP log") error_log("Log to email", 1, "[email protected]"); error_log("Log to a file",3, "/tmp/m.log"); error_log("Message for the SAPI log", 4);
ZendLog
sfLogger
Drupalsyslog
KohanaLog
LOGGING SYSTEM
SyslogMQ File
Database PipeGearman
FirePHP
[root@localhost ~]# pear channel-discover pear.firephp.org [root@localhost ~]# pear install firephp/FirePHPCore
require_once('FirePHPCore/FirePHP.class.php'); ob_start(); $firephp = FirePHP::getInstance(true); doStuff($firephp); $firephp->warn('Done Stuff'); $firephp->error('An error!'); $firephp->log($_GET); ob_end_flush();
function doStuff($firephp) { $firephp->trace('Stuff Backtrace'); echo "This page intentionally blank"; }
DIVIDE ANDCONQUER
RULE 4
<?xml version="1.0" encoding="UTF-8"?><phpunit bootstrap="./TestHelper.php" colors="true"> <testsuite name="Commonlib Tests"> <directory>./library/Cl/</directory> <directory>./library/Sso/</directory> </testsuite><filter> <whitelist> <directory suffix=".php">../Sso/</directory> <directory suffix=".php">../Cl/</directory></whitelist></filter></phpunit>
Folder Root
SSOCL
Model UserAuth Client
PluginAdapter Exception Abstract
GearmanSFDCSSO
<?php
$worker = new GearmanWorker(); $worker->addServer(); $worker->addFunction( "allow_access", "allowAccess"); $worker->addFunction( "deny_access", "denyAccess");
while ($worker->work());
git bisect start git bisect bad git bisect good <known good rev>
git bisect ?
git bisect reset
Git Bisect
Request
Front Controller
InputFilter
Controller
Model
Plugin
View1
2
3
good bad
Firewall
Cache
Web Server
Database
Firewall
Cache
Web Server
Database
Wireshark
Curl
Netcat
MySQLProxy
Tamper Data
Xdebug
Tamper Datahttps://addons.mozilla.org/firefox/addon/966
[root@localhost ~]# { echo -ne "HTTP/1.0 200 OK\r\n \r\n"; cat test.html; } | nc -l 8080 GET / HTTP/1.1 User-Agent: curl/7.19.7 (i386-apple-darwin10.0.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3 Host: general.dev:8080 Accept: */*
[root@localhost ~]# curl http://general.dev:8080 -v * About to connect() to general.dev port 8080 (#0) * Trying 192.168.192.129... connected * Connected to general.dev (192.168.192.129) port 8080 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.19.7 (i386-apple-darwin10.0.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3 > Host: general.dev:8080
MySQL Proxy
local log_file = 'mysql.log' local fh = io.open(log_file, "a+")
function read_query( packet ) if string.byte(packet) == proxy.COM_QUERY then local query = string.sub(packet, 2) fh:write( string.format("%s\n",query)) fh:flush() end end
CHANGE ONETHING ATA TIME
RULE 5
Source Control
[root@localhost ~]#: svn stM index.php
[root@localhost ~]#: git stash saveSaved working directory and index state WIP on master: 0e22fdd Initial checkinHEAD is now at 0e22fdd Initial checkin
[root@localhost ~]#: git status# On branch masternothing to commit (working directory clean)
Source Control
[root@localhost ~]#: svn log . ------------------------------------------- r4341 | rickc | 2010-09-24 03:01 | 3 lines
Don't test if Post::tags is empty before getting tags. There may be a performance hit for this. It can be dealt with if it is noticable. Fixes ticket #1235. Props to ilo for the patch.
Note that Post still needs to be updated to use real Tags, not an array of slug/label pairs as the tags member.--------------------------------------------
Known Good
[root@localhost ~]# diff -yw web.conf web2.conf <VirtualHost *:80> <VirtualHost *:80> ServerAdmin [email protected] ServerAdmin [email protected] DocumentRoot /www/htdocs | DocumentRoot /www/hdocs ServerName general.dev ServerName general.dev ErrorLog logs/error_log ErrorLog logs/error_log</VirtualHost> </VirtualHost>
KEEP ANAUDIT TRAIL
RULE 6
Hot Key Loghttp://www.blacktree.com/
http://simplenoteapp.com/https://launchpad.net/mbhttp://do.davebsd.com/
[root@localhost htdocs]# history 20 365 ls /mnt/hgfs/habari/ 366 ls 367 vi /etc/httpd/conf.d/web.conf 368 setenforce 0 369 /etc/init.d/httpd restart 370 vi /var/log/httpd/error_log 371 cd /mnt/hgfs/habari/ 372 ls 373 cd htdocs/ 374 ls 375 cd scripts/ 376 ls 377 cd .. 378 ls 379 vi /etc/php.ini
CHECK THE PLUG
RULE 7
[root@localhost ~]# apachectl -M Loaded Modules: core_module (static) mpm_prefork_module (static) http_module (static) so_module (static) auth_basic_module (shared) auth_digest_module (shared) authn_file_module (shared) authn_alias_module (shared) authn_anon_module (shared) authn_dbm_module (shared) authn_default_module (shared) authz_host_module (shared) authz_user_module (shared)
Sources of Plugs
[root@localhost ~]# whoami root [root@localhost ~]# ifconfig eth0 Link encap:Ethernet HWaddr 00:0C:29:E8:03:F1 inet addr:192.168.192.129 Bcast:192.168.192.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:fee8:3f1/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:189820 errors:0 dropped:0 overruns:0 frame:0 TX packets:117261 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:83583857 (79.7 MiB) TX bytes:24261778 (23.1 MiB)
GET A FRESHVIEW
RULE 8
if(!is_string($i)) { throw new Xapian_Exception('Incorrect query type, expecting string or array of strings'); }
$q = $this->getParser()->parse_query($i);
if(!is_string($i)) { throw new Xapian_Exception('Incorrect query type, expecting string or array of strings'); }
$q = $this->getParser()->parse_query($i, FLAG_SPELLING_CORRECTION);
“Grovelling is not a substitute for doing your homework” - ESR
http://www.catb.org/esr/faqs/smart-questions.html
IF YOU DIDN’T FIX IT -IT AIN’T FIXED
RULE 9
Five Whys
The page is blank: Why?There is a fatal error : Why?
No mb_check_encoding(): Why?mbstring is not installed: Why?It isn’t part of the build: Why?
It was setup for another project.
The Rules1. Understand The System2. Make It Fail3. Quit Thinking And Look4. Divide And Conquer5. Change One Thing At A Time6. Keep An Audit Trail7. Check The Plug8. Get A Fresh View9. If You Didn’t Fix It, It Ain’t Fixed
?Questions
When men were men and wore white coats - by Jitzehttp://www.flickr.com/photos/jitze1942/4292084185/Vacuum Tube Etch-A-Sketch - by Jurvetsonhttp://www.flickr.com/photos/jurvetson/197768962/Classic - by Oskayhttp://www.flickr.com/photos/oskay/1364147095Firmware Bug - by Oskayhttp://www.flickr.com/photos/oskay/1364148351Ready to hop - by Oskayhttp://www.flickr.com/photos/oskay/1364153441/Albino - by Oskayhttp://www.flickr.com/photos/oskay/1364143833Coming Through! - by Oskayhttp://www.flickr.com/photos/oskay/1364147807Tux the Pinguin - by Patrick van der VeldenFrom the photographer’s private collection
Image Credits