Effective debugging

Post on 28-Nov-2014

831 views 1 download

description

Oh dear, your application has suddenly stopped working as expected. What should you do now? Using techniques applicable to any php application, we'll go over what to look for and which problems to avoid when trying to determine where the problem lies. We'll show how to correctly identify and deal with problems including: * network connectivity * server config issues * php config * WSOD * common CakePHP application errors

Transcript of Effective debugging

EFFECTIVE DEBUGGINGSPEND TIME FIXING PROBLEMS, NOT FINDING THEM

/ Andy Dawson @AD7six

OF COURSE IT'S NOT REALLY THAT SIMPLE

Image: Flickr.com

↖ The hardest problems to fix exist here. In the developer's head.

FIND IT WITH A HAMMER

Image: Codinghorror.com

// pick one throw new \Exception('Made it here!'); print_r(debug_backtrace()); die(__FILE__ . ':' . __LINE__);

MOST APPS AREN'T THAT SIMPLEA hammer will work, but it might take a while.

Image: energysystemsgroup.com

HELLO WORLD EXAMPLE"Where's my webpage"

CHECK THE HTTP RESPONSE CODEIs it actually an error?

READ THE WEBSERVER ERROR LOGLocation depends on configuration

Typically /var/log/*/PHP Parse error: [...] in /var/www/example.dev/public/index.php on line 4"

IDENTIFY THE PROBLEM

$ cat /var/www/example.dev/public/index.php <?php

echo "hello world';

Parse errors are often the line before (or earlier) in a file

NOT AN ERROR EXAMPLENot an error response code so no (direct) log messages:"

GREP FOR IT $ grep -rl "Not Found" * ... src/Really/Not/Obvious/File.php

$ grep -r "Not Found" * ... src/Really/Not/Obvious/File.php 404 => 'Not Found',

$ cat src/Really/Not/Obvious/File.php

... function error() { die($this->_statusCodes['404']); }

CAKEPHP HELLO WORLD EXAMPLE"Why the Four Oh Four?"

CHECK THE ERROR LOGapp/tmp/error.log

IDENTIFY THE PROBLEM $ cat app/View/Pages/home.ctp <?php ... if (!Configure::read('debug')): throw new NotFoundException(); endif;

DEBUG BASICSConfig and functions every developer should know about

PHP CONFIGIni file settings are the defaults if not changed (duh)

display_errors (On/Off)log_errors (On)display_startup_errors (Off)error_reporting (On/Off)

Runtime settings override the ini file - no effect if the file they arein has a parse error (duh)

ini_set('display_errors', 0/1)

PHP FUNCTIONSprint_r();debug_backtrace();get_included_files();phpinfo();

PHP VARIABLES/CONSTANTS__FILE____LINE__$_SERVERet.al.

A WAY TO REPRODUCEHave a way to consistently reproduce the error

$ curl -I http://example.dev/ HTTP/1.1 500 Internal Server Error Server: nginx Date: Sat, 23 Aug 2014 10:33:46 GMT Content-Type: text/html

git bisect - find regression errors quickly

XDEBUGpecl install xdebug

WEBGRINDTurn on xdebug profiling, and look at what a request is doing

CLI DEBUGGINGPause execution with read:

print_r($somethingInteresting); read foo;

Useful when debugging a loop.

NOT CAKEPHP CODE?A ghetto debug function:

function debug ($var, $showHtml = null) { if (!defined('DEBUG') || !DEBUG) { return; }

if ($showHtml === null) { $showHtml = php_sapi_name() === 'cli' ? false : true; } $var = var_export($var, true); if (!$showHtml) { echo $var; return; }

echo '<pre>' . htmlspecialchars($var) . '</pre>'; }

create a trace function (Debugger::trace) too if needed

LOGIC AIDESJust voicing a problem can find the solution/error

Image: Wikipedia

ERROR MESSAGES DON'T LIEPHP Parse error: syntax error, unexpected '$bar' (T_VARIABLE)

in parse.php on line 3 $ cat foo.php <?php ... if ($foo || bar) {

There's an accidental none-breaking space on that line

NETWORKING PROBLEMSIf the problem is not on the webserver - where is it?

NAMESERVER PROBLEMSNo response from nameservers is the same as a domain not

existsing $ dig cakefest.org

; <<>> DiG 9.8.3-P1 <<>> cakefest.org ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 15266 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION: ;cakefest.org. IN A

;; Query time: 4142 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Tue Aug 19 16:26:59 2014 ;; MSG SIZE rcvd: 30

... ;; ANSWER SECTION: cakefest.org. 1568 IN A 50.56.232.22 ...

DNS PROBLEMS"No route to host" means the ip requested isn't accessible $ traceroute cakefest.org

traceroute to cakefest.org (50.56.232.22), 64 hops max, 52 byte packets 1 172.26.81.1 (172.26.81.1) 1.032 ms 0.912 ms 0.912 ms 2 192.168.0.1 (192.168.0.1) 2.777 ms 1.267 ms 2.338 ms ... 12 rackspace-ic-302090-dls-bb1.c.telia.net (62.115.33.78) 152.340 ms 159.367 ms 146.339 ms 13 * * * 14 * * * 15 * * *

If there are stars - there be problems

BACKEND SERVER ISDOWN

502 Bad Gateway

E.g. php-fpm or hhvm is not runningWill be in the webserver error logThere will not be any application log entries

PITFALLS TO AVOIDWhat not to do when debugging code

FIX PROBLEMS, NOT SYMPTOMSDon't ignore errors/warnings/notices

Fix them in order, some errors will be the concequence of earlierproblems.

COMMON MISTAKESNot looking for error logsReading or focussing on the wrong error messageNot reading the error messageNot reading the error message aloudMisinterpretting the error messageStopping debugging too early.

If "the problem" is a class/function with source code - debug thesource code of that function

New user: I found the problem, it'sapp/webroot/index.php!

IMPLICIT ASSUMPTIONSBe wary of implict assumptions

You're debugging the same file the browser is loadingYou're debugging the same application the browser is loadingYou're debugging the same server the browser is loadingYou're debugging the same request the browser is loadingConclusions so far are accurate

WTF? Backup, and re-verify everything.

COMMON PROBLEMSAnd how to debug/identify them

NO MODREWRITE

Don't look at php files - the error is at the webserver.

Enable mod rewriteRestart the webserver

CAKEPHP AUTOMODELS

$model = ClassRegistry::init('MyModel'); $model->methodName();

SQL Error: 1064: You have an error in your SQL syntax; [...]

check [...] for the right syntax to use near 'methodName'

MyModel does not have the function methodNameMyModel has no behaviour bound implementingmethodName$model is an instance of AppModel

CAKEPHP AUTOMODELS - IDENTIFICATION

$model = ClassRegistry::init('MyModel'); debug(get_class($model)); ########## DEBUG ########## 'MyModel' ###########################

$model = ClassRegistry::init('MyModel'); debug(get_included_files()); ########## DEBUG ########## array( ... ...app/Model/MyModel.php ... ) ###########################

CAN'T FIX IT(╯°□°)╯︵ ┻━┻

Can't find the problem/solution? - get help. But first:

Collect the information you've gotWrite a standalone, reproducible example if possibleReduce the question to it's simplest, formDon't over simplify or make a contrived exampleAsk colleagues/the internetBrace for impactStack overflow, the google group and irc as great places to gethelp

SUMMARYIdentify the right part of a request to debugFix errors in orderCheck your assumptions/conclusions at every WTFFormulate a question, and Ask for help

Profit!