xdebug / vscode-php-debug

PHP Debug Adapter for Visual Studio Code 🐞⛔
MIT License
768 stars 175 forks source link

Unable to debug files in archive in newer versions of php #878

Closed twoseascharlie closed 1 year ago

twoseascharlie commented 1 year ago

PHP version: 5.6, 7.3 (tested on 5.6- 8.1) Xdebug version: v2.5.5, v3.1.2 VS Code extension version: v1.30.0

Your launch.json:

"launch": {
        "configurations": [
            {
                "name": "Listen for Xdebug",
                "type": "php",
                "request": "launch",
                "port": 9003,
                "log": true,
                "pathMappings": {
                    "/home/pi/files/utils/php/phuild/phuild/build/libs/PhuildCore.tar": "w:\\home\\pi\\files\\utils\\php\\phuild\\phuild\\PhuildCore\\src"
                }
            },

Xdebug php.ini config:

php 5.6:


zend_extension=xdebug.so

xdebug.var_display_max_data = -1
xdebug.var_display_max_depth = -1
xdebug.var_display_max_children = -1

xdebug.remote_enable = 1
xdebug.start_with_request = yes
xdebug.remote_autostart = yes
xdebug.remote_log = /var/log/apache2/xdebug2.log
xdebug.remote_log_level = 7
xdebug.remote_connect_back = 1

xdebug.remote_host = <my local ip>
xdebug.remote_port = 9003

php 7.3:

zend_extension=/usr/lib/php/20180731/xdebug.so

xdebug.var_display_max_data = -1
xdebug.var_display_max_depth = -1
xdebug.var_display_max_children = -1

xdebug.mode = debug
xdebug.start_with_request = yes
xdebug.log = /var/log/apache2/xdebug3.log
xdebug.log_level = 7
xdebug.discover_client_host = 1

xdebug.client_host = <my local ip>
xdebug.client_port = 9003

Xdebug logfile (from setting xdebug.log in php.ini):

from 5.6:

Log opened at 2023-01-26 18:13:53
I: Checking remote connect back address.
I: Checking header 'HTTP_X_FORWARDED_FOR'.
I: Checking header 'REMOTE_ADDR'.
W: Remote address not found, connecting to configured address/port: 192.168.0.26:9003. :-|
I: Connected to client. :-)
-> <init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" fileuri="file:///home/pi/files/utils/php/phuild/phuild/build/bin/phd" language="PHP" xdebug:language_version="5.6.40-57+0~20211119.60+debian10~1.gbp8a9bd1" protocol_version="1.0" appid="12929" idekey="pi"><engine version="2.5.5"><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[http://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2017 by Derick Rethans]]></copyright></init>

<- feature_get -i 1 -n resolved_breakpoints
-> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="feature_get" transaction_id="1" feature_name="resolved_breakpoints" supported="0"><![CDATA[0]]></response>

<- feature_get -i 2 -n notify_ok
-> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="feature_get" transaction_id="2" feature_name="notify_ok" supported="0"><![CDATA[0]]></response>

<- feature_get -i 3 -n extended_properties
-> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="feature_get" transaction_id="3" feature_name="extended_properties" supported="0"><![CDATA[0]]></response>

<- feature_get -i 4 -n breakpoint_include_return_value
-> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="feature_get" transaction_id="4" feature_name="breakpoint_include_return_value" supported="0"><![CDATA[0]]></response>

<- feature_set -i 5 -n max_children -v 100
-> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="5" feature="max_children" success="1"></response>

<- breakpoint_set -i 6 -t line -f file:///home/pi/files/utils/php/phuild/phuild/build/libs/PhuildCore.tar/main/PhuildMain.php -n 223
-> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="breakpoint_set" transaction_id="6" id="129290001"></response>

<- run -i 7
-> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="run" transaction_id="7" status="break" reason="ok"><xdebug:message filename="phar:///home/pi/files/utils/php/phuild/phuild/build/libs/PhuildCore.tar/main/PhuildMain.php" lineno="223"></xdebug:message></response>

<- stack_get -i 8
-> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="stack_get" transaction_id="8"><stack where="require" level="0" type="file" filename="phar:///home/pi/files/utils/php/phuild/phuild/build/libs/PhuildCore.tar/main/PhuildMain.php" lineno="223"></stack><stack where="DHHDev\PhuildCore\bin\PhuildAutoLoader::loadClass" level="1" type="file" filename="file:///home/pi/files/utils/php/phuild/phuild/build/bin/PhuildAutoloader.php" lineno="59"></stack><stack where="spl_autoload_call" level="2" type="file" filename="file:///home/pi/files/utils/php/phuild/phuild/build/bin/phd" lineno="42"></stack><stack where="require_once" level="3" type="file" filename="file:///home/pi/files/utils/php/phuild/phuild/build/bin/phd" lineno="42"></stack><stack where="{main}" level="4" type="file" filename="file:///home/pi/files/utils/php/phuild/phuild/build/bin/phd" lineno="10"></stack></response>

<- context_names -i 9 -d 0
-> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="context_names" transaction_id="9"><context name="Locals" id="0"></context><context name="Superglobals" id="1"></context><context name="User defined constants" id="2"></context></response>

<- context_get -i 10 -d 0 -c 0
-> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="context_get" transaction_id="10" context="0"><property name="$absToolRoot" fullname="$absToolRoot" type="string" size="44" encoding="base64"><![CDATA[L2hvbWUvcGkvZmlsZXMvdXRpbHMvcGhwL3BodWlsZC9waHVpbGQvYnVpbGQ=]]></property><property name="$class" fullname="$class" type="string" size="33" encoding="base64"><![CDATA[REhIRGV2XFBodWlsZENvcmVcbWFpblxQaHVpbGRNYWlu]]></property><property name="$classFilePath" fullname="$classFilePath" type="string" size="15" encoding="base64"><![CDATA[bWFpbi9QaHVpbGRNYWlu]]></property><property name="$classNoPrefix" fullname="$classNoPrefix" type="string" size="15" encoding="base64"><![CDATA[bWFpblxQaHVpbGRNYWlu]]></property><property name="$libsDir" fullname="$libsDir" type="string" size="49" encoding="base64"><![CDATA[L2hvbWUvcGkvZmlsZXMvdXRpbHMvcGhwL3BodWlsZC9waHVpbGQvYnVpbGQvbGlicw==]]></property><property name="$moduleName" fullname="$moduleName" type="string" size="10" encoding="base64"><![CDATA[UGh1aWxkQ29yZQ==]]></property></response>

<- stop -i 11
-> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="stop" transaction_id="11" status="stopped" reason="ok"></response>

-> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="stop" transaction_id="11" status="stopping" reason="ok"></response>

Log closed at 2023-01-26 18:13:57

from 7.3:

 Log opened at 2023-01-26 18:20:56.370683
 [Step Debug] INFO: Checking remote connect back address.
 [Step Debug] INFO: Checking header 'HTTP_X_FORWARDED_FOR'.
 [Step Debug] INFO: Checking header 'REMOTE_ADDR'.
 [Step Debug] WARN: Could not discover client host through HTTP headers, connecting to configured address/port: 192.168.0.26:9003. :-|
 [Step Debug] INFO: Connected to debugging client: 192.168.0.26:9003 (fallback through xdebug.client_host/xdebug.client_port). :-)
 [Step Debug] -> <init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" fileuri="file:///home/pi/files/utils/php/phuild/phuild/build/bin/phd" language="PHP" xdebug:language_version="7.3.33-1+0~20211119.91+debian10~1.gbp618351" protocol_version="1.0" appid="14341"><engine version="3.1.2"><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[https://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2021 by Derick Rethans]]></copyright></init>

 [Step Debug] <- feature_set -i 1 -n resolved_breakpoints -v 1
 [Step Debug] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="1" feature="resolved_breakpoints" success="1"></response>

 [Step Debug] <- feature_set -i 2 -n notify_ok -v 1
 [Step Debug] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="2" feature="notify_ok" success="1"></response>

 [Step Debug] <- feature_set -i 3 -n extended_properties -v 1
 [Step Debug] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="3" feature="extended_properties" success="1"></response>

 [Step Debug] <- feature_get -i 4 -n breakpoint_include_return_value
 [Step Debug] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_get" transaction_id="4" feature_name="breakpoint_include_return_value" supported="0"><![CDATA[0]]></response>

 [Step Debug] <- feature_set -i 5 -n max_children -v 100
 [Step Debug] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="5" feature="max_children" success="1"></response>

 [Step Debug] <- breakpoint_set -i 6 -t line -f file:///home/pi/files/utils/php/phuild/phuild/build/libs/PhuildCore.tar/main/PhuildMain.php -n 223
 [Step Debug] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="breakpoint_set" transaction_id="6" id="143410001" resolved="unresolved"></response>

 [Step Debug] <- run -i 7
 [Step Debug] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="run" transaction_id="7" status="stopping" reason="ok"></response>

 [Step Debug] <- stop -i 8
 [Step Debug] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="stop" transaction_id="8" status="stopped" reason="ok"></response>

