The third part in the Introspective debugger code breakdown, Lets look at what happens when the code actually stops at a breakpoint…
The first chunk of code uses some globals and the backtrace to figure out if it should actually stop or just keep going I will break this down in detail later, when I go over the breakpoint code
function idbg_tick_function(){
global $idbg_stop_flag, $idbg_id, $idbg_var_spy, $idbg_last_line, $idbg_backtrace; $idbg_backtrace = debug_backtrace();
// echo ($idbg_last_line. ” ?= ” .$idbg_backtrace[0][‘line’] .” in “.$idbg_backtrace[0][‘file’].”<Br/>” );
if($idbg_stop_flag and $idbg_last_line != $idbg_backtrace[0][‘line’] and !strpos($idbg_backtrace[0][‘file’], ‘STOP.php’))
{ //echo(“</hr> idbg_tick_function START <br/>”);Next Up We open up a tcp server on the socket of our ID, which will always be a high port. $socket = stream_socket_server(“tcp://”.$_SERVER[“REMOTE_ADDR”].”:$idbg_id”, $errno, $errstr); if (!$socket) { echo “<h1>Debugger couldn’t open socket: $errstr ($errno)<h1/>\n”;} else { because, its what they did in the example code for opening sockets, we read using a while string.I’m pretty sure that when you open the socket your thread sleeps until there is a connection to it anyway, so this is fine.When it does get a connection, we read the first 1024 bites that got sent to it, and store them in msgIn, This is going to tell us what sort of information is being looked for while ($conn = stream_socket_accept($socket)) { $msgIn = fread($conn, 1024); echo($msgIn);
The flush call is pretty important for this, it makes sure that the version of the page that the users are looking atis up to date (and not being stashed away in the buffer)
flush();For command and control we just send back a serialized version of the backtrace, and our spied variables. Much more onvariable spying in a later post (Code in RED is from a different chunk of code, its basically the other end of the conversation)
if ($msgIn == ‘cnc’){ fwrite($conn, serialize(array(“trace”=>$idbg_backtrace,”vars” => $idbg_var_spy))); $responce = unserialize(idbg_socket_client(“cnc”));<font color="#990000"> foreach($responce["trace"] as $key => $val){ echo("<a href='".$callBackName."file&idbg_open_line=".$val['line']. "&idbg_open=".$val['file']."#anchor' target='infoframe'>".strrchr($val['file'],"/")."</a>"); echo(" Line:". $val['line'] . " Function:" . $responce["trace"][$key+1]["function"]. " <a href='#' onClick=\"document.getElementById('v_$key').style.display='block'\">+</a> <div id='v_$key' style='display:none'><pre>"); print_r($responce["vars"][$responce["trace"][$key+1]["function"]]); echo("</pre></div><hr/>"); </font> }
If the message is step, then we return, so the program keeps running, but we don't turn off the "STOP" flags,we also update the "last line" so that we don't end up hitting the same line over and over. } else if ($msgIn == 'step'){ fclose($conn); fclose($socket); $idbg_last_line = $idbg_backtrace[0]['line']; return(TRUE);If the message is cont, then we turn off the "STOP" flags, and then we go on further } else if ($msgIn == 'cont'){ // fwrite($conn, "ACK"); fclose($conn); fclose($socket); $idbg_last_line = 0; $idbg_stop_flag = FALSE; return(TRUE);If we didn't get a command that we know about, send back a generic message, just showing that we heard them.Regardless after this we are going to close down the connection, and then the socket. We also susspended error messaging while we were in the debug code, so we will re-enable it before exiting. } else { fwrite($conn, " This is a SERVER Responce \n"); } fclose($conn); } fclose($socket); } }}//else just keep goingerror_reporting($old_error_level);