From f9ac3d135f8d1c614f756a4e77e6997836d3fd55 Mon Sep 17 00:00:00 2001 From: "Gabriele N. Tornetta" Date: Wed, 3 May 2023 19:20:07 +0100 Subject: [PATCH] fix(profiler): do not unload google.protobuf in module clean-up (#5747) When cleaning up the modules as part of the support for gevent, we also unload google.protobuf. However, starting with version 4.21, the new default upb backend does not tolerate being unloaded, which resulted in segfaults in applications with a runtime dependency on protobuf. (cherry picked from commit e98cb9180a0157900b1f702f20c8e4af62eed3de) --- ddtrace/bootstrap/sitecustomize.py | 13 ++++++++++++- ...fault-in-protobuf-apps-032558829864cdfe.yaml | 5 +++++ tests/profiling/test_main.py | 17 +++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/fix-profiler-segfault-in-protobuf-apps-032558829864cdfe.yaml diff --git a/ddtrace/bootstrap/sitecustomize.py b/ddtrace/bootstrap/sitecustomize.py index 35dcdbd4e96..2fe779dbe97 100644 --- a/ddtrace/bootstrap/sitecustomize.py +++ b/ddtrace/bootstrap/sitecustomize.py @@ -121,7 +121,18 @@ def drop(module_name): # uses a copy of that module that is distinct from the copy that user code # gets when it does `import threading`. The same applies to every module # not in `KEEP_MODULES`. - KEEP_MODULES = frozenset(["atexit", "ddtrace", "asyncio", "concurrent", "typing", "logging", "attr"]) + KEEP_MODULES = frozenset( + [ + "atexit", + "ddtrace", + "asyncio", + "concurrent", + "typing", + "logging", + "attr", + "google.protobuf", # the upb backend in >= 4.21 does not like being unloaded + ] + ) if PY2: KEEP_MODULES_PY2 = frozenset(["encodings", "codecs"]) for m in list(_ for _ in sys.modules if _ not in LOADED_MODULES): diff --git a/releasenotes/notes/fix-profiler-segfault-in-protobuf-apps-032558829864cdfe.yaml b/releasenotes/notes/fix-profiler-segfault-in-protobuf-apps-032558829864cdfe.yaml new file mode 100644 index 00000000000..ba000c18506 --- /dev/null +++ b/releasenotes/notes/fix-profiler-segfault-in-protobuf-apps-032558829864cdfe.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + profiler: Fixed a bug that caused segmentation faults in applications that + use protobuf as a runtime dependency. diff --git a/tests/profiling/test_main.py b/tests/profiling/test_main.py index 36c228268ef..c535861fd06 100644 --- a/tests/profiling/test_main.py +++ b/tests/profiling/test_main.py @@ -124,3 +124,20 @@ def test_memalloc_no_init_error_on_fork(): if not pid: exit(0) os.waitpid(pid, 0) + + +@pytest.mark.subprocess( + ddtrace_run=True, + env=dict( + DD_PROFILING_ENABLED="1", + DD_UNLOAD_MODULES_FROM_SITECUSTOMIZE="1", + ), + out="OK\n", + err=None, +) +def test_profiler_start_up_with_module_clean_up_in_protobuf_app(): + # This can cause segfaults if we do module clean up with later versions of + # protobuf. This is a regression test. + from google.protobuf import empty_pb2 # noqa + + print("OK")