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

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

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

tzmfreedom

April 09, 2022
Tweet

More Decks by tzmfreedom

Other Decks in Technology

Transcript

  1. גࣜձࣾϠϓϦా࣮੣
    %#(QΛ࢖ͬͯ

    1)1ͷσόοΨʔΛͭ͘Ζ͏

    View Slide

  2. ࣗݾ঺հ
    w ా࣮੣!U[N@GSFFEPN
    w גࣜձࣾϠϓϦͷαʔόʔαΠυΤϯδχΞ
    w 1)1ྺ͸ʙ೥͘Β͍
    w 1)1FS,BJHJͰ͸1)1Ͱ1)1Λ࣮૷

    1)1$POGFSFODFͰ͸ಠࣗϑϨʔϜϫʔΫΛվળ

    View Slide

  3. 1)1FS,BJHJͰ͸ެࣜαΠτͷϝΠϯϏδϡΞϧΛ୲౰

    View Slide

  4. View Slide

  5. μΠΞϞϯυͳεϙϯαʔ΍ͬͯ·͢ʂʂʂ

    View Slide

  6. Έͳ͞Μσόοάͯ͠·͔͢ʂʁ

    View Slide

  7. ͜ͷηογϣϯͰ࿩͢͜ͱ
    w9EFCVHͱ͸Կ͔ʁ
    w9EFCVHͷσόοΨͷ࢖͍ํ
    w9EFCVHͷσόοΨ͸ͲͷΑ͏ʹͯ͠ಈ͍͍ͯΔͷ͔
    w9EFCVHͷσόοΨͷ࡞Γํ

    View Slide

  8. 9EFCVHͱσόοΨʹ͍ͭͯ

    View Slide

  9. 9EFCVHͱ͸Կ͔ʁ
    w 1)1ͷ֦ுϞδϡʔϧʢ;FOEFYUFOTJPOʣ
    w εςοϓσόοάɾΧόϨοδऔಘɾؔ਺ͷτϨʔεɾϓϩϑ
    ΝΠϦϯά͕Ͱ͖Δ։ൃ༻Ϟδϡʔϧ
    w $-* NPE@QIQ 'BTU$(*ͳͲͷ4"1*Ͱར༻Մೳ
    w ओʹεςοϓσόοάɾΧόϨοδऔಘͷจ຺Ͱ࢖ΘΕΔ͜ͱ
    ͕ଟ͍

    View Slide

  10. 9EFCVHͷσόοΨͰͰ͖Δ͜ͱ
    w ΞϓϦέʔγϣϯͷεςοϓ࣮ߦ͕Ͱ͖Δ
    w ϒϨʔΫϙΠϯτͰ೚ҙͷ৔ॴͰϓϩάϥϜΛࢭΊΒΕΔ
    w ϩʔΧϧม਺ɾάϩʔόϧม਺ɾఆ਺ͷ஋ΛऔಘͰ͖Δ
    w 1IQ4UPSNͰσϑΥϧτͰ࢖͑ͨΓɺ7JN΍74$PEFͷϓϥ
    άΠϯ΋͋Δ

    View Slide

  11. 1IQ4UPSN$-*ͷ৔߹
    w ೚ҙͷεΫϦϓτΛσόοά࣮ߦ͢Δ͚ͩ
    w ಺෦తʹ͸ҎԼͷίϚϯυΛୟ͍ͯεΫϦϓτΛ࣮ߦ͠ɺ*%&
    ଆͰσόοΨΛىಈ͍ͯ͠Δ
    $ /usr/bin/php -dxdebug.mode=debug
    -dxdebug.client_port=9000
    -dxdebug.client_host=127.0.0.1 /path/to/file.php

    View Slide

  12. 1IQ4UPSN8FCͷ৔߹
    w πʔϧόʔ͔ΒσόοΨ઀ଓͷड෇Λ։࢝͢Δ
    w 8FCαʔόʔଆͷYEFCVHͷઃఆΛ͢Δ
    w YEFCVHNPEF YEFCVHDMJFOU@QPSU YEFCVHDMJFOU@IPTU
    YEFCVHTUBSU@XJUI@SFRVFTU ʜ
    w ର৅ͷϖʔδʹΞΫηε͢Δ

    View Slide

  13. 1IQ4UPSNϒϨʔΫϙΠϯτͷઃఆ
    ϒϨʔΫϙΠϯτ

    View Slide

  14. 1IQ4UPSNσόοά΢Οϯυ΢
    εςοϓ࣮ߦ
    ม਺
    ίʔϧελοΫ

    View Slide

  15. 9EFCVHʹΑΔσόοάͷ࢓૊Έ

    View Slide

  16. 1)1͔ΒσόοΨʹ઀ଓ
    YEFCVHDMJFOU@IPTU YEFCVHDMJFOU@QPSU͸

    ઀ଓઌͰ͋ΔσόοΨͷϗετɾϙʔτ

    View Slide

  17. %#(QͰ΍ΓऔΓ
    w εςοϓ࣮ߦ΍ϒϨʔΫϙΠϯτͷઃఆΛϦΫΤετ
    w ࣮ߦ݁Ռ΍ఀࢭ৔ॴͷ৘ใͳͲ͕Ϩεϙϯεͱͯ͠ฦͬͯ͘Δ

    View Slide

  18. %#(Qͱ͸
    w ϥϯλΠϜඇґଘͳσόοΨ༻ϓϩτίϧ

    ʢͱ͸͍͑9EFCVH͔͠࢖ͬͯͳͦ͞͏
    w 5$1
    w ϦΫΤετ͸ίϚϯυ
    w Ϩεϙϯε͸9.-
    w IUUQTYEFCVHPSHEPDTECHQ

    View Slide

  19. %#(Qͷϑϩʔ
    1)1͔ΒσόοΨʹ5$1઀ଓ
    1)1͔ΒJOJUύέοτΛૹ৴
    σόοΨ͔ΒίϚϯυΛૹ৴
    1)1͕σόοΨʹϨεϙϯεΛฦ͢
    σόοΨ͕ϨεϙϯεΛղऍ
    ʙͷ܁Γฦ͠

    View Slide

  20. 1)1͔ΒJOJUύέοτΛૹ৴



    xmlns:xdebug="https://xdebug.org/dbgp/xdebug"


    fileuri=“file:///path/to/file"


    language="PHP" xdebug:language_version=“8.0.9"


    protocol_version=“1.0” appid=“19366”
    idekey="1">















    View Slide

  21. σόοΨ͔ΒίϚϯυΛૹ৴
    breakpoint_set -i 2 -t line -f /path/to/file -n 14
    w JΦϓγϣϯͰτϥϯβΫγϣϯ*%ʹҰҙͳ਺ࣈΛࢦఆ
    w Ұҙͳ਺ࣈΛࢦఆ͢Ε͹ྑ͍ͷͰ࿈൪Ͱ0,
    w Ϩεϙϯεʹ΋τϥϯβΫγϣϯ*%ؚ͕·ΕΔͷͰɺϦΫΤετͱ
    ඥ෇͚Δ͜ͱ͕Ͱ͖Δ

    View Slide

  22. 1)1͕σόοΨʹϨεϙϯεΛฦ͢



    xmlns:xdebug="https://xdebug.org/dbgp/xdebug"
    command="run" transaction_id="3" status="break"
    reason="ok">


    lineno="14">






    τϥϯβΫγϣϯ*%

    View Slide

  23. 1IQ4UPSNͷσόοΨͷ௨৴
    ϒϨʔΫϙΠϯτͷઃఆ
    εΫϦϓτͷ࣮ߦ
    ίʔϧελοΫͷऔಘ

    View Slide

  24. 1IQ4UPSNͷσόοΨͷ௨৴
    w Ϩεϙϯε͸\9.-ͷαΠζ^laz\9.-^lazͷܗࣜ

    View Slide

  25. Ϩεϙϯεͷ಺༰
    9.-ͷαΠζ

    View Slide

  26. %#(QͰΑ͘࢖ΘΕΔίϚϯυ
    CSFBLQPJOU@TFU ϒϨΠΫϙΠϯτΛઃఆ͢Δ
    TUFQ@PWFS εςοϓΦʔόʔ
    TUBDL@HFU ݱࡏͷίʔϧελοΫΛऔಘ
    DPOUFYU@HFU ม਺ɾάϩʔόϧม਺ɾఆ਺Λऔಘ
    FWBM &YQSFTTJPOͷධՁ

    View Slide

  27. 1IQ4UPSNϒϨʔΫϙΠϯτ
    CSFBLQPJOU@TFU

    View Slide

  28. 1IQ4UPSNσόοά΢Οϯυ΢
    TUBDL@HFU
    DPOUFYU@HFU
    TUFQ@JOUP TUFQ@PWFS

    View Slide

  29. σόοΨΛ࡞Εͦ͏ͳؾ࣋ͪʹͳ͖ͬͯ
    ·ͨ͠ΑͶʁ

    View Slide

  30. %#(QΛ࢖ͬͯ
    1)1ͷσόοΨΛͭͬͯ͘Έͨ

    View Slide

  31. ࠓճ࡞ͬͨ΋ͷ
    w HECͷΑ͏ͳίϚϯυϕʔεͷσόοΨ
    w 1)1੡
    w ׬੒ͨ͠΋ͷ͸ͪ͜Βʹˣ
    w IUUQTHJUIVCDPNU[NGSFFEPNQIEC
    $ composer global require tzmfreedom/phdb


    $ phdb

    View Slide

  32. View Slide

  33. %#(Qͷϑϩʔ
    1)1͔ΒσόοΨʹ5$1઀ଓ
    1)1͔ΒJOJUύέοτΛૹ৴
    σόοΨ͔ΒίϚϯυΛૹ৴
    1)1͕σόοΨʹϨεϙϯεΛฦ͢
    σόοΨ͕ϨεϙϯεΛղऍ
    ʙͷ܁Γฦ͠

    View Slide

  34. 5$1αʔόʔΛ࣮૷


    $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);

    View Slide

  35. 5$1αʔόʔΛ࣮૷


    $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ύέοτૹ৴

    View Slide

  36. // initͷϋϯυϦϯά


    $this->handleMessages($conn);


    // breakpoint_setͳͲͷॳظઃఆ


    while(true) {


    // ϢʔβೖྗͷಡΈऔΓ


    $input = readline("=> ");


    // ίϚϯυͷૹ৴ͱϨεϙϯεͷϋϯυϦϯά


    if ($this->sendCommand($conn, $input)) {


    $this->handleMessages($conn);


    }


    }
    5$1઀ଓޙͷϑϩʔ

    View Slide

  37. ϒϨʔΫϙΠϯτͷઃఆ



    xmlns:xdebug="https://xdebug.org/dbgp/xdebug"
    command="breakpoint_set" transaction_id="2"
    id="193660001">



    breakpoint_set -i {id} -t line -f /path/to/file -n 14
    ϒϨʔΫϙΠϯτ*%
    छผ ϑΝΠϧ໊ ߦ൪߸

    View Slide

  38. ϒϨʔΫϙΠϯτͷछผ
    MJOF ϑΝΠϧɾߦ൪߸
    DBMM ؔ਺ݺͼग़ͨ͠͠ͱ͖
    SFUVSO ؔ਺ݺͼग़͔͠Β໭ͬͨͱ͖
    FYDFQUJPO &YDFQUJPO͕εϩʔ͞Εͨͱ͖
    DPOEJUJPOBM ϑΝΠϧɾߦ൪߸ʴධՁ৚݅

    View Slide

  39. ϒϨʔΫϙΠϯτͰࢭΊͨ͋ͱ͸ʜ
    w ίʔϧελοΫΛ֬ೝ
    w ม਺Λ֬ೝ
    w εςοϓ࣮ߦ
    w FWBM
    w ͳͲͳͲ

    View Slide

  40. ίʔϧελοΫΛ֬ೝ



    xmlns:xdebug="https://xdebug.org/dbgp/xdebug"
    command="stack_get" transaction_id="6">


    filename=“file:///path/to/file.php” lineno="14">






    stack_get -i {id}
    ϑΝΠϧ໊ ߦ൪߸
    ελοΫ৘ใ

    View Slide

  41. ม਺Λ֬ೝ



    xmlns:xdebug="https://xdebug.org/dbgp/xdebug"
    command="context_get" transaction_id="7" context="0">












    context_get -i {id}

    ม਺໊

    View Slide

  42. ม਺Λ֬ೝΦϒδΣΫτͷ৔߹



    xmlns:xdebug="https://xdebug.org/dbgp/xdebug"
    command="context_get" transaction_id="7" context="0">


    classname="Hoge" children="1" numchildren="1" page="0"
    pagesize="32">


    facet="public" type="string" size="3" encoding="base64">











    Πϯελϯεม਺
    Ϋϥε໊

    View Slide

  43. εςοϓ࣮ߦ



    xmlns:xdebug="https://xdebug.org/dbgp/xdebug"
    command="step_over" transaction_id="4" status="break"
    reason="ok">


    lineno="15">






    step_over -i {id}
    ݱࡏͷϑΝΠϧ໊
    ݱࡏͷߦ൪߸

    View Slide

  44. FWBMͰ&YQSFTTJPOΛධՁ



    xmlns:xdebug="https://xdebug.org/dbgp/xdebug"
    command="eval" transaction_id="6">






    eval -i {id} -d 1 -- ZWNobyAkaTs=
    FYQSFTTJPOͷCBTF
    ධՁ஋

    View Slide

  45. ͓·͚

    View Slide

  46. ʲ্ڃฤʁʳ9EFCVH͸Ͳ͏΍ͬͯಈ͍͍ͯΔʁ
    w 1)1͔ΒσόοΨʹ5$1઀ଓͨ͠ΓɺϒϨʔΫϙΠϯτ΍ε
    ςοϓ࣮ߦͰॲཧΛࢭΊͯσόοΨʹϨεϙϯεΛૹ͍ͬͯΔ
    w ͜ΕΛ1)1ͰͲ͏΍࣮ͬͯݱ͍ͯ͠Δͷ͔

    View Slide

  47. ʲ্ڃฤʁʳ9EFCVH͸Ͳ͏΍ͬͯಈ͍͍ͯΔʁ
    w 1)1͔ΒσόοΨʹ5$1઀ଓͨ͠ΓɺϒϨʔΫϙΠϯτ΍ε
    ςοϓ࣮ߦͰॲཧΛࢭΊͯσόοΨʹϨεϙϯεΛૹ͍ͬͯΔ
    w ͜ΕΛ1)1ͰͲ͏΍࣮ͬͯݱ͍ͯ͠Δͷ͔
    w [FOE@FYFDVUF@FYͷࠩ͠ସ͑
    w TUBUFNFOU@IBOEMFSʹΑΔϑοΫ

    View Slide

  48. [FOE@FYFDVUF@FY
    w εΫϦϓτ࣮ߦ࣌ʹݺ͹ΕΔؔ਺ϙΠϯλ
    w σϑΥϧτͷؔ਺ϙΠϯλ͔Βࠩ͠ସ͑Δͱɺؔ਺ݺͼग़͠ͷͨͼʹݺ͹
    ΕΔΑ͏ʹͳΔ
    w ࠷ॳͷ5$1઀ଓͱJOJUύέοτͷૹ৴
    w εΫϦϓτ࣮ߦ࣌ʹݺ͹ΕΔ[FOE@FYFDVUF@FYͰ࣮ߦ
    w ίʔϧελοΫͷ؅ཧ
    w ؔ਺ݺͼग़͠ͷ[FOE@FYFDVUF@FYͷલޙͰελοΫʹϓογϡϙοϓ

    View Slide

  49. [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Ͱؔ਺ϙΠϯλΛ্ॻ͖

    View Slide

  50. ݩͷ[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Λݺͼग़͠

    View Slide

  51. TUBUFNFOU@IBOEMFS
    w ;FOE֦ுͰ͸εςʔτϝϯτ࣮ߦ͝ͱʹϑοΫ͢Δؔ਺ΛࢦఆͰ͖Δ
    w 9EFCVHͰ͸εςοϓ࣮ߦ΍ϒϨʔΫϙΠϯτͰॲཧΛࢭΊΔͱ͖ʹ
    ར༻
    ZEND_DLEXPORT zend_extension zend_extension_entry = {





    xdebug_statement_call, /* statement_handler_func_t */





    };

    View Slide

  52. 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.-ͷϨεϙϯεΛ࡞੒
    ϝοηʔδΛૹ৴
    ίϚϯυϧʔϓ

    View Slide

  53. ·ͱΊ
    w%#(QͱσόοΨͷ࡞ΓํΛ঺հ͠·ͨ͠
    w%#(Q͸5$1ͳϓϩτίϧ

    ϖΠϩʔυ͸ίϚϯυʴ9.-
    w%#(QΛ࢖ͬͨσόοΨ͸ൺֱత؆୯ʹ࡞ΕΔͷͰ

    օ͞Μ࠷ڧͷσόοΨΛ࡞͍͖ͬͯ·͠ΐ͏💪

    View Slide

  54. σόοΨͱ஥ྑ͘ͳͬͯ
    ര଎։ൃ͍͖ͯ͠·͠ΐ͏👍

    View Slide

  55. ͓·͚ඪ४ग़ྗɾΤϥʔग़ྗ΋੍ޚͰ͖Δ
    stdout -i {id} -c 1
    ແޮ
    ίϐʔ
    ϦμΠϨΫτ

    w ΞϓϦέʔγϣϯͷඪ४ग़ྗɾΤϥʔग़ྗΛ

    σόοΨʹίϐʔ͢Δ͔ϦμΠϨΫτͤ͞Δ͜ͱ͕Մೳ
    w ಺༰͸9.-Ͱฦͬͯ͘Δ

    View Slide

  56. ඪ४ग़ྗͷ9.-





    type="stdout"


    encoding="base64">


    ...Base64 Data...



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

    View Slide