Skip to content

Commit

Permalink
Fixed issue #2262: PHP 8.4: Different algorithm for wrapping closures…
Browse files Browse the repository at this point in the history
… with filename and line number range
  • Loading branch information
derickr committed May 29, 2024
1 parent 4c1b2c9 commit add8311
Show file tree
Hide file tree
Showing 17 changed files with 434 additions and 17 deletions.
26 changes: 26 additions & 0 deletions src/lib/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,31 @@ zend_string *xdebug_wrap_location_around_function_name(const char *prefix, zend_
return wrapped;
}

#if PHP_VERSION_ID >= 80400
zend_string* xdebug_wrap_closure_location_around_function_name(zend_op_array *opa, zend_string *fname)
{
zend_string *tmp, *tmp_loc_info;

if (ZSTR_VAL(fname)[ZSTR_LEN(fname) - 1] != '}') {
return zend_string_copy(fname);
}

tmp = zend_string_init(ZSTR_VAL(fname), strlen("{closure"), false);

tmp_loc_info = zend_strpprintf(
0,
"%s:%s:%d-%d}",
ZSTR_VAL(tmp),
ZSTR_VAL(opa->filename),
opa->line_start,
opa->line_end
);

zend_string_release(tmp);

return tmp_loc_info;
}
#else
zend_string* xdebug_wrap_closure_location_around_function_name(zend_op_array *opa, zend_string *fname)
{
zend_string *tmp, *tmp_loc_info;
Expand All @@ -826,6 +851,7 @@ zend_string* xdebug_wrap_closure_location_around_function_name(zend_op_array *op

return tmp_loc_info;
}
#endif

static void xdebug_declared_var_dtor(void *dummy, void *elem)
{
Expand Down
32 changes: 32 additions & 0 deletions tests/coverage/bug01571-php82.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
--TEST--
Test for bug #1571: Code Coverage doesn't show file/line for closures in namespaces (< PHP 8.4)
--SKIPIF--
<?php
require __DIR__ . '/../utils.inc';
check_reqs('PHP < 8.4');
?>
--INI--
xdebug.mode=coverage
xdebug.auto_profile=0
--FILE--
<?php
namespace Testing;

$pathname = stream_resolve_include_path(__FILE__);
xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE | XDEBUG_CC_BRANCH_CHECK);

$cb = function($a) {
usleep(500);
return $a * 3;
};
$cb(4);

$coverage = xdebug_get_code_coverage();
xdebug_stop_code_coverage();
print_r(array_keys($coverage[$pathname]['functions']));
?>
--EXPECTF--
Array
(
[0] => Testing\{closure:%sbug01571-php82.php:7-10}
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
--TEST--
Test for bug #1571: Code Coverage doesn't show file/line for closures in namespaces
Test for bug #1571: Code Coverage doesn't show file/line for closures in namespaces (>= PHP 8.4)
--SKIPIF--
<?php
require __DIR__ . '/../utils.inc';
check_reqs('PHP >= 8.4');
?>
--INI--
xdebug.mode=coverage
xdebug.auto_profile=0
Expand All @@ -23,5 +28,5 @@ print_r(array_keys($coverage[$pathname]['functions']));
--EXPECTF--
Array
(
[0] => Testing\{closure:%sbug01571.php:7-10}
[0] => {closure:%sbug01571-php84.php:7-10}
)
4 changes: 2 additions & 2 deletions tests/debugger/bug02011-php82.phpt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
--TEST--
Test for bug #2011: Protected closure facets (>= PHP 8.2)
Test for bug #2011: Protected closure facets (>= PHP 8.2, < PHP 8.4)
--SKIPIF--
<?php
require __DIR__ . '/../utils.inc';
check_reqs('PHP >= 8.2; dbgp');
check_reqs('PHP >= 8.2,< 8.4; dbgp');
?>
--FILE--
<?php
Expand Down
50 changes: 50 additions & 0 deletions tests/debugger/bug02011-php84.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
--TEST--
Test for bug #2011: Protected closure facets (>= PHP 8.4)
--SKIPIF--
<?php
require __DIR__ . '/../utils.inc';
check_reqs('PHP >= 8.4; dbgp');
?>
--FILE--
<?php
require 'dbgp/dbgpclient.php';
$filename = dirname(__FILE__) . '/bug02011.inc';

$commands = array(
'feature_set -n max_depth -v 2',
'step_into',
'breakpoint_set -t line -n 13',
'run',
'property_get -n $obj',
'detach',
);

dbgpRunFile( $filename, $commands );
?>
--EXPECTF--
<?xml version="1.0" encoding="iso-8859-1"?>
<init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" fileuri="file://bug02011.inc" language="PHP" xdebug:language_version="" protocol_version="1.0" appid=""><engine version=""><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[https://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2099 by Derick Rethans]]></copyright></init>

-> feature_set -i 1 -n max_depth -v 2
<?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="max_depth" success="1"></response>

-> step_into -i 2
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="step_into" transaction_id="2" status="break" reason="ok"><xdebug:message filename="file://bug02011.inc" lineno="%d"></xdebug:message></response>

-> breakpoint_set -i 3 -t line -n 13
<?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="3" id="{{PID}}0001"></response>

-> run -i 4
<?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="4" status="break" reason="ok"><xdebug:message filename="file://bug02011.inc" lineno="13"></xdebug:message></response>

-> property_get -i 5 -n $obj
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="property_get" transaction_id="5"><property name="$obj" fullname="$obj" type="object" classname="WithProtectedClosure" children="1" numchildren="1" page="0" pagesize="32"><property name="c" fullname="$obj-&gt;c" facet="protected closure" type="object" classname="Closure" children="1" numchildren="4" page="0" pagesize="32"><property name="name" fullname="$obj-&gt;c-&gt;name" facet="public" type="string" size="47" encoding="base64"><![CDATA[e2Nsb3N1cmU6V2l0aFByb3RlY3RlZENsb3N1cmU6Ol9fY29uc3RydWN0KCk6N30=]]></property><property name="file" fullname="$obj-&gt;c-&gt;file" facet="public" type="string" size="63" encoding="base64"><![CDATA[L2hvbWUvZGVyaWNrL2Rldi9waHAvZGVyaWNrci14ZGVidWcvdGVzdHMvZGVidWdnZXIvYnVnMDIwMTEuaW5j]]></property><property name="line" fullname="$obj-&gt;c-&gt;line" facet="public" type="int"><![CDATA[7]]></property><property name="this" fullname="$obj-&gt;c-&gt;this" facet="public" type="object" classname="WithProtectedClosure" children="1" numchildren="1"></property></property></property></response>

-> detach -i 6
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="detach" transaction_id="6" status="stopping" reason="ok"></response>
4 changes: 2 additions & 2 deletions tests/debugger/bug02094-php82.phpt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
--TEST--
Test for bug #2094: Public static property with closure data type have double facet XML attribute (>= PHP 8.2)
Test for bug #2094: Public static property with closure data type have double facet XML attribute (>= PHP 8.2, < PHP 8.4)
--SKIPIF--
<?php
require __DIR__ . '/../utils.inc';
check_reqs('PHP >= 8.2; dbgp');
check_reqs('PHP >= 8.2,< 8.4; dbgp');
?>
--FILE--
<?php
Expand Down
45 changes: 45 additions & 0 deletions tests/debugger/bug02094-php84.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
--TEST--
Test for bug #2094: Public static property with closure data type have double facet XML attribute (>= PHP 8.4)
--SKIPIF--
<?php
require __DIR__ . '/../utils.inc';
check_reqs('PHP >= 8.4; dbgp');
?>
--FILE--
<?php
require 'dbgp/dbgpclient.php';
$filename = dirname(__FILE__) . '/bug02094.inc';

$commands = array(
'step_into',
'breakpoint_set -t line -n 11',
'run',
'context_get',
'detach',
);

dbgpRunFile( $filename, $commands );
?>
--EXPECTF--
<?xml version="1.0" encoding="iso-8859-1"?>
<init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" fileuri="file://bug02094.inc" language="PHP" xdebug:language_version="" protocol_version="1.0" appid=""><engine version=""><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[https://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2099 by Derick Rethans]]></copyright></init>

-> step_into -i 1
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="step_into" transaction_id="1" status="break" reason="ok"><xdebug:message filename="file://bug02094.inc" lineno="%d"></xdebug:message></response>

-> breakpoint_set -i 2 -t line -n 11
<?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="2" id="{{PID}}0001"></response>

-> run -i 3
<?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="3" status="break" reason="ok"><xdebug:message filename="file://bug02094.inc" lineno="11"></xdebug:message></response>

-> context_get -i 4
<?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="4" context="0"><property name="::" fullname="::" type="object" classname="Test" children="1" numchildren="1"><property name="::bar" fullname="::bar" type="object" facet="closure static public" classname="Closure" children="1" numchildren="3" page="0" pagesize="32"><property name="name" fullname="::bar-&gt;name" facet="public" type="string" size="76" encoding="base64"><![CDATA[e2Nsb3N1cmU6L2hvbWUvZGVyaWNrL2Rldi9waHAvZGVyaWNrci14ZGVidWcvdGVzdHMvZGVidWdnZXIvYnVnMDIwOTQuaW5jOjE1fQ==]]></property><property name="file" fullname="::bar-&gt;file" facet="public" type="string" size="63" encoding="base64"><![CDATA[L2hvbWUvZGVyaWNrL2Rldi9waHAvZGVyaWNrci14ZGVidWcvdGVzdHMvZGVidWdnZXIvYnVnMDIwOTQuaW5j]]></property><property name="line" fullname="::bar-&gt;line" facet="public" type="int"><![CDATA[15]]></property></property></property></response>

-> detach -i 5
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="detach" transaction_id="5" status="stopping" reason="ok"></response>
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
--TEST--
Test for bug #2211: File wrapper gets wrong filename location in stack
Test for bug #2211: File wrapper gets wrong filename location in stack (< PHP 8.4)
--SKIPIF--
<?php
require __DIR__ . '/../utils.inc';
check_reqs('dbgp');
check_reqs('PHP < 8.4; dbgp');
?>
--FILE--
<?php
Expand Down
40 changes: 40 additions & 0 deletions tests/debugger/bug02211-php84.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
--TEST--
Test for bug #2211: File wrapper gets wrong filename location in stack (>= PHP 8.4)
--SKIPIF--
<?php
require __DIR__ . '/../utils.inc';
check_reqs('PHP >= 8.4; dbgp');
?>
--FILE--
<?php
require 'dbgp/dbgpclient.php';
$filename = dirname(__FILE__) . '/bug02211.inc';

$commands = array(
'run',
'stack_get',
'source -f data://text/plain;base64,PD9waHAKcmV0dXJuIGZ1bmN0aW9uKCkgewp4ZGVidWdfYnJlYWsoKTsKfTs=',
'detach',
);

dbgpRunFile( $filename, $commands, array( 'allow_url_include' => '1' ) );
?>
--EXPECTF--
<?xml version="1.0" encoding="iso-8859-1"?>
<init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" fileuri="file://bug02211.inc" language="PHP" xdebug:language_version="" protocol_version="1.0" appid=""><engine version=""><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[https://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2099 by Derick Rethans]]></copyright></init>

-> run -i 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="1" status="break" reason="ok"><xdebug:message filename="data://text/plain;base64,PD9waHAKcmV0dXJuIGZ1bmN0aW9uKCkgewp4ZGVidWdfYnJlYWsoKTsKfTs=" lineno="4"></xdebug:message></response>

-> stack_get -i 2
<?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="2"><stack where="{closure:data://text/plain;base64,PD9waHAKcmV0dXJuIGZ1bmN0aW9uKCkgewp4ZGVidWdfYnJlYWsoKTsKfTs=:2-4}" level="0" type="file" filename="data://text/plain;base64,PD9waHAKcmV0dXJuIGZ1bmN0aW9uKCkgewp4ZGVidWdfYnJlYWsoKTsKfTs=" lineno="4"></stack><stack where="{main}" level="1" type="file" filename="file://bug02211.inc" lineno="6"></stack></response>

-> source -i 3 -f data://text/plain;base64,PD9waHAKcmV0dXJuIGZ1bmN0aW9uKCkgewp4ZGVidWdfYnJlYWsoKTsKfTs=
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="source" transaction_id="3" encoding="base64"><![CDATA[PD9waHAKcmV0dXJuIGZ1bmN0aW9uKCkgewp4ZGVidWdfYnJlYWsoKTsKfTs=]]></response>

-> detach -i 4
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="detach" transaction_id="4" status="stopping" reason="ok"></response>
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
--TEST--
Test for bug #1571: Profiler doesn't show file/line for closures in namespaces
Test for bug #1571: Profiler doesn't show file/line for closures in namespaces (< PHP 8.4)
--SKIPIF--
<?php
require __DIR__ . '/../utils.inc';
check_reqs('PHP < 8.4');
?>
--INI--
xdebug.mode=profile
xdebug.start_with_request=default
Expand All @@ -14,7 +19,7 @@ exit();
--EXPECTF--
version: 1
creator: xdebug %d.%s (PHP %s)
cmd: %sbug01571-002.php
cmd: %sbug01571-002-php82.php
part: 1
positions: line

Expand Down Expand Up @@ -60,7 +65,7 @@ cfn=(5)
calls=1 0 0
5 %d %d

fl=(4) %sbug01571-002.php
fl=(4) %sbug01571-002-php82.php
fn=(7) {main}
1 %d %d
cfl=(2)
Expand Down
80 changes: 80 additions & 0 deletions tests/profiler/bug01571-002-php84.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
--TEST--
Test for bug #1571: Profiler doesn't show file/line for closures in namespaces (>= PHP 8.4)
--SKIPIF--
<?php
require __DIR__ . '/../utils.inc';
check_reqs('PHP >= 8.4');
?>
--INI--
xdebug.mode=profile
xdebug.start_with_request=default
--FILE--
<?php
require_once 'capture-profile.inc';

require_once 'bug01571-002.inc';

exit();
?>
--EXPECTF--
version: 1
creator: xdebug %d.%s (PHP %s)
cmd: %sbug01571-002-php84.php
part: 1
positions: line

events: Time_(10ns) Memory_(bytes)

fl=(1) php:internal
fn=(1) php::xdebug_get_profiler_filename
2 %d %d

fl=(1)
fn=(2) php::register_shutdown_function
16 %d %d

fl=(2) %scapture-profile.inc
fn=(3) require_once::%scapture-profile.inc
1 %d %d
cfl=(1)
cfn=(1)
calls=1 0 0
2 %d %d
cfl=(1)
cfn=(2)
calls=1 0 0
16 %d %d

fl=(1)
fn=(4) php::usleep
4 %d %d

fl=(3) %sbug01571-002.inc
fn=(5) {closure:%sbug01571-002.inc:4-4}
4 %d %d
cfl=(1)
cfn=(4)
calls=1 0 0
4 %d %d

fl=(3)
fn=(6) require_once::%sbug01571-002.inc
1 %d %d
cfl=(3)
cfn=(5)
calls=1 0 0
5 %d %d

fl=(4) %sbug01571-002-php84.php
fn=(7) {main}
1 %d %d
cfl=(2)
cfn=(3)
calls=1 0 0
2 %d %d
cfl=(3)
cfn=(6)
calls=1 0 0
4 %d %d

summary: %d %d
4 changes: 2 additions & 2 deletions tests/tracing/bug01571-001-php82.phpt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
--TEST--
Test for bug #1571: Stack traces don't show file/line for closures in namespaces (>= PHP 8.2)
Test for bug #1571: Stack traces don't show file/line for closures in namespaces (>= PHP 8.2, < PHP 8.4)
--SKIPIF--
<?php
require __DIR__ . '/../utils.inc';
check_reqs('PHP >= 8.2');
check_reqs('PHP >= 8.2,< 8.4');
?>
--INI--
xdebug.mode=trace
Expand Down
Loading

0 comments on commit add8311

Please sign in to comment.