litestar-org / litestar

Production-ready, Light, Flexible and Extensible ASGI API framework | Effortlessly Build Performant APIs
https://litestar.dev/
MIT License
5.4k stars 372 forks source link

Bug: segfault when running `pytest .` with `litestar` and `ddtrace` #2402

Closed anden-akkio closed 6 months ago

anden-akkio commented 12 months ago

Description

We use ddtrace, Datadog's tracing library, in order to trace our code without much configuration needed. Getting this low-config tracing is extremely important to us, making this bug a blocker for us potentially switching from FastAPI to Litestar. We were hoping Litestar would have compatibility through their ASGI Integration.

The combo mentioned in the title seems to cause a segfault when running pytest with a Litestar server. Seems like the two libraries are going back and forth to explore each file, then segfaulting for an unknown reason.

Have confirmed that the issue does not occur if I remove ddtrace via poetry remove ddtrace then run pytest . again. We're also successfully using ddtrace with FastAPI, so it's not a FastAPI thing either.

URL to code causing the issue

https://github.com/anden-akkio/litestar-ddtrace-repro

MCVE

See above repo link for a full repro case.

Steps to reproduce

Screenshots

N/A

Logs

============================================================================================ test session starts ============================================================================================
platform darwin -- Python 3.10.12, pytest-7.4.2, pluggy-1.3.0
rootdir: /Users/andenacitelli/litestar-ddtrace-repro
plugins: Faker-19.6.2, anyio-4.0.0, ddtrace-2.0.2
collecting ... Fatal Python error: Segmentation fault

Thread 0x000000016df6f000 (most recent call first):
  File "/Users/andenacitelli/.pyenv/versions/3.10.12/lib/python3.10/threading.py", line 324 in wait
  File "/Users/andenacitelli/.pyenv/versions/3.10.12/lib/python3.10/threading.py", line 607 in wait
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/ddtrace/internal/periodic.py", line 55 in run
  File "/Users/andenacitelli/.pyenv/versions/3.10.12/lib/python3.10/threading.py", line 1016 in _bootstrap_inner
  File "/Users/andenacitelli/.pyenv/versions/3.10.12/lib/python3.10/threading.py", line 973 in _bootstrap

Current thread 0x00000001e2fae080 (most recent call first):
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/litestar/_signature/model.py", line 96 in <module>
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 883 in exec_module
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/ddtrace/internal/module.py", line 220 in _exec_module
  File "<frozen importlib._bootstrap>", line 688 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1006 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1027 in _find_and_load
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/litestar/_signature/__init__.py", line 1 in <module>
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 883 in exec_module
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/ddtrace/internal/module.py", line 220 in _exec_module
  File "<frozen importlib._bootstrap>", line 688 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1006 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1027 in _find_and_load
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/litestar/handlers/base.py", line 7 in <module>
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 883 in exec_module
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/ddtrace/internal/module.py", line 220 in _exec_module
  File "<frozen importlib._bootstrap>", line 688 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1006 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1027 in _find_and_load
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/litestar/handlers/asgi_handlers.py", line 6 in <module>
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 883 in exec_module
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/ddtrace/internal/module.py", line 220 in _exec_module
  File "<frozen importlib._bootstrap>", line 688 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1006 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1027 in _find_and_load
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/litestar/handlers/__init__.py", line 1 in <module>
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 883 in exec_module
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/ddtrace/internal/module.py", line 220 in _exec_module
  File "<frozen importlib._bootstrap>", line 688 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1006 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1027 in _find_and_load
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 992 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1027 in _find_and_load
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/litestar/controller.py", line 11 in <module>
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 883 in exec_module
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/ddtrace/internal/module.py", line 220 in _exec_module
  File "<frozen importlib._bootstrap>", line 688 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1006 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1027 in _find_and_load
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/litestar/openapi/controller.py", line 9 in <module>
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 883 in exec_module
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/ddtrace/internal/module.py", line 220 in _exec_module
  File "<frozen importlib._bootstrap>", line 688 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1006 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1027 in _find_and_load
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/litestar/openapi/config.py", line 7 in <module>
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 883 in exec_module
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/ddtrace/internal/module.py", line 220 in _exec_module
  File "<frozen importlib._bootstrap>", line 688 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1006 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1027 in _find_and_load
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/litestar/openapi/__init__.py", line 1 in <module>
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 883 in exec_module
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/ddtrace/internal/module.py", line 220 in _exec_module
  File "<frozen importlib._bootstrap>", line 688 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1006 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1027 in _find_and_load
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 992 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1027 in _find_and_load
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 992 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1027 in _find_and_load
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/litestar/_openapi/parameters.py", line 8 in <module>
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 883 in exec_module
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/ddtrace/internal/module.py", line 220 in _exec_module
  File "<frozen importlib._bootstrap>", line 688 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1006 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1027 in _find_and_load
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/litestar/_openapi/path_item.py", line 6 in <module>
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 883 in exec_module
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/ddtrace/internal/module.py", line 220 in _exec_module
  File "<frozen importlib._bootstrap>", line 688 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1006 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1027 in _find_and_load
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/litestar/app.py", line 15 in <module>
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 883 in exec_module
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/ddtrace/internal/module.py", line 220 in _exec_module
  File "<frozen importlib._bootstrap>", line 688 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1006 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1027 in _find_and_load
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/litestar/__init__.py", line 1 in <module>
  File "<frozen importlib._bootstrap>", line 241 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 883 in exec_module
  File "/Users/andenacitelli/litestar-ddtrace-repro/venv/lib/python3.10/site-packages/ddtrace/internal/module.py", line 220 in _exec_module
  File "<frozen importlib._bootstrap>", line 688 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1006 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1027 in _find_and_load
  ...

Extension modules: psutil._psutil_osx, psutil._psutil_posix, ddtrace.internal._encoding, ddtrace.internal._rand, ddtrace.internal._tagset, msgspec._core, yaml._yaml, multidict._multidict (total: 8)
[1]    8377 segmentation fault  pytest .

Litestar Version

2.1.1

Running on M2 Mac, Apple Silicon. I mention because it's been a likely cause of segfaults in lots of machine learning code, so I wouldn't be surprised if that's the case here too.

Platform


Funding

Fund with Polar

anden-akkio commented 12 months ago

Found a temporary workaround for this by disabling the several pytest plugins that ddtrace injects. We don't care about them, just need ddtrace itself installed and running, so it's not a big deal. However, this will still need fixed for those that want to use Litestar and ddtrace's pytest integration together, especially because this is the default behavior. I'd imagine most people that install them together will get confused and find this issue.

[tool.pytest.ini_options]
addopts = [
  "-p no:ddtrace",
  "-p no:ddtrace.pytest_bdd",
  "-p no:ddtrace.pytest_benchmark"
]
provinzkraut commented 6 months ago

This seems to be an issue with multidict and ddtrace, as it's multidict that's segfaulting here. @anden-akkio if this persists for you, I'd recommend opening an issue at their repo.