Skip to content

Commit ef083b8

Browse files
committed
fix(remote-config): poll for new config after unblocking SIGVTALRM under valgrind
On Linux, unblocking SIGVTALRM causes immediate delivery if it was pending, which triggers remote config processing via dd_vm_interrupt. However, valgrind intercepts SIGVTALRM for its own timing, making signal delivery unreliable and causing the live debugger probe installation to time out in CI valgrind passes. Introduce REMOTE_CONFIG_NEEDS_POLLING_AFTER_SIGNAL to explicitly call ddtrace_check_for_new_config_now() after unblocking only when needed: - Linux + valgrind: RUNNING_ON_VALGRIND (runtime check, zero overhead otherwise) - Linux without valgrind headers: always 0 (no overhead) - Non-Linux: always 1 (signal delivery not guaranteed) Also add AC_CHECK_HEADERS([valgrind/valgrind.h]) to config.m4 to detect valgrind headers at build time.
1 parent 17c83a1 commit ef083b8

2 files changed

Lines changed: 21 additions & 4 deletions

File tree

config.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ if test "$PHP_DDTRACE" != "no"; then
4646

4747
AC_CHECK_HEADERS([linux/securebits.h])
4848
AC_CHECK_HEADERS([linux/capability.h])
49+
AC_CHECK_HEADERS([valgrind/valgrind.h])
4950

5051
dnl
5152
m4_ifndef([_LT_CHECK_OBJDIR], AC_LIBTOOL_OBJDIR, _LT_CHECK_OBJDIR)

ext/handlers_signal.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,22 @@
33
#include <signal.h>
44
#include <php.h>
55

6+
#ifdef __linux__
7+
# ifdef HAVE_VALGRIND
8+
# include <valgrind/valgrind.h>
9+
# else
10+
# define RUNNING_ON_VALGRIND 0
11+
# endif
12+
// On Linux, unblocking SIGVTALRM causes immediate delivery if it was pending.
13+
// We only need to poll explicitly when running under valgrind, which intercepts
14+
// SIGVTALRM for its own timing and makes signal delivery unreliable.
15+
# define REMOTE_CONFIG_NEEDS_POLLING_AFTER_SIGNAL RUNNING_ON_VALGRIND
16+
#else
17+
// On non-Linux platforms, SIGVTALRM delivery after unblock is not guaranteed,
18+
// so always poll explicitly.
19+
# define REMOTE_CONFIG_NEEDS_POLLING_AFTER_SIGNAL 1
20+
#endif
21+
622
/* We need to do signal blocking for the remote config signaling to not interfere with some PHP functions.
723
* See e.g. https://github.com/php/php-src/issues/16800
824
* I don't know the full problem space, so I expect there might be functions missing here, and we need to eventually expand this list.
@@ -16,10 +32,10 @@ static void dd_handle_signal(zif_handler original_function, INTERNAL_FUNCTION_PA
1632
original_function(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1733

1834
sigprocmask(SIG_UNBLOCK, &x, NULL);
19-
#ifndef __linux__
20-
// At least on linux unblocking causes immediate signal delivery.
21-
ddtrace_check_for_new_config_now();
22-
#endif
35+
// ensures no double-processing when the signal was delivered normally.
36+
if (REMOTE_CONFIG_NEEDS_POLLING_AFTER_SIGNAL) {
37+
ddtrace_check_for_new_config_now();
38+
}
2339
}
2440

2541
#define BLOCKSIGFN(function) \

0 commit comments

Comments
 (0)