This library provides debugging functionality to Ruby (MRI) 2.7 and later.
This debug.rb is the replacement of traditional lib/debug.rb standard library, which is implemented by set_trace_func.
New debug.rb has several advantages:
Fast: No performance penalty on non-stepping mode and non-breakpoints.
Remote debugging: Support remote debugging natively.
UNIX domain socket (UDS)
TCP/IP
Integration with rich debugger frontends
| Frontend | Console | VSCode | Chrome DevTool |
|---|---|---|---|
| Connection | UDS, TCP/IP | UDS, TCP/IP | TCP/IP |
| Requirement | None | vscode-rdbg | Chrome |
Extensible: application can introduce debugging support in several ways:
rdbg command-r command line optionMisc
Ctrl-C at most of timing.$ gem install debug
Alternatively, specify -Ipath/to/debug/lib in RUBYOPT, or as a Ruby command-line option
This is especially useful for debugging this gem during development.
If using Bundler, add the following to your Gemfile:
gem "debug", ">= 1.0.0"
(The version constraint is important; debug < 1.0.0 is an older, abandoned gem that is completely different from this product.)
To use the debugger, you will do roughly the following steps:
p lvar to see the local variable lvar).info to see information about the current frame).step, to the next line with next).catch Exception to set a breakpoint that'll be triggered when Exception is raised).trace call to trace method calls).config set no_color true to disable coloring).c or continue) and goto 3.There are several ways to invoke the debugger, depending on your needs, preferences, and the environment.
binding.break (similar to binding.pry or binding.irb)If you can modify the source code, you can use the debugger by adding require 'debug' at the top of your program and putting binding.break method into lines where you want to stop as breakpoints.
This is similar to how binding.pry and binding.irb work.
binding.break has two aliases which do the same thing:
binding.bdebuggerAfter that, run the program as usual and you will enter the debug console at breakpoints you inserted.
The following is an example of the binding.break method.
$ cat target.rb # Sample program
require 'debug'
a = 1
b = 2
binding.break # Program will stop here
c = 3
d = 4
binding.break # Program will stop here
p [a, b, c, d]
$ ruby target.rb # Run the program normally.
DEBUGGER: Session start (pid: 7604)
[1, 10] in target.rb
1| require 'debug'
2|
3| a = 1
4| b = 2
=> 5| binding.break # Now you can see it stops at this line
6| c = 3
7| d = 4
8| binding.break
9| p [a, b, c, d]
10|
=>#0 <main> at target.rb:5
(rdbg) info locals # You can show local variables
=>#0 <main> at target.rb:5
%self => main
a => 1
b => 2
c => nil
d => nil
(rdbg) continue # Continue the execution
[3, 11] in target.rb
3| a = 1
4| b = 2
5| binding.break
6| c = 3
7| d = 4
=> 8| binding.break # Again the program stops here
9| p [a, b, c, d]
10|
11| __END__
=>#0 <main> at target.rb:8
(rdbg) info locals # And you can see the updated local variables
=>#0 <main> at target.rb:8
%self => main
a => 1
b => 2
c => 3
d => 4
(rdbg) continue
[1, 2, 3, 4]
If you don't want to modify the source code, you can use the rdbg command (or bundle exec rdbg) to run the program with the debugger.
This is similar to how you'd launch a program with ruby program.rb.
Then you can set breakpoints with the debug command break (b for short).
$ cat target.rb # Sample program
a = 1
b = 2
c = 3
d = 4
p [a, b, c, d]
$ rdbg target.rb # run like `ruby target.rb`
DEBUGGER: Session start (pid: 7656)
[1, 7] in target.rb
=> 1| a = 1
2| b = 2
3| c = 3
4| d = 4
5| p [a, b, c, d]
6|
7| __END__
=>#0 <main> at target.rb:1
(rdbg)
The rdbg command suspends the program at the beginning of the given script (target.rb in this case) and you can use debug commands to control execution from there.
(rdbg) is the console prompt.
Let's set breakpoints on line 3 and line 5 with break command (b for short).
(rdbg) break 3 # set breakpoint at line 3
#0 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:3 (line)
(rdbg) b 5 # set breakpoint at line 5
#1 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:5 (line)
(rdbg) break # show all registered breakpoints
#0 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:3 (line)
#1 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:5 (line)
You can see that two breakpoints are registered.
Let's continue the program by using the continue command.
(rdbg) continue
[1, 7] in target.rb
1| a = 1
2| b = 2
=> 3| c = 3
4| d = 4
5| p [a, b, c, d]
6|
7| __END__
=>#0 <main> at target.rb:3
Stop by #0 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:3 (line)
(rdbg)
You can see that we stopped at line 3.
Let's see the local variables with the info command, and continue execution with the continue.
The program will then suspend at line 5 and you can use the info command again.
(rdbg) info
=>#0 <main> at target.rb:3
%self => main
a => 1
b => 2
c => nil
d => nil
(rdbg) continue
[1, 7] in target.rb
1| a = 1
2| b = 2
3| c = 3
4| d = 4
=> 5| p [a, b, c, d]
6|
7| __END__
=>#0 <main> at target.rb:5
Stop by #1 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:5 (line)
(rdbg) info
=>#0 <main> at target.rb:5
%self => main
a => 1
b => 2
c => 3
d => 4
(rdbg) continue
[1, 2, 3, 4]
NOTE: When using rdbg you can suspend your application with C-c (SIGINT) and enter the debug console.
It will help if you want to know what the program is doing.
rdbg with commands written in RubyIf you want to run an executable written in Ruby like rake, rails, bundle, rspec, and so on, you can use rdbg -c option.
-c option, rdbg <name> means that <name> is a Ruby script and it is invoked like ruby <name> with the debugger.-c option, rdbg -c <name> means that <name> is an executable in PATH and simply invokes it with the debugger.Examples:
rdbg -c -- rails serverrdbg -c -- bundle exec ruby foo.rbrdbg -c -- bundle exec rake testrdbg -c -- ruby target.rb is the same as rdbg target.rbNOTE: -- is needed to separate the command line options for rdbg from the executable being invoked, and its options.
For example, rdbg -c rake -T would be parsed as rdbg -c -T -- rake, which is incorrect.
It should be rdbg -c -- rake -T.
NOTE: If you want to use Bundler (bundle executable), you need to add gem 'debug' to your Gemfile.
Like other languages, you can use this debugger on the VSCode.
.rb file (e.g. target.rb)rdbg -c, and VSCode shows the details at breakpoints.Please refer to Debugging in Visual Studio Code for operations on VSCode.
You can configure the extension in .vscode/launch.json.
Please see the extension page for more details.
You can use this debugger as a remote debugger. For example, it will help in the following situations:
binding.pry or binding.irb.
STDIN or STDOUT.You can run your application as a remote debuggee, and the remote debugger console can attach to the debuggee anytime.
There are multiple ways to run your program as a debuggee:
| Stop at program start | rdbg option | require | debugger API |
|---|---|---|---|
| Yes | rdbg --open | require "debug/open" | DEBUGGER__.open |
| No | rdbg --open --nonstop | require "debug/open_nonstop" | DEBUGGER__.open(nonstop: true) |
rdbg --open (or rdbg -O for short)Launch a script with rdbg --open target.rb to run target.rb as a debuggee program.
It also opens the network port and suspends at the beginning of target.rb.
$ rdbg --open target.rb
DEBUGGER: Session start (pid: 7773)
DEBUGGER: Debugger can attach via UNIX domain socket (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-7773)
DEBUGGER: wait for debugger connection...
By default, rdbg --open uses UNIX domain socket and generates the path name automatically (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-7773 in this case).
You can connect to the debuggee with rdbg --attach command (rdbg -A for short).
$ rdbg -A
[1, 7] in target.rb
=> 1| a = 1
2| b = 2
3| c = 3
4| d = 4
5| p [a, b, c, d]
6|
7| __END__
=>#0 <main> at target.rb:1
(rdbg:remote)
If there are no other files in the default directory, rdbg --attach will automatically connect to the UNIX domain socket listed.
If there are multiple files, you need to specify which to use.
When rdbg --attach connects to the debuggee, you can use any debug commands (set breakpoints, continue the program, and so on) like the local debug console.
When a debuggee program exits, the remote console will also terminate.
NOTE: If you use the quit command, only the remote console exits and the debuggee program continues to run (and you can connect it again).
If you want to exit the debuggee program, use kill command.
If you want to use TCP/IP for remote debugging, you need to specify the port and host with --port like rdbg --open --port 12345 and it binds to localhost:12345.
You can add an optional --port_range to try multiple ports in a reliable way.
For example, rdbg --open --port 12345 --port_range 10 will try to bind to 12345, 12346, 12347,… until it finds an available port.
To connect to the debuggee, you need to specify the port.
$ rdbg --attach 12345
If you want to choose the host to bind, you can use --host option.
Messages communicated between the debugger and the debuggee are NOT encrypted so please use remote debugging carefully.
require 'debug/open' in a programIf you can modify the program, you can open the debugging port by adding require 'debug/open' in the program.
If you don't want to stop the program at the beginning, you can also use require 'debug/open_nonstop'.
Using debug/open_nonstop is useful if you want to open a backdoor to the application.
However, it is also dangerous because it can become another vulnerability.
Please use it carefully.
By default, UNIX domain socket is used for the debugging port.
To use TCP/IP, you can set the RUBY_DEBUG_PORT environment variable.
$ RUBY_DEBUG_PORT=12345 ruby target.rb
You can attach with external debugger frontend with VSCode and Chrome.
$ rdbg --open=[frontend] target.rb
This will open a debug port and the [frontend] can attach to the port.
(vscode-rdbg v0.0.9 or later is required)
If you don't run a debuggee Ruby process on VSCode, you can attach it to VSCode later with the following steps.
rdbg --open=vscode opens the debug port and tries to invoke the VSCode (code executable).
$ rdbg --open=vscode target.rb
DEBUGGER: Debugger can attach via UNIX domain socket (/tmp/ruby-debug-sock-1000/ruby-debug-ko1-27706)
DEBUGGER: wait for debugger connection...
Launching: code /tmp/ruby-debug-vscode-20211014-27706-gd7e85/ /tmp/ruby-debug-vscode-20211014-27706-gd7e85/README.rb
DEBUGGER: Connected.
It tries to invoke the new VSCode window and VSCode will attach to the debuggee Ruby program automatically.
You can also use open vscode in a REPL.
$ rdbg target.rb
[1, 8] in target.rb
1|
=> 2| p a = 1
3| p b = 2
4| p c = 3
5| p d = 4
6| p e = 5
7|
8| __END__
=>#0 <main> at target.rb:2
(rdbg) open vscode # command
DEBUGGER: wait for debugger connection...
DEBUGGER: Debugger can attach via UNIX domain socket (/tmp/ruby-debug-sock-1000/ruby-debug-ko1-28337)
Launching: code /tmp/ruby-debug-vscode-20211014-28337-kg9dm/ /tmp/ruby-debug-vscode-20211014-28337-kg9dm/README.rb
DEBUGGER: Connected.
If the machine which runs the Ruby process doesn't have a code executable on $PATH, the following message will be shown:
(rdbg) open vscode
DEBUGGER: wait for debugger connection...
DEBUGGER: Debugger can attach via UNIX domain socket (/tmp/ruby-debug-sock-1000/ruby-debug-ko1-455)
Launching: code /tmp/ruby-debug-vscode-20211014-455-gtjpwi/ /tmp/ruby-debug-vscode-20211014-455-gtjpwi/README.rb
DEBUGGER: Can not invoke the command.
Use the command-line on your terminal (with modification if you need).
code /tmp/ruby-debug-vscode-20211014-455-gtjpwi/ /tmp/ruby-debug-vscode-20211014-455-gtjpwi/README.rb
If your application is running on a SSH remote host, please try:
code --remote ssh-remote+[SSH hostname] /tmp/ruby-debug-vscode-20211014-455-gtjpwi/ /tmp/ruby-debug-vscode-20211014-455-gtjpwi/README.rb
Note that you can attach with rdbg --attach and continue REPL debugging.
Using rdbg --open=chrome will show the following message:
$ rdbg target.rb --open=chrome
DEBUGGER: Debugger can attach via TCP/IP (127.0.0.1:43633)
DEBUGGER: With Chrome browser, type the following URL in the address-bar:
devtools://devtools/bundled/inspector.html?v8only=true&panel=sources&ws=127.0.0.1:57231/b32a55cd-2eb5-4c5c-87d8-b3dfc59d80ef
DEBUGGER: wait for debugger connection...
Type the following in the address bar on Chrome browser, and you can continue the debugging with chrome browser:
devtools://devtools/bundled/inspector.html?v8only=true&panel=sources&ws=127.0.0.1:57231/b32a55cd-2eb5-4c5c-87d8-b3dfc59d80ef`
Similar to VSCode, you can use open chrome to open the debugger in Chrome.
For more information about how to use Chrome debugging, see the devtools docs.
You can configure the debugger's behavior with debug commands and environment variables.
When the debug session is started, some initialization scripts (e.g., ~/.rdbgrc) are loaded, allowing you to configure the debugger's behavior to your needs and preferences.
You can configure the debugger's behavior with environment variables and config command.
Each configuration has an environment variable and a name which can be specified by config command.
# configuration example
config set log_level INFO
config set no_color true
UI
RUBY_DEBUG_LOG_LEVEL (log_level): Log level same as Logger (default: WARN)RUBY_DEBUG_SHOW_SRC_LINES (show_src_lines): Show n lines source code on breakpoint (default: 10)RUBY_DEBUG_SHOW_SRC_LINES_FRAME (show_src_lines_frame): Show n lines source code on frame operations (default: 1)RUBY_DEBUG_SHOW_EVALEDSRC (show_evaledsrc): Show actually evaluated source (default: false)RUBY_DEBUG_SHOW_FRAMES (show_frames): Show n frames on breakpoint (default: 2)RUBY_DEBUG_USE_SHORT_PATH (use_short_path): Show shorten PATH (like $(Gem)/foo.rb) (default: false)RUBY_DEBUG_NO_COLOR (no_color): Do not use colorize (default: false)RUBY_DEBUG_NO_SIGINT_HOOK (no_sigint_hook): Do not suspend on SIGINT (default: false)RUBY_DEBUG_NO_RELINE (no_reline): Do not use Reline library (default: false)RUBY_DEBUG_NO_HINT (no_hint): Do not show the hint on the REPL (default: false)RUBY_DEBUG_NO_LINENO (no_lineno): Do not show line numbers (default: false)RUBY_DEBUG_NO_REPEAT (no_repeat): Do not repeat last line when empty line (default: false)RUBY_DEBUG_IRB_CONSOLE (irb_console): Use IRB as the console (default: false)CONTROL
RUBY_DEBUG_SKIP_PATH (skip_path): Skip showing/entering frames for given pathsRUBY_DEBUG_SKIP_NOSRC (skip_nosrc): Skip on no source code lines (default: false)RUBY_DEBUG_KEEP_ALLOC_SITE (keep_alloc_site): Keep allocation site and p, pp shows it (default: false)RUBY_DEBUG_POSTMORTEM (postmortem): Enable postmortem debug (default: false)RUBY_DEBUG_FORK_MODE (fork_mode): Control which process activates a debugger after fork (both/parent/child) (default: both)RUBY_DEBUG_SIGDUMP_SIG (sigdump_sig): Sigdump signal (default: false)BOOT
RUBY_DEBUG_NONSTOP (nonstop): Nonstop mode (default: false)RUBY_DEBUG_STOP_AT_LOAD (stop_at_load): Stop at just loading location (default: false)RUBY_DEBUG_INIT_SCRIPT (init_script): debug command script path loaded at first stopRUBY_DEBUG_COMMANDS (commands): debug commands invoked at first stop. Commands should be separated by ;;RUBY_DEBUG_NO_RC (no_rc): ignore loading ~/.rdbgrc(.rb) (default: false)RUBY_DEBUG_HISTORY_FILE (history_file): history file (default: ${XDG_STATE_HOME-~/.local/state}/rdbg/history)RUBY_DEBUG_SAVE_HISTORY (save_history): maximum save history lines (default: 10000)REMOTE
RUBY_DEBUG_OPEN (open): Open remote port (same as rdbg --open option)RUBY_DEBUG_PORT (port): TCP/IP remote debugging: portRUBY_DEBUG_PORT_RANGE (port_range): TCP/IP remote debugging: length of port rangeRUBY_DEBUG_HOST (host): TCP/IP remote debugging: host (default: 127.0.0.1)RUBY_DEBUG_SOCK_PATH (sock_path): UNIX Domain Socket remote debugging: socket pathRUBY_DEBUG_SOCK_DIR (sock_dir): UNIX Domain Socket remote debugging: socket directoryRUBY_DEBUG_LOCAL_FS_MAP (local_fs_map): Specify local fs mapRUBY_DEBUG_SKIP_BP (skip_bp): Skip breakpoints if no clients are attached (default: false)RUBY_DEBUG_COOKIE (cookie): Cookie for negotiationRUBY_DEBUG_SESSION_NAME (session_name): Session name for differentiating multiple sessionsRUBY_DEBUG_CHROME_PATH (chrome_path): Platform dependent path of Chrome (For more information, See here)OBSOLETE
RUBY_DEBUG_PARENT_ON_FORK (parent_on_fork): Keep debugging parent process on fork (default: false)There are other environment variables:
NO_COLOR: If the value is set, set RUBY_DEBUG_NO_COLOR (NO_COLOR: disabling ANSI color output in various Unix commands).RUBY_DEBUG_ENABLE: If the value is 0, do not enable debug.gem feature.RUBY_DEBUG_ADDED_RUBYOPT: Remove this value from RUBYOPT at first. This feature helps loading debug.gem with RUBYOPT='-r debug/...', and you don't want to derive it to child processes. In this case, you can set RUBY_DEBUG_ADDED_RUBYOPT='-r debug/...' (same value), and this string will be deleted from RUBYOPT at first.RUBY_DEBUG_EDITOR or EDITOR: An editor used by edit debug command.RUBY_DEBUG_BB: Define Kernel#bb method which is alias of Kernel#debugger.If there is a ~/.rdbgrc file it is loaded as an initialization script (which contains debug commands) when the debug session is started.
RUBY_DEBUG_INIT_SCRIPT environment variable can specify the initial script file.rdbg -x initial_script (like gdb's -x option).Initial scripts are useful to write your favorite configurations.
For example, you can set breakpoints with break file:123 in ~/.rdbgrc.
If there is a ~/.rdbgrc.rb file it is also loaded as a Ruby script when the debug session is started.
On the debug console, you can use the following debug commands.
There are additional features:
<expr> without debug command is almost the same as pp <expr>.
<expr> does NOT start with any debug command, the line <expr> will be evaluated as a Ruby expression, and the result will be printed with pp method.
So that the input foo.bar is the same as pp foo.bar.<expr> is recognized as a debug command, of course, it is not evaluated as a Ruby expression but is executed as debug command.
For example, you can not evaluate such single-letter local variables i, b, n, c because they are single-letter debug commands. Use p i instead.p, pp, or eval command to evaluate the Ruby expression every time.Enter without any input repeats the last command (useful when repeating steps) for some commands.Ctrl-D is equal to quit command.You can use the following debug commands.
Each command should be written in 1 line.
The […] notation means this part can be eliminated. For example, s[tep] means s or step is a valid command. ste is not valid.
The <…> notation means the argument.
s[tep]
s[tep] <n>
<n>th breakable point.n[ext]
n[ext] <n>
step <n>.fin[ish]
fin[ish] <n>
<n>th frames.u[ntil]
next command, but only stop later lines or the end of the current frame.advance command.u[ntil] <[file:]line>
u[ntil] <name>
<name>. <name> can be a regexp with /name/.c or cont or continue
q[uit] or Ctrl-D
q[uit]!
kill
Kernel#exit!.kill!
sigint
SIGINT.b[reak]
b[reak] <line>
<line> at the current frame's file.b[reak] <file>:<line> or <file> <line>
<file>:<line>.b[reak] <class>#<name>
<class>#<name>.b[reak] <expr>.<name>
<expr>.<name>.b[reak] ... if: <expr>
<expr> is true at specified location.b[reak] ... pre: <command>
<command> before stopping.b[reak] ... do: <command>
<command>, and continue.b[reak] ... path: <path>
<path>. <path> can be a regexp with /regexp/.b[reak] if: <expr>
<expr> is true at any lines.catch <Error>
<Error>.catch ... if: <expr>
<expr> is true as well.catch ... pre: <command>
<command> before stopping.catch ... do: <command>
<command>, and continue.catch ... path: <path>
<path>. <path> can be a regexp with /regexp/.watch @ivar
@ivar is changed.watch ... if: <expr>
<expr> is true as well.watch ... pre: <command>
<command> before stopping.watch ... do: <command>
<command>, and continue.watch ... path: <path>
<path>. <path> can be a regexp with /regexp/.del[ete]
del[ete] <bpnum>
bt or backtrace
bt <num> or backtrace <num>
<num> frames.bt /regexp/ or backtrace /regexp/
/regexp/.bt <num> /regexp/ or backtrace <num> /regexp/
<num> frames with method name or location info that matches /regexp/.l[ist]
list command shows the successor lines.l[ist] -
list command.l[ist] <start> or l[ist] <start>-<end>
whereami
edit
EDITOR environment variable).edit <file>
i[nfo]
i[nfo]
info has the following sub-commands.l for 'locals'.i[nfo] l or locals or local_variables
self as %self and a return value as _return.i[nfo] i or ivars or instance_variables
self.info ivars <expr> shows the instance variables of the result of <expr>.i[nfo] c or consts or constants
info consts <expr> shows the constants of a class/module of the result of <expr>i[nfo] g or globals or global_variables
i[nfo] th or threads
th[read]).i[nfo] b or breakpoints or w or watchpoints
i[nfo] ... /regexp/
/regexp/.o[utline] or ls
o[utline] <expr> or ls <expr>
display
display <expr>
<expr> at every suspended timing.undisplay
undisplay <displaynum>
f[rame]
f[rame] <framenum>
up
down
p <expr>
p <expr> on the current frame.pp <expr>
pp <expr> on the current frame.eval <expr>
<expr> on the current frame.irb
irb:rdbg consoletrace
trace line
trace call
trace exception
trace object <expr>
<expr> is passed as a parameter or a receiver on method call.trace ... /regexp/
/regexp/.trace ... into: <file>
<file>.trace off <num>
<num> (use trace command to check the numbers).trace off [line|call|pass]
<type> is provided, disable specified type tracers.record
record [on|off]
step back
s[tep] does stepping forward with the last log.step reset
th[read]
th[read] <thnum>
<thnum>.config
config <name>
config set <name> <val> or config <name> = <val>
config append <name> <val> or config <name> << <val>
<val> to <name> if it is an array.config unset <name>
source <file>
<file> as debug commands.open
open command is EXPERIMENTAL.open [<host>:]<port>
[<host>:]<port> and wait for attaching.open vscode
open chrome
h[elp]
h[elp] <command>
Starting from version v1.9, you can now use IRB as the debug console. This integration brings additional features such as:
debug, like show_source or show_docTo switch to the IRB console, simply use the irb command in the debug console.
Once activated, you'll notice the prompt changes to:
irb:rdbg(main):001>
If you want to make IRB the default console for all sessions, configure the irb_console setting by either:
RUBY_DEBUG_IRB_CONSOLE=true environment variableconfig set irb_console 1 to your ~/.rdbgrcTo disable the IRB console in the current session, execute config set irb_console 0 in the console.
You can start debugging without rdbg command by requiring the following libraries:
require 'debug': Same as rdbg --nonstop --no-sigint-hook.require 'debug/start': Same as rdbg.require 'debug/open': Same as rdbg --open.require 'debug/open_nonstop': Same as rdbg --open --nonstop.You need to require one of them at the very beginning of the application.
Using ruby -r (for example ruby -r debug/start target.rb) is another way to invoke with debugger.
NOTE: Until Ruby 3.0, there is old lib/debug.rb in the standard library.
lib/debug.rb was not maintained well in recent years, and the purpose of this library is to rewrite old lib/debug.rb with recent techniques.
So, if this gem is not installed, or if the Gemfile doesn't include this gem and bundle exec is used, you will see the following output:
$ ruby -r debug -e0
.../2.7.3/lib/ruby/2.7.0/x86_64-linux/continuation.so: warning: callcc is obsolete; use Fiber instead
Debug.rb
Emacs support available.
.../2.7.3/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:162: if RUBYGEMS_ACTIVATION_MONITOR.respond_to?(:mon_owned?)
(rdb:1)
After loading debug/session, you can start a debug session with the following methods.
They are convenient if you want to specify debug configurations in your program.
DEBUGGER__.start(**kw): start debug session with local console.DEBUGGER__.open(**kw): open debug port with configuration (without configurations open with UNIX domain socket).DEBUGGER__.open_unix(**kw): open debug port with UNIX domain socket.DEBUGGER__.open_tcp(**kw): open debug port with TCP/IP.For example:
require 'debug/session'
DEBUGGER__.start(no_color: true, # disable colorize
log_level: 'INFO') # Change log_level to INFO
... # your application code
binding.break methodbinding.break (or binding.b) sets a breakpoint at that line.
It also has several keywords.
If do: 'command' is specified, the debugger suspends the program, runs the command as a debug command, and continues the program.
It is useful if you only want to call a debug command and don't want to stop there.
For example:
def initialize
@a = 1
binding.b do: 'info \n watch @a'
end
In this case, execute the info command, then register a watch breakpoint for @a and continue to run.
You can also use ;; instead of \n to separate your commands.
If pre: 'command' is specified, the debugger suspends the program and runs the command as a debug command, and keeps suspended.
It is useful if you have operations before suspend.
For example:
def foo
binding.b pre: 'p bar()'
...
end
In this case, you can see the result of bar() every time you stop there.
exe/rdbg [options] -- [debuggee options]
Debug console mode:
-n, --nonstop Do not stop at the beginning of the script.
-e DEBUG_COMMAND Execute debug command at the beginning of the script.
-x, --init-script=FILE Execute debug command in the FILE.
--no-rc Ignore ~/.rdbgrc
--no-color Disable colorize
--no-sigint-hook Disable to trap SIGINT
-c, --command Enable command mode.
The first argument should be a command name in $PATH.
Example: 'rdbg -c bundle exec rake test'
-O, --open=[FRONTEND] Start remote debugging with opening the network port.
If TCP/IP options are not given, a UNIX domain socket will be used.
If FRONTEND is given, prepare for the FRONTEND.
Now rdbg, vscode and chrome is supported.
--sock-path=SOCK_PATH UNIX Domain socket path
--port=PORT Listening TCP/IP port
--port-range=PORT_RANGE Number of ports to try to connect to
--host=HOST Listening TCP/IP host
--cookie=COOKIE Set a cookie for connection
--session-name=NAME Session name
Debug console mode runs Ruby program with the debug console.
'rdbg target.rb foo bar' starts like 'ruby target.rb foo bar'.
'rdbg -- -r foo -e bar' starts like 'ruby -r foo -e bar'.
'rdbg -c rake test' starts like 'rake test'.
'rdbg -c -- rake test -t' starts like 'rake test -t'.
'rdbg -c bundle exec rake test' starts like 'bundle exec rake test'.
'rdbg -O target.rb foo bar' starts and accepts attaching with UNIX domain socket.
'rdbg -O --port 1234 target.rb foo bar' starts accepts attaching with TCP/IP localhost:1234.
'rdbg -O --port 1234 -- -r foo -e bar' starts accepts attaching with TCP/IP localhost:1234.
'rdbg target.rb -O chrome --port 1234' starts and accepts connecting from Chrome Devtools with localhost:1234.
Attach mode:
-A, --attach Attach to debuggee process.
Attach mode attaches the remote debug console to the debuggee process.
'rdbg -A' tries to connect via UNIX domain socket.
If there are multiple processes are waiting for the
debugger connection, list possible debuggee names.
'rdbg -A path' tries to connect via UNIX domain socket with given path name.
'rdbg -A port' tries to connect to localhost:port via TCP/IP.
'rdbg -A host port' tries to connect to host:port via TCP/IP.
Other options:
-v Show version number
--version Show version number and exit
-h, --help Print help
--util=NAME Utility mode (used by tools)
--stop-at-load Stop immediately when the debugging feature is loaded.
NOTE
All messages communicated between a debugger and a debuggee are *NOT* encrypted.
Please use the remote debugging feature carefully.
byebug users.Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/debug. This debugger is not mature so your feedback will help us.
Please also check the contributing guideline.
server_cdp.rb are based on geoffreylitt/ladybug: Visual DebuggerRuby
99.2%
This library provides debugging functionality to Ruby (MRI) 2.7 and later.
This debug.rb is the replacement of traditional lib/debug.rb standard library, which is implemented by set_trace_func.
New debug.rb has several advantages:
Fast: No performance penalty on non-stepping mode and non-breakpoints.
Remote debugging: Support remote debugging natively.
UNIX domain socket (UDS)
TCP/IP
Integration with rich debugger frontends
| Frontend | Console | VSCode | Chrome DevTool |
|---|---|---|---|
| Connection | UDS, TCP/IP | UDS, TCP/IP | TCP/IP |
| Requirement | None | vscode-rdbg | Chrome |
Extensible: application can introduce debugging support in several ways:
rdbg command-r command line optionMisc
Ctrl-C at most of timing.$ gem install debug
Alternatively, specify -Ipath/to/debug/lib in RUBYOPT, or as a Ruby command-line option
This is especially useful for debugging this gem during development.
If using Bundler, add the following to your Gemfile:
gem "debug", ">= 1.0.0"
(The version constraint is important; debug < 1.0.0 is an older, abandoned gem that is completely different from this product.)
To use the debugger, you will do roughly the following steps:
p lvar to see the local variable lvar).info to see information about the current frame).step, to the next line with next).catch Exception to set a breakpoint that'll be triggered when Exception is raised).trace call to trace method calls).config set no_color true to disable coloring).c or continue) and goto 3.There are several ways to invoke the debugger, depending on your needs, preferences, and the environment.
binding.break (similar to binding.pry or binding.irb)If you can modify the source code, you can use the debugger by adding require 'debug' at the top of your program and putting binding.break method into lines where you want to stop as breakpoints.
This is similar to how binding.pry and binding.irb work.
binding.break has two aliases which do the same thing:
binding.bdebuggerAfter that, run the program as usual and you will enter the debug console at breakpoints you inserted.
The following is an example of the binding.break method.
$ cat target.rb # Sample program
require 'debug'
a = 1
b = 2
binding.break # Program will stop here
c = 3
d = 4
binding.break # Program will stop here
p [a, b, c, d]
$ ruby target.rb # Run the program normally.
DEBUGGER: Session start (pid: 7604)
[1, 10] in target.rb
1| require 'debug'
2|
3| a = 1
4| b = 2
=> 5| binding.break # Now you can see it stops at this line
6| c = 3
7| d = 4
8| binding.break
9| p [a, b, c, d]
10|
=>#0 <main> at target.rb:5
(rdbg) info locals # You can show local variables
=>#0 <main> at target.rb:5
%self => main
a => 1
b => 2
c => nil
d => nil
(rdbg) continue # Continue the execution
[3, 11] in target.rb
3| a = 1
4| b = 2
5| binding.break
6| c = 3
7| d = 4
=> 8| binding.break # Again the program stops here
9| p [a, b, c, d]
10|
11| __END__
=>#0 <main> at target.rb:8
(rdbg) info locals # And you can see the updated local variables
=>#0 <main> at target.rb:8
%self => main
a => 1
b => 2
c => 3
d => 4
(rdbg) continue
[1, 2, 3, 4]
If you don't want to modify the source code, you can use the rdbg command (or bundle exec rdbg) to run the program with the debugger.
This is similar to how you'd launch a program with ruby program.rb.
Then you can set breakpoints with the debug command break (b for short).
$ cat target.rb # Sample program
a = 1
b = 2
c = 3
d = 4
p [a, b, c, d]
$ rdbg target.rb # run like `ruby target.rb`
DEBUGGER: Session start (pid: 7656)
[1, 7] in target.rb
=> 1| a = 1
2| b = 2
3| c = 3
4| d = 4
5| p [a, b, c, d]
6|
7| __END__
=>#0 <main> at target.rb:1
(rdbg)
The rdbg command suspends the program at the beginning of the given script (target.rb in this case) and you can use debug commands to control execution from there.
(rdbg) is the console prompt.
Let's set breakpoints on line 3 and line 5 with break command (b for short).
(rdbg) break 3 # set breakpoint at line 3
#0 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:3 (line)
(rdbg) b 5 # set breakpoint at line 5
#1 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:5 (line)
(rdbg) break # show all registered breakpoints
#0 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:3 (line)
#1 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:5 (line)
You can see that two breakpoints are registered.
Let's continue the program by using the continue command.
(rdbg) continue
[1, 7] in target.rb
1| a = 1
2| b = 2
=> 3| c = 3
4| d = 4
5| p [a, b, c, d]
6|
7| __END__
=>#0 <main> at target.rb:3
Stop by #0 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:3 (line)
(rdbg)
You can see that we stopped at line 3.
Let's see the local variables with the info command, and continue execution with the continue.
The program will then suspend at line 5 and you can use the info command again.
(rdbg) info
=>#0 <main> at target.rb:3
%self => main
a => 1
b => 2
c => nil
d => nil
(rdbg) continue
[1, 7] in target.rb
1| a = 1
2| b = 2
3| c = 3
4| d = 4
=> 5| p [a, b, c, d]
6|
7| __END__
=>#0 <main> at target.rb:5
Stop by #1 BP - Line /mnt/c/ko1/src/rb/ruby-debug/target.rb:5 (line)
(rdbg) info
=>#0 <main> at target.rb:5
%self => main
a => 1
b => 2
c => 3
d => 4
(rdbg) continue
[1, 2, 3, 4]
NOTE: When using rdbg you can suspend your application with C-c (SIGINT) and enter the debug console.
It will help if you want to know what the program is doing.
rdbg with commands written in RubyIf you want to run an executable written in Ruby like rake, rails, bundle, rspec, and so on, you can use rdbg -c option.
-c option, rdbg <name> means that <name> is a Ruby script and it is invoked like ruby <name> with the debugger.-c option, rdbg -c <name> means that <name> is an executable in PATH and simply invokes it with the debugger.Examples:
rdbg -c -- rails serverrdbg -c -- bundle exec ruby foo.rbrdbg -c -- bundle exec rake testrdbg -c -- ruby target.rb is the same as rdbg target.rbNOTE: -- is needed to separate the command line options for rdbg from the executable being invoked, and its options.
For example, rdbg -c rake -T would be parsed as rdbg -c -T -- rake, which is incorrect.
It should be rdbg -c -- rake -T.
NOTE: If you want to use Bundler (bundle executable), you need to add gem 'debug' to your Gemfile.
Like other languages, you can use this debugger on the VSCode.
.rb file (e.g. target.rb)rdbg -c, and VSCode shows the details at breakpoints.Please refer to Debugging in Visual Studio Code for operations on VSCode.
You can configure the extension in .vscode/launch.json.
Please see the extension page for more details.
You can use this debugger as a remote debugger. For example, it will help in the following situations:
binding.pry or binding.irb.
STDIN or STDOUT.You can run your application as a remote debuggee, and the remote debugger console can attach to the debuggee anytime.
There are multiple ways to run your program as a debuggee:
| Stop at program start | rdbg option | require | debugger API |
|---|---|---|---|
| Yes | rdbg --open | require "debug/open" | DEBUGGER__.open |
| No | rdbg --open --nonstop | require "debug/open_nonstop" | DEBUGGER__.open(nonstop: true) |
rdbg --open (or rdbg -O for short)Launch a script with rdbg --open target.rb to run target.rb as a debuggee program.
It also opens the network port and suspends at the beginning of target.rb.
$ rdbg --open target.rb
DEBUGGER: Session start (pid: 7773)
DEBUGGER: Debugger can attach via UNIX domain socket (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-7773)
DEBUGGER: wait for debugger connection...
By default, rdbg --open uses UNIX domain socket and generates the path name automatically (/home/ko1/.ruby-debug-sock/ruby-debug-ko1-7773 in this case).
You can connect to the debuggee with rdbg --attach command (rdbg -A for short).
$ rdbg -A
[1, 7] in target.rb
=> 1| a = 1
2| b = 2
3| c = 3
4| d = 4
5| p [a, b, c, d]
6|
7| __END__
=>#0 <main> at target.rb:1
(rdbg:remote)
If there are no other files in the default directory, rdbg --attach will automatically connect to the UNIX domain socket listed.
If there are multiple files, you need to specify which to use.
When rdbg --attach connects to the debuggee, you can use any debug commands (set breakpoints, continue the program, and so on) like the local debug console.
When a debuggee program exits, the remote console will also terminate.
NOTE: If you use the quit command, only the remote console exits and the debuggee program continues to run (and you can connect it again).
If you want to exit the debuggee program, use kill command.
If you want to use TCP/IP for remote debugging, you need to specify the port and host with --port like rdbg --open --port 12345 and it binds to localhost:12345.
You can add an optional --port_range to try multiple ports in a reliable way.
For example, rdbg --open --port 12345 --port_range 10 will try to bind to 12345, 12346, 12347,… until it finds an available port.
To connect to the debuggee, you need to specify the port.
$ rdbg --attach 12345
If you want to choose the host to bind, you can use --host option.
Messages communicated between the debugger and the debuggee are NOT encrypted so please use remote debugging carefully.
require 'debug/open' in a programIf you can modify the program, you can open the debugging port by adding require 'debug/open' in the program.
If you don't want to stop the program at the beginning, you can also use require 'debug/open_nonstop'.
Using debug/open_nonstop is useful if you want to open a backdoor to the application.
However, it is also dangerous because it can become another vulnerability.
Please use it carefully.
By default, UNIX domain socket is used for the debugging port.
To use TCP/IP, you can set the RUBY_DEBUG_PORT environment variable.
$ RUBY_DEBUG_PORT=12345 ruby target.rb
You can attach with external debugger frontend with VSCode and Chrome.
$ rdbg --open=[frontend] target.rb
This will open a debug port and the [frontend] can attach to the port.
(vscode-rdbg v0.0.9 or later is required)
If you don't run a debuggee Ruby process on VSCode, you can attach it to VSCode later with the following steps.
rdbg --open=vscode opens the debug port and tries to invoke the VSCode (code executable).
$ rdbg --open=vscode target.rb
DEBUGGER: Debugger can attach via UNIX domain socket (/tmp/ruby-debug-sock-1000/ruby-debug-ko1-27706)
DEBUGGER: wait for debugger connection...
Launching: code /tmp/ruby-debug-vscode-20211014-27706-gd7e85/ /tmp/ruby-debug-vscode-20211014-27706-gd7e85/README.rb
DEBUGGER: Connected.
It tries to invoke the new VSCode window and VSCode will attach to the debuggee Ruby program automatically.
You can also use open vscode in a REPL.
$ rdbg target.rb
[1, 8] in target.rb
1|
=> 2| p a = 1
3| p b = 2
4| p c = 3
5| p d = 4
6| p e = 5
7|
8| __END__
=>#0 <main> at target.rb:2
(rdbg) open vscode # command
DEBUGGER: wait for debugger connection...
DEBUGGER: Debugger can attach via UNIX domain socket (/tmp/ruby-debug-sock-1000/ruby-debug-ko1-28337)
Launching: code /tmp/ruby-debug-vscode-20211014-28337-kg9dm/ /tmp/ruby-debug-vscode-20211014-28337-kg9dm/README.rb
DEBUGGER: Connected.
If the machine which runs the Ruby process doesn't have a code executable on $PATH, the following message will be shown:
(rdbg) open vscode
DEBUGGER: wait for debugger connection...
DEBUGGER: Debugger can attach via UNIX domain socket (/tmp/ruby-debug-sock-1000/ruby-debug-ko1-455)
Launching: code /tmp/ruby-debug-vscode-20211014-455-gtjpwi/ /tmp/ruby-debug-vscode-20211014-455-gtjpwi/README.rb
DEBUGGER: Can not invoke the command.
Use the command-line on your terminal (with modification if you need).
code /tmp/ruby-debug-vscode-20211014-455-gtjpwi/ /tmp/ruby-debug-vscode-20211014-455-gtjpwi/README.rb
If your application is running on a SSH remote host, please try:
code --remote ssh-remote+[SSH hostname] /tmp/ruby-debug-vscode-20211014-455-gtjpwi/ /tmp/ruby-debug-vscode-20211014-455-gtjpwi/README.rb
Note that you can attach with rdbg --attach and continue REPL debugging.
Using rdbg --open=chrome will show the following message:
$ rdbg target.rb --open=chrome
DEBUGGER: Debugger can attach via TCP/IP (127.0.0.1:43633)
DEBUGGER: With Chrome browser, type the following URL in the address-bar:
devtools://devtools/bundled/inspector.html?v8only=true&panel=sources&ws=127.0.0.1:57231/b32a55cd-2eb5-4c5c-87d8-b3dfc59d80ef
DEBUGGER: wait for debugger connection...
Type the following in the address bar on Chrome browser, and you can continue the debugging with chrome browser:
devtools://devtools/bundled/inspector.html?v8only=true&panel=sources&ws=127.0.0.1:57231/b32a55cd-2eb5-4c5c-87d8-b3dfc59d80ef`
Similar to VSCode, you can use open chrome to open the debugger in Chrome.
For more information about how to use Chrome debugging, see the devtools docs.
You can configure the debugger's behavior with debug commands and environment variables.
When the debug session is started, some initialization scripts (e.g., ~/.rdbgrc) are loaded, allowing you to configure the debugger's behavior to your needs and preferences.
You can configure the debugger's behavior with environment variables and config command.
Each configuration has an environment variable and a name which can be specified by config command.
# configuration example
config set log_level INFO
config set no_color true
UI
RUBY_DEBUG_LOG_LEVEL (log_level): Log level same as Logger (default: WARN)RUBY_DEBUG_SHOW_SRC_LINES (show_src_lines): Show n lines source code on breakpoint (default: 10)RUBY_DEBUG_SHOW_SRC_LINES_FRAME (show_src_lines_frame): Show n lines source code on frame operations (default: 1)RUBY_DEBUG_SHOW_EVALEDSRC (show_evaledsrc): Show actually evaluated source (default: false)RUBY_DEBUG_SHOW_FRAMES (show_frames): Show n frames on breakpoint (default: 2)RUBY_DEBUG_USE_SHORT_PATH (use_short_path): Show shorten PATH (like $(Gem)/foo.rb) (default: false)RUBY_DEBUG_NO_COLOR (no_color): Do not use colorize (default: false)RUBY_DEBUG_NO_SIGINT_HOOK (no_sigint_hook): Do not suspend on SIGINT (default: false)RUBY_DEBUG_NO_RELINE (no_reline): Do not use Reline library (default: false)RUBY_DEBUG_NO_HINT (no_hint): Do not show the hint on the REPL (default: false)RUBY_DEBUG_NO_LINENO (no_lineno): Do not show line numbers (default: false)RUBY_DEBUG_NO_REPEAT (no_repeat): Do not repeat last line when empty line (default: false)RUBY_DEBUG_IRB_CONSOLE (irb_console): Use IRB as the console (default: false)CONTROL
RUBY_DEBUG_SKIP_PATH (skip_path): Skip showing/entering frames for given pathsRUBY_DEBUG_SKIP_NOSRC (skip_nosrc): Skip on no source code lines (default: false)RUBY_DEBUG_KEEP_ALLOC_SITE (keep_alloc_site): Keep allocation site and p, pp shows it (default: false)RUBY_DEBUG_POSTMORTEM (postmortem): Enable postmortem debug (default: false)RUBY_DEBUG_FORK_MODE (fork_mode): Control which process activates a debugger after fork (both/parent/child) (default: both)RUBY_DEBUG_SIGDUMP_SIG (sigdump_sig): Sigdump signal (default: false)BOOT
RUBY_DEBUG_NONSTOP (nonstop): Nonstop mode (default: false)RUBY_DEBUG_STOP_AT_LOAD (stop_at_load): Stop at just loading location (default: false)RUBY_DEBUG_INIT_SCRIPT (init_script): debug command script path loaded at first stopRUBY_DEBUG_COMMANDS (commands): debug commands invoked at first stop. Commands should be separated by ;;RUBY_DEBUG_NO_RC (no_rc): ignore loading ~/.rdbgrc(.rb) (default: false)RUBY_DEBUG_HISTORY_FILE (history_file): history file (default: ${XDG_STATE_HOME-~/.local/state}/rdbg/history)RUBY_DEBUG_SAVE_HISTORY (save_history): maximum save history lines (default: 10000)REMOTE
RUBY_DEBUG_OPEN (open): Open remote port (same as rdbg --open option)RUBY_DEBUG_PORT (port): TCP/IP remote debugging: portRUBY_DEBUG_PORT_RANGE (port_range): TCP/IP remote debugging: length of port rangeRUBY_DEBUG_HOST (host): TCP/IP remote debugging: host (default: 127.0.0.1)RUBY_DEBUG_SOCK_PATH (sock_path): UNIX Domain Socket remote debugging: socket pathRUBY_DEBUG_SOCK_DIR (sock_dir): UNIX Domain Socket remote debugging: socket directoryRUBY_DEBUG_LOCAL_FS_MAP (local_fs_map): Specify local fs mapRUBY_DEBUG_SKIP_BP (skip_bp): Skip breakpoints if no clients are attached (default: false)RUBY_DEBUG_COOKIE (cookie): Cookie for negotiationRUBY_DEBUG_SESSION_NAME (session_name): Session name for differentiating multiple sessionsRUBY_DEBUG_CHROME_PATH (chrome_path): Platform dependent path of Chrome (For more information, See here)OBSOLETE
RUBY_DEBUG_PARENT_ON_FORK (parent_on_fork): Keep debugging parent process on fork (default: false)There are other environment variables:
NO_COLOR: If the value is set, set RUBY_DEBUG_NO_COLOR (NO_COLOR: disabling ANSI color output in various Unix commands).RUBY_DEBUG_ENABLE: If the value is 0, do not enable debug.gem feature.RUBY_DEBUG_ADDED_RUBYOPT: Remove this value from RUBYOPT at first. This feature helps loading debug.gem with RUBYOPT='-r debug/...', and you don't want to derive it to child processes. In this case, you can set RUBY_DEBUG_ADDED_RUBYOPT='-r debug/...' (same value), and this string will be deleted from RUBYOPT at first.RUBY_DEBUG_EDITOR or EDITOR: An editor used by edit debug command.RUBY_DEBUG_BB: Define Kernel#bb method which is alias of Kernel#debugger.If there is a ~/.rdbgrc file it is loaded as an initialization script (which contains debug commands) when the debug session is started.
RUBY_DEBUG_INIT_SCRIPT environment variable can specify the initial script file.rdbg -x initial_script (like gdb's -x option).Initial scripts are useful to write your favorite configurations.
For example, you can set breakpoints with break file:123 in ~/.rdbgrc.
If there is a ~/.rdbgrc.rb file it is also loaded as a Ruby script when the debug session is started.
On the debug console, you can use the following debug commands.
There are additional features:
<expr> without debug command is almost the same as pp <expr>.
<expr> does NOT start with any debug command, the line <expr> will be evaluated as a Ruby expression, and the result will be printed with pp method.
So that the input foo.bar is the same as pp foo.bar.<expr> is recognized as a debug command, of course, it is not evaluated as a Ruby expression but is executed as debug command.
For example, you can not evaluate such single-letter local variables i, b, n, c because they are single-letter debug commands. Use p i instead.p, pp, or eval command to evaluate the Ruby expression every time.Enter without any input repeats the last command (useful when repeating steps) for some commands.Ctrl-D is equal to quit command.You can use the following debug commands.
Each command should be written in 1 line.
The […] notation means this part can be eliminated. For example, s[tep] means s or step is a valid command. ste is not valid.
The <…> notation means the argument.
s[tep]
s[tep] <n>
<n>th breakable point.n[ext]
n[ext] <n>
step <n>.fin[ish]
fin[ish] <n>
<n>th frames.u[ntil]
next command, but only stop later lines or the end of the current frame.advance command.u[ntil] <[file:]line>
u[ntil] <name>
<name>. <name> can be a regexp with /name/.c or cont or continue
q[uit] or Ctrl-D
q[uit]!
kill
Kernel#exit!.kill!
sigint
SIGINT.b[reak]
b[reak] <line>
<line> at the current frame's file.b[reak] <file>:<line> or <file> <line>
<file>:<line>.b[reak] <class>#<name>
<class>#<name>.b[reak] <expr>.<name>
<expr>.<name>.b[reak] ... if: <expr>
<expr> is true at specified location.b[reak] ... pre: <command>
<command> before stopping.b[reak] ... do: <command>
<command>, and continue.b[reak] ... path: <path>
<path>. <path> can be a regexp with /regexp/.b[reak] if: <expr>
<expr> is true at any lines.catch <Error>
<Error>.catch ... if: <expr>
<expr> is true as well.catch ... pre: <command>
<command> before stopping.catch ... do: <command>
<command>, and continue.catch ... path: <path>
<path>. <path> can be a regexp with /regexp/.watch @ivar
@ivar is changed.watch ... if: <expr>
<expr> is true as well.watch ... pre: <command>
<command> before stopping.watch ... do: <command>
<command>, and continue.watch ... path: <path>
<path>. <path> can be a regexp with /regexp/.del[ete]
del[ete] <bpnum>
bt or backtrace
bt <num> or backtrace <num>
<num> frames.bt /regexp/ or backtrace /regexp/
/regexp/.bt <num> /regexp/ or backtrace <num> /regexp/
<num> frames with method name or location info that matches /regexp/.l[ist]
list command shows the successor lines.l[ist] -
list command.l[ist] <start> or l[ist] <start>-<end>
whereami
edit
EDITOR environment variable).edit <file>
i[nfo]
i[nfo]
info has the following sub-commands.l for 'locals'.i[nfo] l or locals or local_variables
self as %self and a return value as _return.i[nfo] i or ivars or instance_variables
self.info ivars <expr> shows the instance variables of the result of <expr>.i[nfo] c or consts or constants
info consts <expr> shows the constants of a class/module of the result of <expr>i[nfo] g or globals or global_variables
i[nfo] th or threads
th[read]).i[nfo] b or breakpoints or w or watchpoints
i[nfo] ... /regexp/
/regexp/.o[utline] or ls
o[utline] <expr> or ls <expr>
display
display <expr>
<expr> at every suspended timing.undisplay
undisplay <displaynum>
f[rame]
f[rame] <framenum>
up
down
p <expr>
p <expr> on the current frame.pp <expr>
pp <expr> on the current frame.eval <expr>
<expr> on the current frame.irb
irb:rdbg consoletrace
trace line
trace call
trace exception
trace object <expr>
<expr> is passed as a parameter or a receiver on method call.trace ... /regexp/
/regexp/.trace ... into: <file>
<file>.trace off <num>
<num> (use trace command to check the numbers).trace off [line|call|pass]
<type> is provided, disable specified type tracers.record
record [on|off]
step back
s[tep] does stepping forward with the last log.step reset
th[read]
th[read] <thnum>
<thnum>.config
config <name>
config set <name> <val> or config <name> = <val>
config append <name> <val> or config <name> << <val>
<val> to <name> if it is an array.config unset <name>
source <file>
<file> as debug commands.open
open command is EXPERIMENTAL.open [<host>:]<port>
[<host>:]<port> and wait for attaching.open vscode
open chrome
h[elp]
h[elp] <command>
Starting from version v1.9, you can now use IRB as the debug console. This integration brings additional features such as:
debug, like show_source or show_docTo switch to the IRB console, simply use the irb command in the debug console.
Once activated, you'll notice the prompt changes to:
irb:rdbg(main):001>
If you want to make IRB the default console for all sessions, configure the irb_console setting by either:
RUBY_DEBUG_IRB_CONSOLE=true environment variableconfig set irb_console 1 to your ~/.rdbgrcTo disable the IRB console in the current session, execute config set irb_console 0 in the console.
You can start debugging without rdbg command by requiring the following libraries:
require 'debug': Same as rdbg --nonstop --no-sigint-hook.require 'debug/start': Same as rdbg.require 'debug/open': Same as rdbg --open.require 'debug/open_nonstop': Same as rdbg --open --nonstop.You need to require one of them at the very beginning of the application.
Using ruby -r (for example ruby -r debug/start target.rb) is another way to invoke with debugger.
NOTE: Until Ruby 3.0, there is old lib/debug.rb in the standard library.
lib/debug.rb was not maintained well in recent years, and the purpose of this library is to rewrite old lib/debug.rb with recent techniques.
So, if this gem is not installed, or if the Gemfile doesn't include this gem and bundle exec is used, you will see the following output:
$ ruby -r debug -e0
.../2.7.3/lib/ruby/2.7.0/x86_64-linux/continuation.so: warning: callcc is obsolete; use Fiber instead
Debug.rb
Emacs support available.
.../2.7.3/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:162: if RUBYGEMS_ACTIVATION_MONITOR.respond_to?(:mon_owned?)
(rdb:1)
After loading debug/session, you can start a debug session with the following methods.
They are convenient if you want to specify debug configurations in your program.
DEBUGGER__.start(**kw): start debug session with local console.DEBUGGER__.open(**kw): open debug port with configuration (without configurations open with UNIX domain socket).DEBUGGER__.open_unix(**kw): open debug port with UNIX domain socket.DEBUGGER__.open_tcp(**kw): open debug port with TCP/IP.For example:
require 'debug/session'
DEBUGGER__.start(no_color: true, # disable colorize
log_level: 'INFO') # Change log_level to INFO
... # your application code
binding.break methodbinding.break (or binding.b) sets a breakpoint at that line.
It also has several keywords.
If do: 'command' is specified, the debugger suspends the program, runs the command as a debug command, and continues the program.
It is useful if you only want to call a debug command and don't want to stop there.
For example:
def initialize
@a = 1
binding.b do: 'info \n watch @a'
end
In this case, execute the info command, then register a watch breakpoint for @a and continue to run.
You can also use ;; instead of \n to separate your commands.
If pre: 'command' is specified, the debugger suspends the program and runs the command as a debug command, and keeps suspended.
It is useful if you have operations before suspend.
For example:
def foo
binding.b pre: 'p bar()'
...
end
In this case, you can see the result of bar() every time you stop there.
exe/rdbg [options] -- [debuggee options]
Debug console mode:
-n, --nonstop Do not stop at the beginning of the script.
-e DEBUG_COMMAND Execute debug command at the beginning of the script.
-x, --init-script=FILE Execute debug command in the FILE.
--no-rc Ignore ~/.rdbgrc
--no-color Disable colorize
--no-sigint-hook Disable to trap SIGINT
-c, --command Enable command mode.
The first argument should be a command name in $PATH.
Example: 'rdbg -c bundle exec rake test'
-O, --open=[FRONTEND] Start remote debugging with opening the network port.
If TCP/IP options are not given, a UNIX domain socket will be used.
If FRONTEND is given, prepare for the FRONTEND.
Now rdbg, vscode and chrome is supported.
--sock-path=SOCK_PATH UNIX Domain socket path
--port=PORT Listening TCP/IP port
--port-range=PORT_RANGE Number of ports to try to connect to
--host=HOST Listening TCP/IP host
--cookie=COOKIE Set a cookie for connection
--session-name=NAME Session name
Debug console mode runs Ruby program with the debug console.
'rdbg target.rb foo bar' starts like 'ruby target.rb foo bar'.
'rdbg -- -r foo -e bar' starts like 'ruby -r foo -e bar'.
'rdbg -c rake test' starts like 'rake test'.
'rdbg -c -- rake test -t' starts like 'rake test -t'.
'rdbg -c bundle exec rake test' starts like 'bundle exec rake test'.
'rdbg -O target.rb foo bar' starts and accepts attaching with UNIX domain socket.
'rdbg -O --port 1234 target.rb foo bar' starts accepts attaching with TCP/IP localhost:1234.
'rdbg -O --port 1234 -- -r foo -e bar' starts accepts attaching with TCP/IP localhost:1234.
'rdbg target.rb -O chrome --port 1234' starts and accepts connecting from Chrome Devtools with localhost:1234.
Attach mode:
-A, --attach Attach to debuggee process.
Attach mode attaches the remote debug console to the debuggee process.
'rdbg -A' tries to connect via UNIX domain socket.
If there are multiple processes are waiting for the
debugger connection, list possible debuggee names.
'rdbg -A path' tries to connect via UNIX domain socket with given path name.
'rdbg -A port' tries to connect to localhost:port via TCP/IP.
'rdbg -A host port' tries to connect to host:port via TCP/IP.
Other options:
-v Show version number
--version Show version number and exit
-h, --help Print help
--util=NAME Utility mode (used by tools)
--stop-at-load Stop immediately when the debugging feature is loaded.
NOTE
All messages communicated between a debugger and a debuggee are *NOT* encrypted.
Please use the remote debugging feature carefully.
byebug users.Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/debug. This debugger is not mature so your feedback will help us.
Please also check the contributing guideline.
server_cdp.rb are based on geoffreylitt/ladybug: Visual DebuggerRuby
99.2%