Skip to content

Commit

Permalink
Fixed issue #2234: Detect 'tsc' clock and don't enable control socket…
Browse files Browse the repository at this point in the history
… by default if unavailable
  • Loading branch information
derickr committed Jan 29, 2024
1 parent 5115378 commit cb0e1c0
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 13 deletions.
17 changes: 16 additions & 1 deletion src/base/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| Xdebug |
+----------------------------------------------------------------------+
| Copyright (c) 2002-2023 Derick Rethans |
| Copyright (c) 2002-2024 Derick Rethans |
+----------------------------------------------------------------------+
| This source file is subject to version 1.01 of the Xdebug license, |
| that is bundled with this package in the file LICENSE, and is |
Expand Down Expand Up @@ -1415,6 +1415,21 @@ void xdebug_base_rinit()

#ifdef __linux__
/* Set-up Control Socket */

# if HAVE_XDEBUG_CLOCK_GETTIME
/* Check whether we have a broken TSC clock, and adjust if needed */
if (!XG_BASE(working_tsc_clock)) {
if (XINI_BASE(control_socket_granularity) == XDEBUG_CONTROL_SOCKET_DEFAULT) {
xdebug_log_ex(XLOG_CHAN_CONFIG, XLOG_WARN, "TSC-NO", "Not setting up control socket with default value due to unavailable 'tsc' clock");
XINI_BASE(control_socket_granularity) = XDEBUG_CONTROL_SOCKET_OFF;
}
if (XINI_BASE(control_socket_granularity) == XDEBUG_CONTROL_SOCKET_TIME) {
xdebug_log_ex(XLOG_CHAN_CONFIG, XLOG_WARN, "TSC-INFREQ", "Due to unavailable TSC clock, setting poll granularity to 100ms instead of 25ms");
XINI_BASE(control_socket_threshold_ms) = 100;
}
}
# endif

if (XINI_BASE(control_socket_granularity) != XDEBUG_CONTROL_SOCKET_OFF) {
xdebug_control_socket_setup();
}
Expand Down
3 changes: 2 additions & 1 deletion src/base/base_globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| Xdebug |
+----------------------------------------------------------------------+
| Copyright (c) 2002-2022 Derick Rethans |
| Copyright (c) 2002-2024 Derick Rethans |
+----------------------------------------------------------------------+
| This source file is subject to version 1.01 of the Xdebug license, |
| that is bundled with this package in the file LICENSE, and is |
Expand Down Expand Up @@ -48,6 +48,7 @@ typedef struct _xdebug_base_globals_t {
#endif
xdebug_nanotime_context nanotime_context;
uint64_t start_nanotime;
unsigned int working_tsc_clock; /* -1 = unknown, 0 = not available, 1 = available */
unsigned int prev_memory;
zif_handler orig_set_time_limit_func;
zif_handler orig_error_reporting_func;
Expand Down
3 changes: 2 additions & 1 deletion src/base/ctrl_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| Xdebug |
+----------------------------------------------------------------------+
| Copyright (c) 2002-2023 Derick Rethans |
| Copyright (c) 2002-2024 Derick Rethans |
+----------------------------------------------------------------------+
| This source file is subject to version 1.01 of the Xdebug license, |
| that is bundled with this package in the file LICENSE, and is |
Expand Down Expand Up @@ -292,6 +292,7 @@ void xdebug_control_socket_dispatch(void)
case XDEBUG_CONTROL_SOCKET_OFF:
return;

case XDEBUG_CONTROL_SOCKET_DEFAULT:
case XDEBUG_CONTROL_SOCKET_TIME:
if (xdebug_get_nanotime() < (XG_BASE(control_socket_last_trigger) + (XINI_BASE(control_socket_threshold_ms) * 1000000))) {
return;
Expand Down
15 changes: 12 additions & 3 deletions src/lib/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| Xdebug |
+----------------------------------------------------------------------+
| Copyright (c) 2002-2023 Derick Rethans |
| Copyright (c) 2002-2024 Derick Rethans |
+----------------------------------------------------------------------+
| This source file is subject to version 1.01 of the Xdebug license, |
| that is bundled with this package in the file LICENSE, and is |
Expand Down Expand Up @@ -214,8 +214,17 @@ int xdebug_lib_set_control_socket_granularity(char *value)
return 1;
}

XINI_BASE(control_socket_granularity) = XDEBUG_CONTROL_SOCKET_TIME;
XINI_BASE(control_socket_threshold_ms) = 25;
if (strcmp(value, "default") == 0) {
XINI_BASE(control_socket_granularity) = XDEBUG_CONTROL_SOCKET_DEFAULT;
XINI_BASE(control_socket_threshold_ms) = 25;
return 1;
}

if (strcmp(value, "time") == 0) {
XINI_BASE(control_socket_granularity) = XDEBUG_CONTROL_SOCKET_TIME;
XINI_BASE(control_socket_threshold_ms) = 25;
return 1;
}

return 0;
}
Expand Down
5 changes: 3 additions & 2 deletions src/lib/lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| Xdebug |
+----------------------------------------------------------------------+
| Copyright (c) 2002-2023 Derick Rethans |
| Copyright (c) 2002-2024 Derick Rethans |
+----------------------------------------------------------------------+
| This source file is subject to version 1.01 of the Xdebug license, |
| that is bundled with this package in the file LICENSE, and is |
Expand Down Expand Up @@ -286,7 +286,8 @@ int xdebug_lib_get_start_upon_error(void);

