Skip to content

Performance issue when stepping through a deep callstack #760

@marianosimone

Description

@marianosimone

Your environment

  • ruby -v: 2.7.2p137
  • rdbg -v: 1.6.2

Describe the bug
When stepping through with a deep callstack, the debugger becomes slower with each step.

To Reproduce
In a codebase which has a method that's ~150 calls deep in the stack, add a breakpoint, debug, and step through.

Expected behavior
It wouldn't be slow

Additional context
We are facing this issue at Stripe, and we tracked down the problem to:

debug/ext/debug/debug.c

Lines 92 to 98 in 296daa6

static VALUE
frame_depth(VALUE self)
{
// TODO: more efficient API
VALUE bt = rb_make_backtrace();
return INT2FIX(RARRAY_LEN(bt));
}

This seems to be generating the full backtrace through rb_make_backtrace, just to then take the size. rb_make_backtrace (source) generates an array of strings each time it's called. Those strings end up not being used, and after a couple of iterations, you end up with a big memory footprint, which causes the GC to collect them, significantly slowing down the debugger.

Luckily, it looks like you are already aware that this is inefficient (given the // TODO: more efficient API) :)

Looking into alternatives, I came up with a couple of options (but open to any other ideas):

  1. Use rb_threadptr_backtrace_object to skip the formatting of the backtrace, saving some extra memory (but still generating more than necessary)
  2. debase solves this with a different approach: https://github.com/ruby-debug/debase/blob/5780803819f16190ce50ddfdad5775acf8f95fd1/ext/hacks.h#L26

Both of them, though, require the inclusion of *_core.h, which is not currently possible (debase solves it by using its own version of ruby_core_source)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions