Add timeout to debugger captures#4003
Conversation
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 793daeec61
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| usec = dd_find_lowest_dealine_timer(); | ||
| #endif | ||
| struct itimerval it = { | ||
| .it_value = { .tv_sec = usec / 10000000, .tv_usec = usec % 1000000 }, |
There was a problem hiding this comment.
Use microseconds-per-second for setitimer
On the non-Linux setitimer path, usec is already in microseconds, so tv_sec must divide by 1,000,000 rather than 10,000,000. When DD_DYNAMIC_INSTRUMENTATION_CAPTURE_TIMEOUT_MS is configured above 999 ms on macOS/BSD, values like 1000 ms or 2000 ms produce {0, 0} and disarm the timeout, while other multi-second values fire much too early; the same conversion should be fixed in the stop/re-arm paths as well.
Useful? React with 👍 / 👎.
Benchmarks [ tracer ]Benchmark execution time: 2026-06-29 16:36:22 Comparing candidate commit 89a1dcd in PR branch Found 0 performance improvements and 7 performance regressions! Performance is the same for 187 metrics, 0 unstable metrics.
|
efc9646 to
db71d0a
Compare
Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>
Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>
db71d0a to
92fe6c4
Compare
Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>
a3a2bcb to
c6da6b1
Compare
| if (next_deadline != ~0ull) { // re-arm the timer, for ZTS concurrency | ||
| uint64_t usec = (next_deadline - now_ns) / 1000ull; | ||
| struct itimerval it = { | ||
| .it_value = { .tv_sec = usec / 10000000, .tv_usec = usec % 1000000 }, |
There was a problem hiding this comment.
| .it_value = { .tv_sec = usec / 10000000, .tv_usec = usec % 1000000 }, | |
| .it_value = { .tv_sec = usec / 1000000, .tv_usec = usec % 1000000 }, |
there is an extra 0 here no ?
| usec = dd_find_lowest_dealine_timer(); | ||
| #endif | ||
| struct itimerval it = { | ||
| .it_value = { .tv_sec = usec / 10000000, .tv_usec = usec % 1000000 }, |
| #ifdef __linux__ | ||
| #include <sys/syscall.h> | ||
| #elif defined(ZTS) | ||
| uint64_t dd_find_lowest_dealine_timer(void) { |
There was a problem hiding this comment.
| uint64_t dd_find_lowest_dealine_timer(void) { | |
| uint64_t dd_find_lowest_deadline_timer(void) { |
needs to be changed in other places as well :D
|
|
||
| void dd_stop_debugger_timeout(void) { | ||
| if (DDTRACE_G(capture_timer_handle)) { | ||
| DeleteTimerQueueTimer(NULL, DDTRACE_G(capture_timer_handle), NULL); |
There was a problem hiding this comment.
| DeleteTimerQueueTimer(NULL, DDTRACE_G(capture_timer_handle), NULL); | |
| DeleteTimerQueueTimer(NULL, DDTRACE_G(capture_timer_handle), INVALID_HANDLE_VALUE); |
We can use this value to block until any running callback completes first
| #if !defined(__linux__) && defined(ZTS) | ||
| } ZEND_HASH_FOREACH_END(); | ||
| if (next_deadline != ~0ull) { // re-arm the timer, for ZTS concurrency | ||
| uint64_t usec = (next_deadline - now_ns) / 1000ull; |
There was a problem hiding this comment.
| uint64_t usec = (next_deadline - now_ns) / 1000ull; | |
| uint64_t usec = next_deadline > now_ns ? (next_deadline - now_ns) / 1000ull : 0; |
Should we check just in case ?
There was a problem hiding this comment.
That check happens on line 92: if (now_ns >= deadline) {
| struct timespec now; | ||
| clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now); | ||
| uint64_t now_ns = (uint64_t)now.tv_sec * 1000000000ULL + (uint64_t)now.tv_nsec; | ||
| usec = (next_deadline - now_ns) / 1000ull; |
There was a problem hiding this comment.
| usec = (next_deadline - now_ns) / 1000ull; | |
| usec = next_deadline > now_ns ? (next_deadline - now_ns) / 1000ull : 0; |
same here
| #endif | ||
|
|
||
| // SIGEV_THREAD_ID delivers SIGVTALRM to exactly this thread, not a random one (critical for ZTS). | ||
| void dd_start_debugger_timeout(void) { |
There was a problem hiding this comment.
I think we should add guards to check if a timer is already active first before starting a new one
Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>
Adding
DD_DYNAMIC_INSTRUMENTATION_CAPTURE_TIMEOUT_MSconfig to enforce limits on capture times.