$30 off During Our Annual Pro Sale. View Details »

DBGpを使って
PHPのデバッガーをつくろう / DGBp PHP Debugger

tzmfreedom
April 09, 2022

DBGpを使って
PHPのデバッガーをつくろう / DGBp PHP Debugger

tzmfreedom

April 09, 2022
Tweet

More Decks by tzmfreedom

Other Decks in Technology

Transcript

  1. σόοΨ͔ΒίϚϯυΛૹ৴ breakpoint_set -i 2 -t line -f /path/to/file -n 14

    w JΦϓγϣϯͰτϥϯβΫγϣϯ*%ʹҰҙͳ਺ࣈΛࢦఆ w Ұҙͳ਺ࣈΛࢦఆ͢Ε͹ྑ͍ͷͰ࿈൪Ͱ0, w Ϩεϙϯεʹ΋τϥϯβΫγϣϯ*%ؚ͕·ΕΔͷͰɺϦΫΤετͱ ඥ෇͚Δ͜ͱ͕Ͱ͖Δ
  2. 5$1αʔόʔΛ࣮૷ <?php $socket = stream_socket_server("tcp://0.0.0.0:9000", $errno, $errstr); while ($conn =

    stream_socket_accept($socket, -1)) { while (true) { $body = stream_socket_recvfrom($this->conn, 1024, 0); $command = 'xxx'; stream_socket_sendto($this->conn, "${command}\0"); } } fclose($socket);
  3. 5$1αʔόʔΛ࣮૷ <?php $socket = stream_socket_server("tcp://0.0.0.0:9000", $errno, $errstr); while ($conn =

    stream_socket_accept($socket, -1)) { while (true) { $body = stream_socket_recvfrom($this->conn, 1024, 0); $command = 'xxx'; stream_socket_sendto($this->conn, "${command}\0"); } } fclose($socket); 5$1αʔόʔͷ্ཱͪ͛ 5$1઀ଓͷ଴ड 5$1ύέοτड৴ 5$1ύέοτૹ৴
  4. // initͷϋϯυϦϯά $this->handleMessages($conn); // breakpoint_setͳͲͷॳظઃఆ while(true) { // ϢʔβೖྗͷಡΈऔΓ $input

    = readline("=> "); // ίϚϯυͷૹ৴ͱϨεϙϯεͷϋϯυϦϯά if ($this->sendCommand($conn, $input)) { $this->handleMessages($conn); } } 5$1઀ଓޙͷϑϩʔ
  5. ίʔϧελοΫΛ֬ೝ <?xml version="1.0" encoding="iso-8859-1"?> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="stack_get" transaction_id="6"> <stack

    where="{main}" level="0" type="file" filename=“file:///path/to/file.php” lineno="14"> </stack> </response> stack_get -i {id} ϑΝΠϧ໊ ߦ൪߸ ελοΫ৘ใ
  6. ม਺Λ֬ೝΦϒδΣΫτͷ৔߹ <?xml version="1.0" encoding="iso-8859-1"?> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="context_get" transaction_id="7" context="0">

    <property name="$hoge" fullname="$hoge" type="object" classname="Hoge" children="1" numchildren="1" page="0" pagesize="32"> <property name="hoge" fullname="$hoge-&gt;hoge" facet="public" type="string" size="3" encoding="base64"> <![CDATA[MTIz]]> </property> </property> </response> Πϯελϯεม਺ Ϋϥε໊
  7. εςοϓ࣮ߦ <?xml version="1.0" encoding="iso-8859-1"?> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="step_over" transaction_id="4" status="break"

    reason="ok"> <xdebug:message filename=“file:///path/to/file.php” lineno="15"> </xdebug:message> </response> step_over -i {id} ݱࡏͷϑΝΠϧ໊ ݱࡏͷߦ൪߸
  8. [FOE@FYFDVUF@FYͷࠩ͠ସ͑ void xdebug_base_minit(INIT_FUNC_ARGS) { // ... xdebug_old_execute_ex = zend_execute_ex; zend_execute_ex

    = xdebug_execute_ex; xdebug_old_execute_internal = zend_execute_internal; zend_execute_internal = xdebug_execute_internal; // ... } ݩͷ[FOE@FYFDVUF@FYΛPMEʹ଴ආ YEFCVH@FYFDVUF@FYͰؔ਺ϙΠϯλΛ্ॻ͖
  9. ݩͷ[FOE@FYFDVUF@FYલޙʹॲཧΛೖΕΔ static void xdebug_execute_ex(zend_execute_data *execute_data) { // ... fse =

    xdebug_add_stack_frame(edata, op_array, XDEBUG_USER_DEFINED); // ... xdebug_old_execute_ex(execute_data); // ... if (XG_BASE(stack)) { xdebug_vector_pop(XG_BASE(stack)); } } ίʔϧελοΫʹϓογϡ ίʔϧελοΫ͔Βϙοϓ ݩͷ[FOE@FYFDVUF@FYΛݺͼग़͠
  10. CSFBLQPJOUͰݺ͹ΕΔؔ਺ int xdebug_dbgp_breakpoint() { // ... response = xdebug_xml_node_init("response"); xdebug_xml_add_attribute(response,

    "xmlns", "urn:debugger_protocol_v1"); // ... send_message(context, response); // ... xdebug_dbgp_cmdloop(context, XDEBUG_CMDLOOP_BAIL); // ... 9.-ͷϨεϙϯεΛ࡞੒ ϝοηʔδΛૹ৴ ίϚϯυϧʔϓ
  11. ͓·͚ඪ४ग़ྗɾΤϥʔग़ྗ΋੍ޚͰ͖Δ stdout -i {id} -c 1 ແޮ  ίϐʔ 

    ϦμΠϨΫτ  w ΞϓϦέʔγϣϯͷඪ४ग़ྗɾΤϥʔग़ྗΛ 
 σόοΨʹίϐʔ͢Δ͔ϦμΠϨΫτͤ͞Δ͜ͱ͕Մೳ w ಺༰͸9.-Ͱฦͬͯ͘Δ
  12. ඪ४ग़ྗͷ9.- <?xml version="1.0" encoding="UTF-8"?> <stream xmlns="urn:debugger_protocol_v1" type="stdout" encoding="base64"> ...Base64 Data...

    </stream> w lSFTQPOTFͰ͸ͳ͘lTUSFBNzͰฦͬͯ͘Δ w ίϚϯυϨεϙϯεͷΑ͏ʹҰରʹͳ͓ͬͯΒͣෳ਺ฦͬ ͯ͘ΔͷͰ஫ҙ͕ඞཁ