Performance issue when stepping through a deep callstack
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 30/100
- Tipo de issue
- Error
- Claridad
- Bastante claro
- Estado de actividad
- Estancado
- Área
- devtools, performance
Línea de trabajo
Start at ext/debug/debug.c lines 92-98 and inspect how rb_make_backtrace is used while stepping through a deep callstack. Compare the proposed rb_threadptr_backtrace_object and debase approaches, including their *_core.h requirements. Done means stepping through roughly 150 calls no longer incurs the reported slowdown and memory pressure.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Your environment
ruby -v: 2.7.2p137rdbg -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: https://github.com/ruby/debug/blob/296daa6742e114395a4ce336b8721d48a6e5e52f/ext/debug/debug.c#L92-L98
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):
- Use
rb_threadptr_backtrace_objectto skip the formatting of the backtrace, saving some extra memory (but still generating more than necessary) debasesolves 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)
- Lenguaje dominante
- Ruby
- Estrellas
- 1.3k
- Forks
- 146
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de ruby/debug
-
Dificultad 3/5 1-2 días Aptitud para principiantes 68/100
-
Support exceptionOptions in setExceptionBreakpoints to catch arbitrary exception classes via DAP Abierto
Dificultad 4/5 3-5 días Aptitud para principiantes 55/100
-
Dificultad 3/5 1-2 días Aptitud para principiantes 45/100
-
Dificultad 4/5 3-5 días Aptitud para principiantes 52/100
-
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
Todos los issues de ruby/debug
Issues similares
-
SyncEm always forwards a dummy block, so wrapped methods lose their no-block/Enumerator behavior Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
endoflife-date/endoflife.date#11086 ·
-
internal
Dificultad 1/5 Menos de una hora Aptitud para principiantes 88/100
Kong/developer.konghq.com#7322 ·
-
bug P2
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100