Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
535b023
temp! attempt to fix
KowalskiThomas Dec 17, 2025
b01c5c2
fixup! temp! attempt to fix
KowalskiThomas Dec 17, 2025
2ba047c
fixup! fixup! temp! attempt to fix
KowalskiThomas Dec 17, 2025
73aa315
fixup! fixup! fixup! temp! attempt to fix
KowalskiThomas Dec 17, 2025
28515a0
fixup! fixup! fixup! fixup! temp! attempt to fix
KowalskiThomas Dec 17, 2025
719a5ad
fixup! fixup! fixup! fixup! fixup! temp! attempt to fix
KowalskiThomas Dec 17, 2025
59ac5f8
fixup! fixup! fixup! fixup! fixup! fixup! temp! attempt to fix
KowalskiThomas Dec 17, 2025
aacca14
fixup! fixup! fixup! fixup! fixup! fixup! fixup! temp! attempt to fix
KowalskiThomas Dec 17, 2025
246ff60
fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! temp! attempt…
KowalskiThomas Dec 17, 2025
c1c97b1
fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! temp! …
KowalskiThomas Dec 17, 2025
e62e96d
fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup!…
KowalskiThomas Dec 17, 2025
d8bb6be
fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup!…
KowalskiThomas Dec 18, 2025
dd5bbe8
fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup!…
KowalskiThomas Dec 18, 2025
c4107d1
fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup!…
KowalskiThomas Dec 18, 2025
79d9b85
fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup!…
KowalskiThomas Dec 18, 2025
0bac720
fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup!…
KowalskiThomas Dec 18, 2025
104f290
fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup!…
KowalskiThomas Dec 18, 2025
d075427
cancel stack changes
KowalskiThomas Dec 18, 2025
3b73a1e
fixup! cancel stack changes
KowalskiThomas Dec 18, 2025
b6d5821
fixup! fixup! cancel stack changes
KowalskiThomas Dec 20, 2025
2bd69ee
fixup! fixup! fixup! cancel stack changes
KowalskiThomas Dec 20, 2025
a7bfce9
fixup! fixup! fixup! fixup! cancel stack changes
KowalskiThomas Dec 20, 2025
e9ac96d
fixup! fixup! fixup! fixup! fixup! cancel stack changes
KowalskiThomas Dec 20, 2025
ba48bc5
fixup! fixup! fixup! fixup! fixup! fixup! cancel stack changes
KowalskiThomas Dec 20, 2025
bab34b3
fixup! fixup! fixup! fixup! fixup! fixup! fixup! cancel stack changes
KowalskiThomas Dec 20, 2025
cd64bea
fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! cancel stack …
KowalskiThomas Dec 21, 2025
185a9a8
fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! cancel…
KowalskiThomas Dec 21, 2025
dd69fc7
no strict aliasing
KowalskiThomas Dec 21, 2025
24b04a2
fixup! no strict aliasing
KowalskiThomas Dec 21, 2025
712b840
fixup! fixup! no strict aliasing
KowalskiThomas Dec 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 50 additions & 4 deletions ddtrace/internal/datadog/profiling/stack/echion/echion/tasks.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,19 @@ class TaskInfo
typedef std::unique_ptr<TaskInfo> Ptr;
typedef std::reference_wrapper<TaskInfo> Ref;

// The address of the Task PyObject* the TaskInfo represents
PyObject* origin = NULL;

// The address of the asyncio Event Loop PyObject* the Task is running on
PyObject* loop = NULL;

StringTable::Key name;

// Whether the Task's coroutine (or a coroutine it awaits, transitively) is currently running (on CPU).
// This will not be true if the Task is currently awaiting another Task, and this other Task is on CPU.
bool is_on_cpu = false;

// The Task's "root" coroutine
GenInfo::Ptr coro = nullptr;

// Information to reconstruct the async stack as best as we can
Expand Down Expand Up @@ -289,34 +297,72 @@ inline Result<size_t>
TaskInfo::unwind(FrameStack& stack)
{
// TODO: Check for running task.
uint64_t c1 = 0x1111111111111111ULL;
std::stack<PyObject*> coro_frames;
uint64_t c2 = 0x2222222222222222ULL;

// Unwind the coro chain
// Detect cycles in the await chain to prevent infinite loops.
// This can happen if the Profiler samples during as the Task is running,
// or due to memory corruption/race conditions when reading coroutine pointers.
std::unordered_set<GenInfo*> seen_coros;
std::unordered_set<size_t> pure_coro_frames;
for (auto py_coro = this->coro.get(); py_coro != NULL; py_coro = py_coro->await.get()) {
if (seen_coros.find(py_coro) != seen_coros.end()) {
break;
}

seen_coros.insert(py_coro);

if (py_coro->frame != NULL) {
coro_frames.push(py_coro->frame);
auto py_coro_frame = py_coro->frame;
if (py_coro_frame != NULL) {
// Inserting only non-NULL frames
coro_frames.push(py_coro_frame);
// if (coro_frames.top() == nullptr) {
// std::cerr << "Pushed a non-null frame to the stack, but the top is null." << std::endl;
// std::abort();
// }
}
}

if (c1 != 0x1111111111111111ULL) {
std::cerr << "c1 is not 0x1111111111111111ULL. This should not happen." << std::endl;
std::abort();
}
if (c2 != 0x2222222222222222ULL) {
std::cerr << "c2 is not 0x2222222222222222ULL. This should not happen." << std::endl;
std::abort();
}

// Total number of frames added to the Stack
size_t count = 0;

// Unwind the coro frames
// Unwind the coro frames (iterate in reverse since we pushed in await-chain order)
size_t stack_index = 0;
while (!coro_frames.empty()) {
PyObject* frame = coro_frames.top();

// if (frame == nullptr) {
// // THIS ACTUALLY HAPPENS, IT SHOULD NOT.
// std::cerr << "Received a nullptr frame from the coroutine chain (before pop). This should not happen."
// << std::endl;
// std::abort();
// }

coro_frames.pop();

// if (frame == nullptr) {
// // THIS ACTUALLY HAPPENS, IT SHOULD NOT.
// std::cerr << "Received a nullptr frame from the coroutine chain. This should not happen." << std::endl;
// std::abort();
// }

if (frame == nullptr) {
std::cerr << "Received a nullptr frame from the coroutine chain at index " << stack_index
<< ". This should not happen." << std::endl;
std::abort();
}
stack_index++;

auto new_frames = unwind_frame(frame, stack);

// If we failed to unwind the Frame, stop unwinding the coroutine chain; otherwise we could
Expand Down
5 changes: 5 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,11 @@ def get_exts_for(name):
STACK_DIR / ".." / "cmake",
STACK_DIR / ".." / "dd_wrapper",
],
cmake_args=[
"-DCMAKE_C_FLAGS=-fno-strict-aliasing -O1",
"-DCMAKE_CXX_FLAGS=-fno-strict-aliasing -O1",
"-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF",
],
optional=False,
),
)
Expand Down
Loading