Skip to content

Commit 3a46ae6

Browse files
perf(profiling): unwind only one Frame per Task
1 parent 61b1799 commit 3a46ae6

File tree

2 files changed

+9
-19
lines changed

2 files changed

+9
-19
lines changed

ddtrace/internal/datadog/profiling/stack/echion/echion/stacks.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ inline FrameStack python_stack;
4444

4545
// ----------------------------------------------------------------------------
4646
static size_t
47-
unwind_frame(PyObject* frame_addr, FrameStack& stack)
47+
unwind_frame(PyObject* frame_addr, FrameStack& stack, size_t max_depth = 0)
4848
{
4949
std::unordered_set<PyObject*> seen_frames; // Used to detect cycles in the stack
50-
int count = 0;
50+
size_t count = 0;
5151

5252
PyObject* current_frame_addr = frame_addr;
5353
while (current_frame_addr != NULL && stack.size() < max_frames) {
@@ -72,6 +72,10 @@ unwind_frame(PyObject* frame_addr, FrameStack& stack)
7272

7373
stack.push_back(*maybe_frame);
7474
count++;
75+
76+
if (max_depth > 0 && count >= max_depth) {
77+
break;
78+
}
7579
}
7680

7781
return count;

ddtrace/internal/datadog/profiling/stack/echion/echion/tasks.h

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -321,29 +321,15 @@ TaskInfo::unwind(FrameStack& stack)
321321
PyObject* frame = coro_frames.top();
322322
coro_frames.pop();
323323

324-
auto new_frames = unwind_frame(frame, stack);
324+
auto new_frames = unwind_frame(frame, stack, 1);
325+
assert(new_frames <= 1 && "expected exactly 1 frame to be unwound (or 0 in case of an error)");
325326

326327
// If we failed to unwind the Frame, stop unwinding the coroutine chain; otherwise we could
327328
// end up with Stacks with missing Frames between two coroutines Frames.
328329
if (new_frames == 0) {
329330
break;
330331
}
331-
332-
// If this is the first Frame being unwound (we have not added any Frames to the Stack yet),
333-
// use the number of Frames added to the Stack to determine the size of the upper Python stack.
334-
if (count == 0) {
335-
// The first Frame is the coroutine Frame, so the Python stack size is the number of Frames - 1
336-
auto upper_python_stack_size = new_frames - 1;
337-
338-
// Remove the Python Frames from the Stack (they will be added back later)
339-
// We cannot push those Frames now because otherwise they would be added once per Task,
340-
// we only want to add them once per Leaf Task, and on top of all non-leaf Tasks.
341-
for (size_t i = 0; i < upper_python_stack_size; i++) {
342-
stack.pop_back();
343-
}
344-
}
345-
346-
count += new_frames;
332+
count += 1;
347333
}
348334

349335
return count;

0 commit comments

Comments
 (0)