Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 56 additions & 34 deletions src/debugger/com.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,21 +794,27 @@ void xdebug_debug_init_if_requested_on_xdebug_break(void)
}
}

static void xdebug_update_ide_key(char *new_key)
void xdebug_update_ide_key(char *new_key)
{
if (XG_DBG(ide_key)) {
xdfree(XG_DBG(ide_key));
}
XG_DBG(ide_key) = xdstrdup(new_key);
}

static int xdebug_handle_start_session(void)
int xdebug_handle_start_session(void)
{
int activate_session = 0;
zval *dummy;
char *dummy_env;
int session_start_found = 0;
zval *dummy = NULL;
char *dummy_env = NULL;

/* Set session cookie if requested */
/* Return cached result if already checked this request to avoid duplicate side effects */
if (XG_DBG(start_session_result) != -1) {
return XG_DBG(start_session_result);
}

/* Check if session start trigger is present */
if (
((
(dummy = zend_hash_str_find(Z_ARR(PG(http_globals)[TRACK_VARS_ENV]), "XDEBUG_SESSION_START", sizeof("XDEBUG_SESSION_START") - 1)) != NULL
Expand All @@ -825,41 +831,55 @@ static int xdebug_handle_start_session(void)
))
&& !SG(headers_sent)
) {
xdebug_log(XLOG_CHAN_DEBUG, XLOG_DEBUG, "Found 'XDEBUG_SESSION_START' HTTP variable, with value '%s'", Z_STRVAL_P(dummy));
session_start_found = 1;

if (!xdebug_lib_has_shared_secret()) {
xdebug_log(XLOG_CHAN_DEBUG, XLOG_DEBUG, "Found 'XDEBUG_SESSION_START' HTTP variable, with value '%s'", Z_STRVAL_P(dummy));

convert_to_string_ex(dummy);
xdebug_update_ide_key(Z_STRVAL_P(dummy));
convert_to_string_ex(dummy);
xdebug_update_ide_key(Z_STRVAL_P(dummy));

xdebug_setcookie("XDEBUG_SESSION", sizeof("XDEBUG_SESSION") - 1, Z_STRVAL_P(dummy), Z_STRLEN_P(dummy), 0, "/", 1, NULL, 0, 0, 1, 0);
activate_session = 1;
xdebug_setcookie("XDEBUG_SESSION", sizeof("XDEBUG_SESSION") - 1, Z_STRVAL_P(dummy), Z_STRLEN_P(dummy), 0, "/", 1, NULL, 0, 0, 1, 0);
activate_session = 1;
}
} else if (
(dummy_env = getenv("XDEBUG_SESSION_START")) != NULL ||
(dummy_env = getenv("PHP_DEBUGGER_SESSION_START")) != NULL
) {
xdebug_log(XLOG_CHAN_DEBUG, XLOG_DEBUG, "Found 'XDEBUG_SESSION_START' ENV variable, with value '%s'", dummy_env);
session_start_found = 1;

xdebug_update_ide_key(dummy_env);
if (!xdebug_lib_has_shared_secret()) {
xdebug_log(XLOG_CHAN_DEBUG, XLOG_DEBUG, "Found 'XDEBUG_SESSION_START' ENV variable, with value '%s'", dummy_env);

if (!SG(headers_sent)) {
xdebug_setcookie("XDEBUG_SESSION", sizeof("XDEBUG_SESSION") - 1, XG_DBG(ide_key), strlen(XG_DBG(ide_key)), 0, "/", 1, NULL, 0, 0, 1, 0);
}
xdebug_update_ide_key(dummy_env);

activate_session = 1;
} else if (getenv("XDEBUG_CONFIG") || getenv("PHP_DEBUGGER_CONFIG")) {
xdebug_log(XLOG_CHAN_DEBUG, XLOG_DEBUG, "Found 'XDEBUG_CONFIG' or 'PHP_DEBUGGER_CONFIG' ENV variable");
if (!SG(headers_sent)) {
xdebug_setcookie("XDEBUG_SESSION", sizeof("XDEBUG_SESSION") - 1, XG_DBG(ide_key), strlen(XG_DBG(ide_key)), 0, "/", 1, NULL, 0, 0, 1, 0);
}

if (XG_DBG(ide_key) && *XG_DBG(ide_key) && !SG(headers_sent)) {
xdebug_setcookie("XDEBUG_SESSION", sizeof("XDEBUG_SESSION") - 1, XG_DBG(ide_key), strlen(XG_DBG(ide_key)), 0, "/", 1, NULL, 0, 0, 1, 0);
activate_session = 1;
}
} else if (getenv("XDEBUG_CONFIG") || getenv("PHP_DEBUGGER_CONFIG")) {
session_start_found = 1;

if (!xdebug_lib_has_shared_secret()) {
xdebug_log(XLOG_CHAN_DEBUG, XLOG_DEBUG, "Found 'XDEBUG_CONFIG' or 'PHP_DEBUGGER_CONFIG' ENV variable");

if (XG_DBG(ide_key) && *XG_DBG(ide_key) && !SG(headers_sent)) {
xdebug_setcookie("XDEBUG_SESSION", sizeof("XDEBUG_SESSION") - 1, XG_DBG(ide_key), strlen(XG_DBG(ide_key)), 0, "/", 1, NULL, 0, 0, 1, 0);
activate_session = 1;
}
}
}

/* Make sure that if we have a trigger value configured, we don't start the session unless it matches */
if (activate_session && xdebug_lib_has_shared_secret()) {
/* Log warning if session start was found but shared secret is configured */
if (session_start_found && xdebug_lib_has_shared_secret()) {
xdebug_log_ex(XLOG_CHAN_DEBUG, XLOG_INFO, "TRGSEC-LEGACY", "Not activating through legacy method because xdebug.trigger_value is set");
activate_session = 0;
}

/* Cache result to make this function idempotent */
XG_DBG(start_session_result) = activate_session;

return activate_session;
}

Expand Down Expand Up @@ -898,19 +918,21 @@ void xdebug_debug_init_if_requested_at_startup(void)
return;
}

if (
xdebug_lib_start_with_request() ||
(!xdebug_lib_never_start_with_request() && xdebug_handle_start_session()) ||
xdebug_lib_start_with_trigger(&found_trigger_value)
) {
if (found_trigger_value) {
xdebug_update_ide_key(found_trigger_value);
if (EXPECTED(XG_BASE(observer_active))) {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have already tried to connect and found out that we are not connected, we don't need to try here again

if (
xdebug_lib_start_with_request() ||
(!xdebug_lib_never_start_with_request() && xdebug_handle_start_session()) ||
xdebug_lib_start_with_trigger(&found_trigger_value)
) {
if (found_trigger_value) {
xdebug_update_ide_key(found_trigger_value);
}
xdebug_init_debugger();
}
xdebug_init_debugger();
}

if (found_trigger_value) {
xdfree(found_trigger_value);
if (found_trigger_value) {
xdfree(found_trigger_value);
}
}

xdebug_handle_stop_session();
Expand Down
2 changes: 2 additions & 0 deletions src/debugger/com.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,7 @@ int xdebug_early_connect_to_client(void);
void xdebug_debug_init_if_requested_on_connect_to_client(void);
void xdebug_debug_init_if_requested_on_error(void);
void xdebug_debug_init_if_requested_on_xdebug_break(void);
void xdebug_update_ide_key(char *new_key);
int xdebug_handle_start_session(void);

#endif
1 change: 1 addition & 0 deletions src/debugger/debugger.c
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,7 @@ void xdebug_debugger_rinit(void)
}

XG_DBG(no_exec) = 0;
XG_DBG(start_session_result) = -1;
xdebug_lib_set_active_symbol_table(NULL);

/* Check if we have this special get variable that stops a debugging
Expand Down
1 change: 1 addition & 0 deletions src/debugger/debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ typedef struct _xdebug_debugger_globals_t {
unsigned int breakpoint_count;
unsigned int no_exec;
char *ide_key; /* As Xdebug uses it, from environment, USER, USERNAME or empty */
int start_session_result; /* -1 = unchecked, 0 = checked/inactive, 1 = checked/active */

/* breakpoint resolving */
size_t function_count;
Expand Down
4 changes: 4 additions & 0 deletions src/lib/headers.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#include "lib_private.h"

#include "log.h"

extern ZEND_DECLARE_MODULE_GLOBALS(xdebug);

static int xdebug_header_handler(sapi_header_struct *h, sapi_header_op_enum op, sapi_headers_struct *s);
Expand Down Expand Up @@ -46,6 +48,7 @@ static int xdebug_header_handler(sapi_header_struct *h, sapi_header_op_enum op,
if (XG_LIB(headers)) {
switch (op) {
case SAPI_HEADER_ADD:
xdebug_log(XLOG_CHAN_DEBUG, XLOG_DEBUG, "Adding header '%s'.", h->header);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the xdebug_get_headers is no longer available, we need a way to see the headers that have been set. We add a log entry here that we can later use to check them

xdebug_llist_insert_next(XG_LIB(headers), XDEBUG_LLIST_TAIL(XG_LIB(headers)), xdstrdup(h->header));
break;
case SAPI_HEADER_REPLACE: {
Expand All @@ -59,6 +62,7 @@ static int xdebug_header_handler(sapi_header_struct *h, sapi_header_op_enum op,
*colon_offset = save;
}

xdebug_log(XLOG_CHAN_DEBUG, XLOG_DEBUG, "Adding header '%s'.", h->header);
xdebug_llist_insert_next(XG_LIB(headers), XDEBUG_LLIST_TAIL(XG_LIB(headers)), xdstrdup(h->header));
} break;
case SAPI_HEADER_DELETE_ALL:
Expand Down
18 changes: 8 additions & 10 deletions tests/debugger/bug01782.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,23 @@ Test for bug #1782: Make sure we use SameSite=Lax cookies (>= PHP 7.3)
<?php
require __DIR__ . '/../utils.inc';
check_reqs('PHP >= 7.3');
if (is_stripped_debugger()) die('skip Needs develop mode');
?>
--ENV--
XDEBUG_CONFIG=idekey=testing
--INI--
xdebug.mode=debug,develop
xdebug.mode=debug
default_charset=utf-8
xdebug.filename_format=
xdebug.client_port=9172
xdebug.log=
xdebug.log={TMPFILE:bug01782.txt}
xdebug.log_level=10
--FILE--
<?php
var_dump( xdebug_get_headers( ) );
require_once __DIR__ . '/../utils.inc';

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using the xdebug_get_headers function which is no longer available, we log the header in the xdebug log and then print it to confirm it's working. Previously this tests would not have worked because we were not calling xdebug_handle_start_session in RINIT, so the cookie was not being set


echo file_get_contents(getTmpFile('bug01782.txt'));
unlink(getTmpFile('bug01782.txt'));
?>
--EXPECTF--
Xdebug: [Step Debug] %sTried: localhost:9172 (through xdebug.client_host/xdebug.client_port).
%sbug01782.php:2:
array(1) {
[0] =>
string(%d) "Set-Cookie: XDEBUG_SESSION=testing; path=/; SameSite=Lax"
}
%A Adding header 'Set-Cookie: XDEBUG_SESSION=testing; path=/; SameSite=Lax'.
%A
1 change: 1 addition & 0 deletions tests/debugger/bug02348.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,5 @@ echo file_get_contents( $xdebugLogFileName );
[%d] [Step Debug] <- detach -i 4
[%d] [Step Debug] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="detach" transaction_id="4" status="stopping" reason="ok"></response>

[%d] [Step Debug] DEBUG: Adding header 'Content-type: %s'.
[%d] Log closed at %s
1 change: 1 addition & 0 deletions tests/debugger/remote_log-unix-2.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ unlink(getTmpFile('remote-unix.txt'));
[%d] [Step Debug] WARN: Invalid remote address provided containing URI spec 'unix:///tmp/haxx0r.sock'.
[%d] [Step Debug] WARN: Could not discover client host through HTTP headers, connecting to configured address/port: unix:///tmp/xdbg.sock:0.
[%d] [Step Debug] WARN: Creating socket for 'unix:///tmp/xdbg.sock', connect: No such file or directory.
[%d] [Step Debug] DEBUG: Adding header 'Content-type: %s'.
1 change: 1 addition & 0 deletions tests/debugger/remote_log-unix.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ unlink (getTmpFile('remote-log4.txt'));
[%d] Log opened at %d-%d-%d %d:%d:%d.%d
[%d] [Step Debug] INFO: Connecting to configured address/port: unix:///tmp/xdbg.sock:0.
[%d] [Step Debug] WARN: Creating socket for 'unix:///tmp/xdbg.sock', connect: No such file or directory.
[%d] [Step Debug] DEBUG: Adding header 'Content-type: %s'.
1 change: 1 addition & 0 deletions tests/debugger/remote_log1.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ unlink(getTmpFile('remote-log1.txt'));
[%d] Log opened at %d-%d-%d %d:%d:%d.%d
[%d] [Step Debug] INFO: Connecting to configured address/port: doesnotexist:9002.
[%d] [Step Debug] WARN: Creating socket for 'doesnotexist:9002', getaddrinfo: %s.
[%d] [Step Debug] DEBUG: Adding header 'Content-type: %s'.
1 change: 1 addition & 0 deletions tests/debugger/remote_log2.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ unlink(getTmpFile('remote-log2.txt'));
[%d] [Step Debug] INFO: Checking header 'REMOTE_ADDR'.
[%d] [Step Debug] WARN: Could not discover client host through HTTP headers, connecting to configured address/port: doesnotexist2:9003.
[%d] [Step Debug] WARN: Creating socket for 'doesnotexist2:9003', getaddrinfo: %s.
[%d] [Step Debug] DEBUG: Adding header 'Content-type: %s'.
1 change: 1 addition & 0 deletions tests/debugger/remote_log3.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ unlink(getTmpFile('remote-log3.txt'));
[%d] [Step Debug] INFO: Checking header 'REMOTE_ADDR'.
[%d] [Step Debug] WARN: Could not discover client host through HTTP headers, connecting to configured address/port: doesnotexist2:9003.
[%d] [Step Debug] WARN: Creating socket for 'doesnotexist2:9003', getaddrinfo: %s.
[%d] [Step Debug] DEBUG: Adding header 'Content-type: %s'.
1 change: 1 addition & 0 deletions tests/debugger/remote_log4.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ unlink(getTmpFile('remote-log4.txt'));
[%d] [Step Debug] WARN: Creating socket for 'cookiehost:9003', getaddrinfo: %s.
[%d] [Step Debug] WARN: Could not connect to client host discovered through HTTP headers, connecting to configured address/port: doesnotexist2:9003.
[%d] [Step Debug] WARN: Creating socket for 'doesnotexist2:9003', getaddrinfo: %s.
[%d] [Step Debug] DEBUG: Adding header 'Content-type: %s'.
1 change: 1 addition & 0 deletions tests/debugger/start_ignore_yes_cookie.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ Hi!
[%d] Log opened at %s%A
[%d] [Step Debug] DEBUG: Not activating because an 'XDEBUG_IGNORE' ENV variable is present, with value 'yes'.
[%d] [Step Debug] DEBUG: Not activating because an 'XDEBUG_IGNORE' COOKIE variable is present, with value 'yes'.
[%d] [Step Debug] DEBUG: Adding header 'Content-type: %s'.
[%d] Log closed at %s
1 change: 1 addition & 0 deletions tests/debugger/start_ignore_yes_env.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ Hi!

[%d] Log opened at %s%A
[%d] [Step Debug] DEBUG: Not activating because an 'XDEBUG_IGNORE' ENV variable is present, with value 'yes'.
[%d] [Step Debug] DEBUG: Adding header 'Content-type: %s'.
[%d] Log closed at %s
1 change: 1 addition & 0 deletions tests/debugger/start_ignore_yes_get.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ Hi!
[%d] Log opened at %s%A
[%d] [Step Debug] DEBUG: Not activating because an 'XDEBUG_IGNORE' ENV variable is present, with value 'yes'.
[%d] [Step Debug] DEBUG: Not activating because an 'XDEBUG_IGNORE' GET variable is present, with value 'yes'.
[%d] [Step Debug] DEBUG: Adding header 'Content-type: %s'.
[%d] Log closed at %s
1 change: 1 addition & 0 deletions tests/debugger/start_ignore_yes_post.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ Hi!
[%d] Log opened at %s%A
[%d] [Step Debug] DEBUG: Not activating because an 'XDEBUG_IGNORE' ENV variable is present, with value 'yes'.
[%d] [Step Debug] DEBUG: Not activating because an 'XDEBUG_IGNORE' POST variable is present, with value 'yes'.
[%d] [Step Debug] DEBUG: Adding header 'Content-type: %s'.
[%d] Log closed at %s
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ dbgpRunFile(
?>
--EXPECTF--
<?xml version="1.0" encoding="iso-8859-1"?>
<init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" fileuri="file://empty-echo.inc" language="PHP" xdebug:language_version="" protocol_version="1.0" appid=""><engine version=""><![CDATA[PHP Debugger]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[https://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2099 by Derick Rethans]]></copyright></init>
<init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" fileuri="file://empty-echo.inc" language="PHP" xdebug:language_version="" protocol_version="1.0" appid="" idekey="yes"><engine version=""><![CDATA[PHP Debugger]]></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"?>
Expand Down
1 change: 1 addition & 0 deletions tests/debugger/start_with_request_trigger_match-009.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,5 @@ Hi!
[%d] [Config] DEBUG: Checking if trigger 'XDEBUG_TRIGGER' is enabled
[%d] [Config] DEBUG: The shared secret (xdebug.trigger_value) is multi-value
[%d] [Config] WARN: The trigger value 'value3', as set through 'XDEBUG_TRIGGER', did not match any of the shared secrets (xdebug.trigger_value)
[%d] [Step Debug] DEBUG: Adding header 'Content-type: %s'.
[%d] Log closed at %s
1 change: 1 addition & 0 deletions tests/debugger/start_with_request_trigger_match-010.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ Hi!
[%d] [Config] INFO: Trigger value for 'XDEBUG_TRIGGER' not found, falling back to 'XDEBUG_SESSION'
[%d] [Config] DEBUG: The shared secret (xdebug.trigger_value) is multi-value
[%d] [Config] WARN: The trigger value 'value3', as set through 'XDEBUG_SESSION', did not match any of the shared secrets (xdebug.trigger_value)
[%d] [Step Debug] DEBUG: Adding header 'Content-type: %s'.
[%d] Log closed at %s
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
--TEST--
Starting Debugger: trigger with shared secret, XDEBUG_SESSION_START
--XFAIL--
Phase 2 early connect attempts TCP connection at RINIT before the shared secret (xdebug.trigger_value) is validated. The connection succeeds even when the trigger value does not match the secret. Original Xdebug validated the trigger value before connecting.
--ENV--
XDEBUG_SESSION_START=foobar
--FILE--
Expand All @@ -20,7 +18,6 @@ dbgpRunFile(
'variables_order' => 'PGCS',
'xdebug.log' => $xdebugLogFileName, 'xdebug.log_level' => 10,
'xdebug.control_socket' => 'off', 'xdebug.path_mapping' => 'off',
'xdebug.on_demand_debugging_enabled' => 1

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually not needed for this test, once we fix the issue, it works fine even without this setting

],
['timeout' => 1]
);
Expand All @@ -35,9 +32,9 @@ Hi!


[%d] Log opened at %s
[%d] [Step Debug] DEBUG: Found 'XDEBUG_SESSION_START' ENV variable, with value 'foobar'
[%d] [Step Debug] INFO: Not activating through legacy method because xdebug.trigger_value is set
[%d] [Config] DEBUG: Checking if trigger 'XDEBUG_TRIGGER' is enabled
[%d] [Config] INFO: Trigger value for 'XDEBUG_TRIGGER' not found, falling back to 'XDEBUG_SESSION'
[%d] [Config] INFO: Trigger value for 'XDEBUG_SESSION' not found, so not activating
[%d] [Config] INFO: Trigger value for 'PHP_DEBUGGER_SESSION' not found, so not activating
[%d] [Step Debug] DEBUG: Adding header 'Content-type: %s'.
[%d] Log closed at %s
32 changes: 17 additions & 15 deletions xdebug.c
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ static void xdebug_init_auto_globals(void)

PHP_RINIT_FUNCTION(xdebug)
{
char *found_trigger_value = NULL;
int debug_requested;
int connected;

Expand Down Expand Up @@ -614,28 +615,29 @@ PHP_RINIT_FUNCTION(xdebug)
xdebug_base_rinit();

/* Check early if debugging could be requested this request.
* Check if start_with_request=trigger and any trigger is present
* or if start_with_request=yes.
* If not, disable all heavy hooks for
* near-zero overhead. The actual connection happens on first
* function call if triggers are present. */
/* Check if debugging could be requested this request.
* For trigger/default mode: check triggers, cookies, env vars.
* For yes mode: always expect a connection.
* For no mode: no debugging will happen.
* Note: xdebug_break() can initiate connections without triggers,
* Determines whether to enable the observer and attempt early connection.
*
* Three checks (all must pass start_with_request=no and XDEBUG_IGNORE guards):
* 1. xdebug_handle_start_session() - legacy XDEBUG_SESSION_START or XDEBUG_CONFIG
* 2. xdebug_lib_start_with_request() - start_with_request=yes
* 3. xdebug_lib_start_with_trigger() - start_with_request=trigger and trigger present
*
* If none match, observer stays disabled for near-zero overhead.
* Note: xdebug_break() can initiate connections later without any of these triggers,
* but it handles re-enabling the observer itself. */
/* Respect start_with_request=no and XDEBUG_IGNORE */
debug_requested = !xdebug_lib_never_start_with_request() && !xdebug_should_ignore() && (
xdebug_handle_start_session() ||
xdebug_lib_start_with_request() ||
xdebug_lib_start_with_trigger(NULL) ||
xdebug_lib_start_upon_error() ||
getenv("XDEBUG_SESSION_START") != NULL ||
getenv("PHP_DEBUGGER_SESSION_START") != NULL
xdebug_lib_start_with_trigger(&found_trigger_value)
);

connected = false;
if (debug_requested) {
if (found_trigger_value) {
xdebug_update_ide_key(found_trigger_value);
xdfree(found_trigger_value);
}

/* Debug session requested: check if a client is actually listening
* before enabling expensive EXT_STMT opcodes. This avoids ~2x
* overhead when triggers are present but no IDE is connected. */
Expand Down
Loading