[14341] Log closed at 2023-01-26 18:21:11.046962

VS Code extension logfile (from setting "log": true in launch.json):

from 5.6:

new connection 1 from ::ffff:192.168.0.17
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" fileuri="file:///home/pi/files/utils/php/phuild/phuild/build/bin/phd" language="PHP" xdebug:language_version="5.6.40-57+0~20211119.60+debian10~1.gbp8a9bd1" protocol_version="1.0" appid="12632" idekey="pi"><engine version="2.5.5"><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[http://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2017 by Derick Rethans]]></copyright></init>
xd(1) <- feature_get -i 1 -n resolved_breakpoints
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="feature_get" transaction_id="1" feature_name="resolved_breakpoints" supported="0"><![CDATA[0]]></response>
xd(1) <- feature_get -i 2 -n notify_ok
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="feature_get" transaction_id="2" feature_name="notify_ok" supported="0"><![CDATA[0]]></response>
xd(1) <- feature_get -i 3 -n extended_properties
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="feature_get" transaction_id="3" feature_name="extended_properties" supported="0"><![CDATA[0]]></response>
xd(1) <- feature_get -i 4 -n breakpoint_include_return_value
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="feature_get" transaction_id="4" feature_name="breakpoint_include_return_value" supported="0"><![CDATA[0]]></response>
xd(1) <- feature_set -i 5 -n max_children -v 100
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="5" feature="max_children" success="1"></response>
<- threadEvent
ThreadEvent { seq: 0, type: 'event', event: 'thread', body: { reason: 'started', threadId: 1 } }
xd(1) <- breakpoint_set -i 6 -t line -f file:///home/pi/files/utils/php/phuild/phuild/build/libs/PhuildCore.tar/main/PhuildMain.php -n 223
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="breakpoint_set" transaction_id="6" id="126320001"></response>
<- breakpointEvent
BreakpointEvent {
  seq: 0,
  type: 'event',
  event: 'breakpoint',
  body: { reason: 'changed', breakpoint: { id: 1, verified: true } } }
