Skip to content

Commit 077d257

Browse files
dd-octo-sts[bot]taegyunkimbrettlangdon
authored
fix(ssi, crashtracker): load receiver script manually when not available in PATH [backport 3.12] (#14424)
Backport ef44d8c from #14421 to 3.12. When ddtrace is injected, `_dd_crashtracker_receiver` command is not available and we need to manually specify the script path. Without this change ``` apt update apt install -y curl php systemctl DD_INSTALLER=true DD_NO_AGENT_INSTALL=true bash -c "$(curl -L https://s3.amazonaws.com/dd-agent/scripts/install_script_agent7.sh)" datadog-installer install "oci://docker.io/datadog/apm-library-python-package:latest" datadog-installer install "oci://docker.io/datadog/apm-inject-package:latest" datadog-installer apm instrument bash # a new shell is required to enable the preload python3 -c 'print("Hello, World!")' ``` Gives us ``` Failed to find _dd_crashtracker_receiver Failed to start crashtracker: failed to construct crashtracker configuration Hello, World! ``` ## Checklist - [x] PR author has checked that all the criteria below are met - The PR description includes an overview of the change - The PR description articulates the motivation for the change - The change includes tests OR the PR description describes a testing strategy - The PR description notes risks associated with the change, if any - Newly-added code is easy to change - The change follows the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) - The change includes or references documentation updates if necessary - Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [x] Reviewer has checked that all the criteria below are met - Title is accurate - All changes are related to the pull request's stated goal - Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes - Testing strategy adequately addresses listed risks - Newly-added code is easy to change - Release note makes sense to a user of the library - If necessary, author has acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment - Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting) [PROF-12387](https://datadoghq.atlassian.net/browse/PROF-12387) [PROF-12387]: https://datadoghq.atlassian.net/browse/PROF-12387?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ Co-authored-by: Taegyun Kim <[email protected]> Co-authored-by: Brett Langdon <[email protected]>
1 parent 9b71acf commit 077d257

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

ddtrace/internal/core/crashtracking.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
import platform
23
import shutil
34
from typing import Dict
@@ -77,6 +78,14 @@ def _get_tags(additional_tags: Optional[Dict[str, str]]) -> Dict[str, str]:
7778

7879
def _get_args(additional_tags: Optional[Dict[str, str]]):
7980
dd_crashtracker_receiver = shutil.which("_dd_crashtracker_receiver")
81+
82+
# If not found in PATH, try ddtrace installation directory. This can happen
83+
# in an injected environment
84+
if dd_crashtracker_receiver is None:
85+
script_path = os.path.join(os.path.dirname(__file__), "..", "..", "commands", "_dd_crashtracker_receiver.py")
86+
if os.path.exists(script_path):
87+
dd_crashtracker_receiver = script_path
88+
8089
if dd_crashtracker_receiver is None:
8190
print("Failed to find _dd_crashtracker_receiver")
8291
return (None, None, None)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
fixes:
3+
- |
4+
ssi, crashtracker: This fix resolves an issue where crashtracker receiver
5+
binary was not available in an injected environment.
6+

tests/internal/crashtracker/test_crashtracker.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,37 @@ def test_crashtracker_started():
9090
pytest.fail("contents of stdout.log: %s, stderr.log: %s" % (stdout_msg, stderr_msg))
9191

9292

93+
@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
94+
@pytest.mark.subprocess()
95+
def test_crashtracker_receiver_not_in_path():
96+
import os
97+
import shutil
98+
99+
import pytest
100+
101+
from ddtrace.internal.core import crashtracking
102+
from tests.internal.crashtracker.utils import CrashtrackerWrapper
103+
104+
try:
105+
# Remove the receiver from the path. This mimics the case where we don't
106+
# have _dd_crashtracker_receiver in the PATH, for example when running
107+
# in an injected environment. And we should just load the script
108+
# directly.
109+
os.environ["PATH"] = ""
110+
dd_crashtracker_receiver = shutil.which("_dd_crashtracker_receiver")
111+
assert dd_crashtracker_receiver is None
112+
113+
ct = CrashtrackerWrapper(1234, "started")
114+
assert ct.start()
115+
assert crashtracking.is_started() # Confirmation at the module level
116+
except Exception:
117+
pytest.fail("Exception when starting crashtracker")
118+
119+
stdout_msg, stderr_msg = ct.logs()
120+
if stdout_msg or stderr_msg:
121+
pytest.fail("contents of stdout.log: %s, stderr.log: %s" % (stdout_msg, stderr_msg))
122+
123+
93124
@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
94125
@pytest.mark.subprocess()
95126
def test_crashtracker_simple():

0 commit comments

Comments
 (0)