diff --git a/ddtrace/internal/_threads.cpp b/ddtrace/internal/_threads.cpp index d775544827b..efbcceddf0e 100644 --- a/ddtrace/internal/_threads.cpp +++ b/ddtrace/internal/_threads.cpp @@ -128,6 +128,7 @@ typedef struct periodic_thread double interval; PyObject* name; PyObject* ident; + PyObject* native_id; PyObject* _target; PyObject* _on_shutdown; @@ -159,6 +160,7 @@ static PyMemberDef PeriodicThread_members[] = { { "name", T_OBJECT_EX, offsetof(PeriodicThread, name), 0, "thread name" }, { "ident", T_OBJECT_EX, offsetof(PeriodicThread, ident), 0, "thread ID" }, + { "native_id", T_OBJECT_EX, offsetof(PeriodicThread, native_id), 0, "thread native ID" }, { "_ddtrace_profiling_ignore", T_OBJECT_EX, @@ -189,6 +191,9 @@ PeriodicThread_init(PeriodicThread* self, PyObject* args, PyObject* kwargs) Py_INCREF(Py_None); self->ident = Py_None; + Py_INCREF(Py_None); + self->native_id = Py_None; + Py_INCREF(Py_True); self->_ddtrace_profiling_ignore = Py_True; @@ -257,6 +262,13 @@ PeriodicThread_start(PeriodicThread* self, PyObject* args) Py_DECREF(self->ident); self->ident = PyLong_FromLong((long)PyThreadState_Get()->thread_id); + Py_DECREF(self->native_id); +#if PY_VERSION_HEX >= 0x030b0000 + self->native_id = PyLong_FromLong((long)PyThreadState_Get()->native_thread_id); +#else // PY_VERSION_HEX < 0x030b0000 + self->native_id = PyLong_FromLong((long)PyThread_get_thread_native_id()); +#endif // PY_VERSION_HEX >= 0x030b0000 + // Map the PeriodicThread object to its thread ID PyDict_SetItem(_periodic_threads, self->ident, (PyObject*)self); } @@ -469,6 +481,7 @@ PeriodicThread_dealloc(PeriodicThread* self) Py_XDECREF(self->_on_shutdown); Py_XDECREF(self->ident); + Py_XDECREF(self->native_id); Py_XDECREF(self->_ddtrace_profiling_ignore); self->_thread = nullptr; diff --git a/ddtrace/internal/_threads.pyi b/ddtrace/internal/_threads.pyi index 84a6ca0eb3f..face7cc765e 100644 --- a/ddtrace/internal/_threads.pyi +++ b/ddtrace/internal/_threads.pyi @@ -3,6 +3,7 @@ import typing as t class PeriodicThread: name: str ident: int + native_id: int interval: float def __init__( diff --git a/tests/profiling_v2/collector/test_stack.py b/tests/profiling_v2/collector/test_stack.py index 99cae2a3f17..a1c87b6b96d 100644 --- a/tests/profiling_v2/collector/test_stack.py +++ b/tests/profiling_v2/collector/test_stack.py @@ -664,9 +664,6 @@ def test_max_time_usage_over(): [True, False], ) def test_ignore_profiler(stack_v2_enabled, ignore_profiler, tmp_path): - if stack_v2_enabled: - pytest.xfail("Echion doesn't support ignore_profiler yet, and the test flakes") - test_name = "test_ignore_profiler" pprof_prefix = str(tmp_path / test_name) output_filename = pprof_prefix + "." + str(os.getpid())