xd(1) <- run -i 7
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="run" transaction_id="7" status="break" reason="ok"><xdebug:message filename="phar:///home/pi/files/utils/php/phuild/phuild/build/libs/PhuildCore.tar/main/PhuildMain.php" lineno="223"></xdebug:message></response>
<- stoppedEvent
StoppedEvent {
  seq: 0,
  type: 'event',
  event: 'stopped',
  body: { reason: 'breakpoint', threadId: 1, allThreadsStopped: false } }
-> threadsRequest
{ command: 'threads', type: 'request', seq: 8 }
<- threadsResponse
Response {
  seq: 0,
  type: 'response',
  request_seq: 8,
  command: 'threads',
  success: true,
  body: { threads: [ Thread { id: 1, name: 'Request 1 (12:11:57 PM)' } ] } }
-> stackTraceRequest
{ command: 'stackTrace',
  arguments: { threadId: 1, startFrame: 0, levels: 20 },
  type: 'request',
  seq: 9 }
xd(1) <- stack_get -i 8
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="stack_get" transaction_id="8"><stack where="require" level="0" type="file" filename="phar:///home/pi/files/utils/php/phuild/phuild/build/libs/PhuildCore.tar/main/PhuildMain.php" lineno="223"></stack><stack where="DHHDev\PhuildCore\bin\PhuildAutoLoader::loadClass" level="1" type="file" filename="file:///home/pi/files/utils/php/phuild/phuild/build/bin/PhuildAutoloader.php" lineno="59"></stack><stack where="spl_autoload_call" level="2" type="file" filename="file:///home/pi/files/utils/php/phuild/phuild/build/bin/phd" lineno="42"></stack><stack where="require_once" level="3" type="file" filename="file:///home/pi/files/utils/php/phuild/phuild/build/bin/phd" lineno="42"></stack><stack where="{main}" level="4" type="file" filename="file:///home/pi/files/utils/php/phuild/phuild/build/bin/phd" lineno="10"></stack></response>
<- stackTraceResponse
Response {
  seq: 0,
  type: 'response',
  request_seq: 9,
  command: 'stackTrace',
  success: true,
  body:
   { totalFrames: 5,
     stackFrames:
      [ { id: 1,
          name: 'require',
          source:
           { name: 'PhuildMain.php',
             path:
              'w:\\home\\pi\\files\\utils\\php\\phuild\\phuild\\PhuildCore\\src\\main\\PhuildMain.php' },
          line: 223,
          column: 1 },
        { id: 2,
          name: 'DHHDev\\PhuildCore\\bin\\PhuildAutoLoader::loadClass',
          source:
           { name: 'PhuildAutoloader.php',
             path: '/home/pi/files/utils/php/phuild/phuild/build/bin/PhuildAutoloader.php' },
          line: 59,
          column: 1 },
        { id: 3,
          name: 'spl_autoload_call',
          source: { name: 'phd', path: '/home/pi/files/utils/php/phuild/phuild/build/bin/phd' },
          line: 42,
          column: 1 },
        { id: 4,
          name: 'require_once',
          source: { name: 'phd', path: '/home/pi/files/utils/php/phuild/phuild/build/bin/phd' },
          line: 42,
          column: 1 },
        { id: 5,
          name: '{main}',
          source: { name: 'phd', path: '/home/pi/files/utils/php/phuild/phuild/build/bin/phd' },
          line: 10,
          column: 1 } ] } }