#if __linux__
# define XDEBUG_CONTROL_SOCKET_OFF 1
# define XDEBUG_CONTROL_SOCKET_TIME 4
# define XDEBUG_CONTROL_SOCKET_DEFAULT 2
# define XDEBUG_CONTROL_SOCKET_TIME 3
int xdebug_lib_set_control_socket_granularity(char *value);
#endif

Expand Down
3 changes: 2 additions & 1 deletion src/lib/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| Xdebug |
+----------------------------------------------------------------------+
| Copyright (c) 2002-2022 Derick Rethans |
| Copyright (c) 2002-2024 Derick Rethans |
+----------------------------------------------------------------------+
| This source file is subject to version 1.01 of the Xdebug license, |
| that is bundled with this package in the file LICENSE, and is |
Expand Down Expand Up @@ -335,6 +335,7 @@ void xdebug_print_info(void)
php_info_print_table_row(2, "Clock Source", "clock_gettime_nsec_np");
# elif HAVE_XDEBUG_CLOCK_GETTIME
php_info_print_table_row(2, "Clock Source", "clock_gettime");
php_info_print_table_row(2, "TSC Clock Source", XG_BASE(working_tsc_clock) ? "available" : "unavailable");
# else
php_info_print_table_row(2, "Clock Source", "gettimeofday");
# endif
Expand Down
40 changes: 39 additions & 1 deletion src/lib/timing.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| Xdebug |
+----------------------------------------------------------------------+
| Copyright (c) 2002-2021 Derick Rethans |
| Copyright (c) 2002-2024 Derick Rethans |
+----------------------------------------------------------------------+
| This source file is subject to version 1.01 of the Xdebug license, |
| that is bundled with this package in the file LICENSE, and is |
Expand Down Expand Up @@ -124,12 +124,43 @@ static uint64_t xdebug_get_nanotime_rel(xdebug_nanotime_context *nanotime_contex

return 0;
}

# ifdef __linux__
bool detect_linux_working_tsc_clock(void)
{
FILE *current_clocksource;
char contents[64];

current_clocksource = fopen("/sys/devices/system/clocksource/clocksource0/current_clocksource", "r");
if (!current_clocksource) {
/* Inconclusive, assume working clock */
return true;
}

if (!fgets(contents, sizeof(contents), current_clocksource)) {
/* Can't read any clock source */
fclose(current_clocksource);
return false;
}

if (strcmp(contents, "tsc\n") != 0) {
/* Current clock is not 'tsc' (+ newline) */
fclose(current_clocksource);
return false;
}

fclose(current_clocksource);
return true;
}
# endif
#endif

void xdebug_nanotime_init(xdebug_base_globals_t *base)
{
xdebug_nanotime_context context = {0};

base->working_tsc_clock = -1;

#if PHP_WIN32
LARGE_INTEGER tcounter;

Expand All @@ -156,6 +187,13 @@ void xdebug_nanotime_init(xdebug_base_globals_t *base)
context.last_rel = 0;
#endif

#ifdef __linux__
# if HAVE_XDEBUG_CLOCK_GETTIME
/* Detect if we have a 'broken' tsc clock on Linux for clock_gettime */
base->working_tsc_clock = detect_linux_working_tsc_clock();
# endif
#endif

base->nanotime_context = context;
}

Expand Down
2 changes: 1 addition & 1 deletion tests/debugger/bug02123.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ echo file_get_contents( $xdebugLogFileName );

%A[Step Debug] WARN: Breakpoint file name does not exist: /var/www/elephpants-are-cool/does-not-exist (No such file or directory).%A

[%d] Log opened at %s
[%d] Log opened at %s%A
[%d] [Step Debug] WARN: Breakpoint file name does not exist: /var/www/elephpants-are-cool/does-not-exist (No such file or directory).
[%d] Log closed at %s
7 changes: 5 additions & 2 deletions xdebug.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| Xdebug |
+----------------------------------------------------------------------+
| Copyright (c) 2002-2023 Derick Rethans |
| Copyright (c) 2002-2024 Derick Rethans |
+----------------------------------------------------------------------+
| This source file is subject to version 1.01 of the Xdebug license, |
| that is bundled with this package in the file LICENSE, and is |
Expand Down Expand Up @@ -241,6 +241,9 @@ ZEND_INI_DISP(display_control_socket)
case XDEBUG_CONTROL_SOCKET_OFF:
ZEND_PUTS("off");
break;
case XDEBUG_CONTROL_SOCKET_DEFAULT:
php_printf("time: %ldms", XINI_BASE(control_socket_threshold_ms));
break;
case XDEBUG_CONTROL_SOCKET_TIME:
php_printf("time: %ldms", XINI_BASE(control_socket_threshold_ms));
break;
Expand Down Expand Up @@ -310,7 +313,7 @@ PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("xdebug.file_link_format", "", PHP_INI_ALL, OnUpdateString, settings.library.file_link_format, zend_xdebug_globals, xdebug_globals)
STD_PHP_INI_ENTRY("xdebug.filename_format", "", PHP_INI_ALL, OnUpdateString, settings.library.filename_format, zend_xdebug_globals, xdebug_globals)
#if __linux__
PHP_INI_ENTRY_EX("xdebug.control_socket", "time", PHP_INI_ALL, OnUpdateCtrlSocket, display_control_socket)
PHP_INI_ENTRY_EX("xdebug.control_socket", "default", PHP_INI_ALL, OnUpdateCtrlSocket, display_control_socket)
#endif

STD_PHP_INI_ENTRY("xdebug.log", "", PHP_INI_ALL, OnUpdateString, settings.library.log, zend_xdebug_globals, xdebug_globals)
Expand Down

0 comments on commit cb0e1c0

Please sign in to comment.