なんで新しいdebug.gem が必要なの？
Koichi Sasada<ko1@cookpad.com>

1About this talk• Introduce “debug.gem” https://github.com/ruby/debug• Newly created debugger for Ruby 2.6 and later• Will be bundled with Ruby 3.1 (Dec/2021)• Demonstrate “debug.gem”• Basic usage instructions• Advanced features• The presentation slides with the talk script is available at here:
https://www.atdot.net/~ko1/activities/2

About Koichi Sasada• Ruby interpreter developer employed byCookpad Inc. (2017-) with @mame• YARV (Ruby 1.9-)• Generational/Incremental GC (Ruby 2.1-)• Ractor (Ruby 3.0-)•…

• Ruby Association Director (2012-)

3

What is a debugger?
• A tool to help debugging• To investigate the cause of problems• To know the program live state• To understand the program• Basic features• CONTROL execution• STOP at breakpoints• STEP forward to the next line
• …

• QUERY program status
4

Ruby’s existing debuggers• lib/debug.rb• ruby -r debug script.rb• Standard library, but maybe nobody uses it• byebug• byebug script.rb• debase / ruby-debug-ide• Used by IDE (rubymine, vscode, …)

5

Why create yet another debugger?
• Performance• Existing debuggers slow with breakpoints• Recent TracePoint API support line-specific• Native support for remote execution and IDE• Native support for Ractors• (and I like to make this kind of tools)

6Introduction of“debug.gem”
https://github.com/ruby/debug

7

All information are explained in
https://github.com/ruby/debug

8debug.gem• Created from scratch (2021 Feb~)• Supports Ruby 2.6 and later• Utilize recent introduced APIs

• Ruby 3.1 (2021/Dec) will be shipped with debug.gem• Replacement with old lib/debug.rb• Like other libraries (lib/debug.rb, byebug, gdb, lldb, …)
debug.gem provides REPL to execute debug commands

9Performancedef fib n
if n < 0raise # breakpoint
elsif n<2nelse
fib(n-1)+fib(n-2)
end
endrequire 'benchmark'Benchmark.bm{|x|x.report{ fib(35) }}Without
breakpoint
ruby

With breakpoint
0.93

N/Ardbg (debug.gem)

0.92 (x0.98)

0.92 (x0.98)

byebug1.23 (x1.32)

75.15 (x80.80)

RubyMine0.97 (x1.04)

22.66 (x24.36)

221.88 (x238.58)

285.99 (x307.51)

old lib/debug.rb

Execution time in sec (ratio with ruby result (smaller is better))ruby 3.0.1p64
rdbg 1.0.0.rc2
byebug 11.1.3
RubyMine 2021.2.1 w/ debase 0.2.5.beta2
Intel(R) Core(TM) i7-10810U CPU, Windows 10, WSL210

Use debug.gem
1. Use “rdbg” command• rdbg target.rb• rdbg –c -- bin/rails• rdbg –c -- bundle exec rake

2. Load “debug.gem” in your application• require “debug” (or “debug/…”, see doc)
• gem ‘debug’ in Gemfile (and Bundler.require)

3. Use with IDE• (VSCode) .vscode/launch.json (ruby-rdbg extension will make) andpush “Start debugging” button
11Demo: Basic usage

12

13

Basic features• Control the program execution• Set breakpoints• Step execution (step-in/over/out)• Query the program status• See the source code at breakpoint• See the backtrace• Select the frame in backtrace• Access to variables of the specific frames• Evaluate an expression on the specific frame

14

Set a breakpoint• Use “break” command at the beginning• break 10 # break at 10 line on current file• break foo.rb:10 # break at the location• break MyClass#my_method # break at the method• catch FooException # break at FooException is raised• break … if foo == bar # break if foo == bar• Write “binding.break” line in your program• You can insert it like “binding.irb”• “binding.b” for short and “debugger” like JavaScript• Use IDEs/editors breakpoint support
15

Set a breakpoint (cont.)• Use “break” command at the beginning (and IDE)
• Do not need to modify the source code
• Cooperation with IDE/Editor (e.g. set it with F9 on VSCode)• Write “binding.break” method in your program• Straight forward for some Ruby users

16

Control debugger from the program bybinding.break do: expr
# enable “trace line” feature while bar()def foobinding.break do: ‘trace line’bar()biding.break do: ‘trace off line’end

17Step execution
Step-in, Step-over, Step-out
def foo(a)bar()(2) step-overbaz()boo()
Step-overend(“next” command)Stop at next line

Step-in(“step” command)
Stop at next breakable line(3) step-out(1) step-infoo(1)
foo(2)

Step-out(“finish” command)
Stop at outer frame
18

Access to the local variables in the specificframe• See the backtrace with “backtrace”• Select the frame• “frame <num>”• “up” / “down” to select upper/lower• Access to the frame local variables• “outline” command and “info”
command for overview• “p <expr>” and “pp <expr>”

19

Advanced features• [demo] Pause with “Ctrl-C” or when attaching the debugger• [demo] VSCode/Chrome browser seamless integration• [demo] Remote debugging• [demo] Postmortem debugging• [demo] Record and replay debugging• [demo] Multi-process debugging• [demo?] Event tracing

20

Demo: Pause with “Ctrl-C” or when
attaching the debugger• You can see the current execution status with the debugger

21

Demo: Seamless integration with
VSCode/Chrome browser

22

Demo: Seamless integration with
VSCode/Chrome browser

23

Demo: Start VSCode for debugger frontend

24

Demo: Remote debugging
Connect over network• Easy to open remote debug port and attach• rdbg --open script.rb (or rdbg –O)• Run program with opening debug port
• require ‘debug/open’ # in script• rdbg –attach (or rdbg –A)• Access to debug port

• Debug no TTY attached processes• Daemon processes• Redirecting by shell’s pipe

• Query the process status like sigdump but moredetails
25

26

Same machineprocess

Cross machineprocess

UNIX Domain socket

debugger

VSCode/Chrome

VSCodecross machineprocess

process

debuggerdebugger

TCP/IPvscode client

debugger

VSCode/Chromessh
VSCodeDemo: Postmortem debugging
Debug dead Ruby process28

Demo: Record and replay debugging
Backward stepping execution

29

30

Demo: Multi-process debugging• You can debug multiple processes (fork family) with onedebugger• Prompt shows which process• Only one process can be operated by the debug console at the same
time

31

Acknowledgements• Naoto Ono san (@ono-max) implements test-frameworks forthe debugger and Chrome browser support. The part ofworks were done in GSoC project.
• Stan Lo san (@st0012) submits tremendous patches toimprove the debugger usability such as coloring and so on
based on his debugger trials. Also, he makes many tests forthe debugger.
• Ruby committers helps me to design and implement thedebugger

32

Conclusion• “debug.gem” is newly created Ruby debugger from scratch• Faster.
• Modern UI.
• Many useful features.

• “gem install debug” now!
• And give us your feedback.
• I love to introduce the debugger on your meetup, please contact me.

• Ractor supports is not available, now working on.

33

Thank you for your listening!

なんで新しいdebug.gem が必要なの？
Koichi Sasada<ko1@cookpad.com>

34