-> threadsRequest
{ command: 'threads', type: 'request', seq: 10 }
<- threadsResponse
Response {
  seq: 0,
  type: 'response',
  request_seq: 10,
  command: 'threads',
  success: true,
  body: { threads: [ Thread { id: 1, name: 'Request 1 (12:11:57 PM)' } ] } }
-> scopesRequest
{ command: 'scopes', arguments: { frameId: 1 }, type: 'request', seq: 11 }
xd(1) <- context_names -i 9 -d 0
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="context_names" transaction_id="9"><context name="Locals" id="0"></context><context name="Superglobals" id="1"></context><context name="User defined constants" id="2"></context></response>
<- scopesResponse
Response {
  seq: 0,
  type: 'response',
  request_seq: 11,
  command: 'scopes',
  success: true,
  body:
   { scopes:
      [ Scope { name: 'Locals', variablesReference: 1, expensive: false },
        Scope { name: 'Superglobals', variablesReference: 2, expensive: false },
        Scope { name: 'User defined constants', variablesReference: 3, expensive: false } ] } }
-> variablesRequest
{ command: 'variables',
  arguments: { variablesReference: 1 },
  type: 'request',
  seq: 12 }
xd(1) <- context_get -i 10 -d 0 -c 0
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="context_get" transaction_id="10" context="0"><property name="$absToolRoot" fullname="$absToolRoot" type="string" size="44" encoding="base64"><![CDATA[L2hvbWUvcGkvZmlsZXMvdXRpbHMvcGhwL3BodWlsZC9waHVpbGQvYnVpbGQ=]]></property><property name="$class" fullname="$class" type="string" size="33" encoding="base64"><![CDATA[REhIRGV2XFBodWlsZENvcmVcbWFpblxQaHVpbGRNYWlu]]></property><property name="$classFilePath" fullname="$classFilePath" type="string" size="15" encoding="base64"><![CDATA[bWFpbi9QaHVpbGRNYWlu]]></property><property name="$classNoPrefix" fullname="$classNoPrefix" type="string" size="15" encoding="base64"><![CDATA[bWFpblxQaHVpbGRNYWlu]]></property><property name="$libsDir" fullname="$libsDir" type="string" size="49" encoding="base64"><![CDATA[L2hvbWUvcGkvZmlsZXMvdXRpbHMvcGhwL3BodWlsZC9waHVpbGQvYnVpbGQvbGlicw==]]></property><property name="$moduleName" fullname="$moduleName" type="string" size="10" encoding="base64"><![CDATA[UGh1aWxkQ29yZQ==]]></property></response>
<- variablesResponse
Response {
  seq: 0,
  type: 'response',
  request_seq: 12,
  command: 'variables',
  success: true,
  body:
   { variables:
      [ { name: '$absToolRoot',
          value: '"/home/pi/files/utils/php/phuild/phuild/build"',
          type: 'string',
          variablesReference: 0,
          presentationHint: {},
          evaluateName: '$absToolRoot',
          indexedVariables: undefined },
        { name: '$class',
          value: '"DHHDev\\PhuildCore\\main\\PhuildMain"',
          type: 'string',
          variablesReference: 0,
          presentationHint: {},
          evaluateName: '$class',
          indexedVariables: undefined },
        { name: '$classFilePath',
          value: '"main/PhuildMain"',
          type: 'string',
          variablesReference: 0,
          presentationHint: {},
          evaluateName: '$classFilePath',
          indexedVariables: undefined },
        { name: '$classNoPrefix',
          value: '"main\\PhuildMain"',
          type: 'string',
          variablesReference: 0,
          presentationHint: {},
          evaluateName: '$classNoPrefix',
          indexedVariables: undefined },
        { name: '$libsDir',
          value: '"/home/pi/files/utils/php/phuild/phuild/build/libs"',
          type: 'string',
          variablesReference: 0,
          presentationHint: {},
          evaluateName: '$libsDir',
          indexedVariables: undefined },
        { name: '$moduleName',
          value: '"PhuildCore"',
          type: 'string',
          variablesReference: 0,
          presentationHint: {},
          evaluateName: '$moduleName',
          indexedVariables: undefined } ] } }

from 7.3:

new connection 1 from ::ffff:192.168.0.17
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" fileuri="file:///home/pi/files/utils/php/phuild/phuild/build/bin/phd" language="PHP" xdebug:language_version="7.3.33-1+0~20211119.91+debian10~1.gbp618351" protocol_version="1.0" appid="14341"><engine version="3.1.2"><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[https://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2021 by Derick Rethans]]></copyright></init>
xd(1) <- feature_set -i 1 -n resolved_breakpoints -v 1
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="1" feature="resolved_breakpoints" success="1"></response>
xd(1) <- feature_set -i 2 -n notify_ok -v 1
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="2" feature="notify_ok" success="1"></response>
xd(1) <- feature_set -i 3 -n extended_properties -v 1
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="3" feature="extended_properties" success="1"></response>
xd(1) <- feature_get -i 4 -n breakpoint_include_return_value
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_get" transaction_id="4" feature_name="breakpoint_include_return_value" supported="0"><![CDATA[0]]></response>
xd(1) <- feature_set -i 5 -n max_children -v 100
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="5" feature="max_children" success="1"></response>
<- threadEvent
ThreadEvent { seq: 0, type: 'event', event: 'thread', body: { reason: 'started', threadId: 1 } }
xd(1) <- breakpoint_set -i 6 -t line -f file:///home/pi/files/utils/php/phuild/phuild/build/libs/PhuildCore.tar/main/PhuildMain.php -n 223
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="breakpoint_set" transaction_id="6" id="143410001" resolved="unresolved"></response>
<- breakpointEvent
BreakpointEvent {
  seq: 0,
  type: 'event',
  event: 'breakpoint',
  body: { reason: 'changed', breakpoint: { id: 1, verified: false } } }
xd(1) <- run -i 7
-> threadsRequest
{ command: 'threads', type: 'request', seq: 8 }
<- threadsResponse
Response {
  seq: 0,
  type: 'response',
  request_seq: 8,
  command: 'threads',
  success: true,
  body: { threads: [ Thread { id: 1, name: 'Request 1 (12:20:56 PM)' } ] } }
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="run" transaction_id="7" status="stopping" reason="ok"></response>
xd(1) <- stop -i 8
xd(1) -> <?xml version="1.0" encoding="iso-8859-1"?><response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="stop" transaction_id="8" status="stopped" reason="ok"></response>
<- threadEvent
ThreadEvent { seq: 0, type: 'event', event: 'thread', body: { reason: 'exited', threadId: 1 } }

Code snippet to reproduce:

<?php
// bundle this file in a tar or phar
echo "inside archive" . PHP_EOL;

set a breakpoint on the echo line Expected: breakpoint is hit Actual: breakpoint is NOT hit on versions after php5.6

I have done some debugging through the vscode-php-debug extension and it looks like you are always sending a file:// uri path to the server.

I tried prepending the pathMappings with phar://, but then the uri gets sent like file://phar:///home/pi/files/...

ex:

"pathMappings": {
                    "phar:///home/pi/files/utils/php/phuild/phuild/build/libs/PhuildCore.tar": "w:\\home\\pi\\files\\utils\\php\\phuild\\phuild\\PhuildCore\\src"
}

I have done some test hacking and if I send a phar:// uri path to the server, I do see breakpoints get hit on php7.3

diff --git a/src/paths.ts b/src/paths.ts
old mode 100644
new mode 100755
index 7024f2d..1dc64cc
--- a/src/paths.ts
+++ b/src/paths.ts
@@ -41,10 +41,22 @@ export function convertDebuggerPathToClient(
         serverPath = serverPath.substr(1)
     }
     if (pathMapping) {
-        for (const mappedServerPath of Object.keys(pathMapping)) {
+        for (let mappedServerPath of Object.keys(pathMapping)) {
             const mappedLocalSource = pathMapping[mappedServerPath]
             // normalize slashes for windows-to-unix
-            const serverRelative = (serverIsWindows ? path.win32 : path.posix).relative(mappedServerPath, serverPath)
+            let serverRelative = (serverIsWindows ? path.win32 : path.posix).relative(mappedServerPath, serverPath)
+
+            // if there's not a match, check for mappings that start with a protocol/scheme
+            // and pluck it off to generate a local mapping
+            if (serverRelative.indexOf('..') === 0) {
+                let mappedServerPathUlr = url.parse(mappedServerPath)
+                if(mappedServerPathUlr.protocol && mappedServerPathUlr.path){
+                    mappedServerPath = mappedServerPathUlr.path
+                }
+            }
+
+            serverRelative = (serverIsWindows ? path.win32 : path.posix).relative(mappedServerPath, serverPath)
+
             if (serverRelative.indexOf('..') !== 0) {
                 // If a matching mapping has previously been found, only update
                 // it if the current server path is longer than the previous one
@@ -87,6 +99,7 @@ export function convertDebuggerPathToClient(
 export function convertClientPathToDebugger(localPath: string, pathMapping?: { [index: string]: string }): string {
     let localSourceRoot: string | undefined
     let serverSourceRoot: string | undefined
+    let serverSourceProtocol: string | undefined
     // Xdebug always lowercases Windows drive letters in file URIs
     let localFileUri = fileUrl(
         localPath.replace(/^[A-Z]:\\/, match => match.toLowerCase()),
@@ -118,6 +131,13 @@ export function convertClientPathToDebugger(localPath: string, pathMapping?: { [
         localSourceRoot = localSourceRoot.replace(/^[A-Z]:\//, match => match.toLowerCase())
     }
     if (serverSourceRoot) {
+        let serverSourceUrl = url.parse(serverSourceRoot)
+        serverSourceProtocol = (serverSourceUrl.protocol ? serverSourceUrl.protocol : undefined)
+        if(serverSourceProtocol){
+            // trim off the preceding protocol
+            serverSourceRoot = (serverSourceUrl.path ? serverSourceUrl.path : serverSourceRoot)
+        }
+
         serverSourceRoot = serverSourceRoot.replace(/^[A-Z]:$/, match => match.toLowerCase())
         serverSourceRoot = serverSourceRoot.replace(/^[A-Z]:\\/, match => match.toLowerCase())
         serverSourceRoot = serverSourceRoot.replace(/^[A-Z]:\//, match => match.toLowerCase())
@@ -128,6 +148,7 @@ export function convertClientPathToDebugger(localPath: string, pathMapping?: { [
             localSourceRootUrl += '/'
         }
         let serverSourceRootUrl = fileUrl(serverSourceRoot, { resolve: false })
+
         if (!serverSourceRootUrl.endsWith('/')) {
             serverSourceRootUrl += '/'
         }
@@ -135,6 +156,13 @@ export function convertClientPathToDebugger(localPath: string, pathMapping?: { [
         const urlRelativeToSourceRoot = relativeUrl(localSourceRootUrl, localFileUri)
         // resolve from the server source root
         serverFileUri = url.resolve(serverSourceRootUrl, urlRelativeToSourceRoot)
+
+        if(serverSourceProtocol){
+            // restore previously assigned protocol/scheme
+            let serverFileUrl = url.parse(serverFileUri)
+            serverFileUri = serverSourceProtocol + "//" + serverFileUrl.path
+        }
+
     } else {
         serverFileUri = localFileUri
     }
(END)

Not sure I have time to wrap this up in a formal PR right now. Can you please take a look and let me know what you think? I'm pretty sure I just got lucky that it worked in php5.6. Newer versions of php/xdebug don't seem to support debugging through archives using the file:// scheme/protocol. But they do work when specifying the phar:// scheme/protocol. It would be great if this plugin could be updated to support that.

zobo commented 1 year ago

Ok, so the core issue, if I understand correctly, is you want to step through phar files. The contents of the phar file is somewhere else and you want to path-map the phar file to that location.

I haven't done much with phars in this extension, so I'll do some tests to see how Xdebug behaves.

One possible option would be that vscode-php-debug gets the phar-er file contents via the debug protocol, another would be that vscode is able to extract the contents itself. Third is what you are doing here, path mappings.

Will try to look at this soon.

twoseascharlie commented 1 year ago

Ok, so the core issue, if I understand correctly, is you want to step through phar files. The contents of the phar file is somewhere else and you want to path-map the phar file to that location.

Yes that's correct. I am running php remotely via ssh and have a samba mount to develop with vscode on windows. I have some source located at some path and I am bundling that up in a tar (same behavior with a phar) and I'm trying to use path mappings to debug through the source in a vscode workspace. It works on 5.6, but not on php >= 7.0. If I make the updates to vscode-php-debug I posted and send a phar:// path to xdebug, I can hit breakpoints.

Thanks for taking a look!

zobo commented 1 year ago

I have reimplemented the whole path mapping logic. I have not tried it with PHAR yet, but it should work. Will test and let you know. PR #879

twoseascharlie commented 1 year ago

Thanks for the updates! I pulled your changes and can confirm that I am able to debug through archives now when using phar:// prefixed path mappings.

twoseascharlie commented 1 year ago

I did some more testing on my end and I did notice a regression:

I have these 2 path mappings that correspond to files that are not bundled in a phar/tar, before your changes, I was able to hit breakpoints as expected, but with your recent changes, they no longer work:

"pathMappings": {
    "/home/pi/files/utils/php/phuild/phuild/phuild.php": "w:\\home\\pi\\files\\utils\\php\\phuild\\phuild\\.build\\phuild.php",
    "/home/pi/files/utils/php/phuild/phuild/prodBuild.php": "w:\\home\\pi\\files\\utils\\php\\phuild\\phuild\\.build\\prodBuild.php",
}

On a very quick debug through your changes, it seems like forcing the path to end in a / is causing the issue since these are files: src/paths.ts line:72

not sure if direct file mappings were supposed to be formally supported, but they did used to work and do come in handy,

zobo commented 1 year ago

You are right, that would not work now. I didn't think anyone would map individual files. I'll look at this too.

zobo commented 1 year ago

I didn't want to change the trailing slash logic, so I added one extra step to look for exact length matching.

I'm not sure yet if I want to keep the forcing of trailing slash. Previous implementation used path resolving to figure out if both paths had the same root. I changed the implementation to work internally with URLs and simpler sting prefix matching. The reason I added the trailing slash is to not match in the middle of a folder name like [/var/fold]er/file.

Again I appreciate the feedback, there are cases I just didn't consider. You are a true pathMappings power user 😀

twoseascharlie commented 1 year ago

sure that makes sense, I pulled your latest changes again and can confirm that phar paths and individual file mapping works 😀

Again I appreciate the feedback, there are cases I just didn't consider. You are a true pathMappings power user 😀

ha, thanks! I appreciate your responsiveness and quick updates! this plugin has been very useful, thanks for continuing to make it great!

twoseascharlie commented 1 year ago

Closing this as confirmed the release fixes the issue. 🎉 Thanks for merging this one Damjan!