Skip to content

fix(exec): don't treat shell_exec() null return as an error#3723

Merged
Leiyks merged 1 commit intomasterfrom
leiyks/fix-shell-exec-false-positives
Mar 25, 2026
Merged

fix(exec): don't treat shell_exec() null return as an error#3723
Leiyks merged 1 commit intomasterfrom
leiyks/fix-shell-exec-false-positives

Conversation

@Leiyks
Copy link
Copy Markdown
Contributor

@Leiyks Leiyks commented Mar 24, 2026

Summary

shell_exec() returning null was flagged as an error span. Per PHP docs, null means either no output or failure — the two are indistinguishable. This caused false-positive error spans for any silent command (e.g. Symfony's stty 2>/dev/null), which is especially disruptive with DD_APM_FEATURES=error_rare_sample_tracer_drop since those spans can't be sampled away.

A prior partial fix (cff203464) hooked two specific Symfony methods, but left the root defect in postHookShell() alive for all other callers.

Changes

  • Remove the shell_exec() returned null error condition from postHookShell() — the false return check above it covers genuine PHP-level failures
  • Add testShellExecNullReturnIsNotAnError: asserts shell_exec('true') (null return, no output) produces a clean span with no error

Fixes: APMS-18967 / #3127

PHP's shell_exec() returns null both when a command produces no output
AND when execution fails — the two cases are indistinguishable. Flagging
null as an error causes false-positive error spans for any intentionally
silent command (e.g. Symfony's `stty 2>/dev/null` called internally by
Terminal::hasSttyAvailable()), which is especially harmful when
DD_APM_FEATURES=error_rare_sample_tracer_drop is set, since those spans
cannot be sampled out.

The fix from cff2034 (v1.8.0) added hooks on two specific Symfony
methods to suppress their spans, but the root defect in postHookShell()
remained. Any other shell_exec() call returning null — from a Symfony
bundle, third-party package, or application code — still produced an
error span.

Per PHP docs: "It is not possible to detect execution failures using
this function." Remove the null check entirely; the false return check
above it already handles the case where PHP itself cannot invoke the
shell.

Adds a regression test asserting that shell_exec('true') — which
returns null due to no output — produces a clean span with no error.

Fixes: APMS-18967
@Leiyks Leiyks force-pushed the leiyks/fix-shell-exec-false-positives branch from 67f32fe to ba93b1d Compare March 25, 2026 11:34
@datadog-prod-us1-5
Copy link
Copy Markdown

datadog-prod-us1-5 Bot commented Mar 25, 2026

⚠️ Tests

Fix all issues with BitsAI or with Cursor

⚠️ Warnings

🧪 1048 Tests failed

testSearchPhpBinaries from integration.DDTrace\Tests\Integration\PHPInstallerTest   View in Datadog   (Fix with Cursor)
Risky Test
phpvfscomposer://tests/vendor/phpunit/phpunit/phpunit:97
testSimplePushAndProcess from laravel-58-test.DDTrace\Tests\Integrations\Laravel\V5_8\QueueTest   View in Datadog   (Fix with Cursor)
Risky Test
phpvfscomposer://tests/vendor/phpunit/phpunit/phpunit:97
testSimplePushAndProcess from laravel-8x-test.DDTrace\Tests\Integrations\Laravel\V8_x\QueueTest   View in Datadog   (Fix with Cursor)
DDTrace\Tests\Integrations\Laravel\V8_x\QueueTest::testSimplePushAndProcess
Test code or tested code printed unexpected output: spanLinksTraceId: 69c3cae3000000009bd01f70fdb5f689
tid: 69c3cae300000000
hexProcessTraceId: 9bd01f70fdb5f689
hexProcessSpanId: 5c28fa32fb6f8a39
processTraceId: 11227508441188005513
processSpanId: 6640832747431496249

phpvfscomposer://tests/vendor/phpunit/phpunit/phpunit:106
View all

ℹ️ Info

No other issues found (see more)

❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 100.00%
Overall Coverage: 60.66% (+0.04%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: ba93b1d | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback!

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Mar 25, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 68.79%. Comparing base (a1bb038) to head (ba93b1d).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3723      +/-   ##
==========================================
- Coverage   68.81%   68.79%   -0.02%     
==========================================
  Files         166      166              
  Lines       19030    19030              
  Branches     1797     1797              
==========================================
- Hits        13095    13092       -3     
- Misses       5121     5125       +4     
+ Partials      814      813       -1     
Flag Coverage Δ
helper-rust-integration 78.82% <ø> (-0.03%) ⬇️
helper-rust-unit 49.36% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 2 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a1bb038...ba93b1d. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pr-commenter
Copy link
Copy Markdown

pr-commenter Bot commented Mar 25, 2026

Benchmarks [ tracer ]

Benchmark execution time: 2026-03-25 12:53:14

Comparing candidate commit ba93b1d in PR branch leiyks/fix-shell-exec-false-positives with baseline commit a1bb038 in branch master.

Found 0 performance improvements and 2 performance regressions! Performance is the same for 192 metrics, 0 unstable metrics.

scenario:MessagePackSerializationBench/benchMessagePackSerialization

  • 🟥 execution_time [+7.382µs; +8.258µs] or [+7.394%; +8.271%]

scenario:MessagePackSerializationBench/benchMessagePackSerialization-opcache

  • 🟥 execution_time [+5.028µs; +6.872µs] or [+4.824%; +6.594%]

@Leiyks Leiyks marked this pull request as ready for review March 25, 2026 13:35
@Leiyks Leiyks requested review from a team as code owners March 25, 2026 13:35
@Leiyks Leiyks merged commit 55eb9e5 into master Mar 25, 2026
2083 of 2086 checks passed
@Leiyks Leiyks deleted the leiyks/fix-shell-exec-false-positives branch March 25, 2026 13:46
@github-actions github-actions Bot added this to the 1.18.0 milestone Mar 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants