debugging_rails_applications.md 32.0 KB
Newer Older
1
**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
X
Xavier Noria 已提交
2

3 4
Debugging Rails Applications
============================
5

6 7 8
This guide introduces techniques for debugging Ruby on Rails applications.

After reading this guide, you will know:
9

10 11 12 13
* The purpose of debugging.
* How to track down problems and issues in your application that your tests aren't identifying.
* The different ways of debugging.
* How to analyze the stack trace.
14

15
--------------------------------------------------------------------------------
16

17 18
View Helpers for Debugging
--------------------------
19

20
One common task is to inspect the contents of a variable. Rails provides three different ways to do this:
21

22 23 24
* `debug`
* `to_yaml`
* `inspect`
25

26
### `debug`
27

J
Jonathan Roes 已提交
28
The `debug` helper will return a \<pre> tag that renders the object using the YAML format. This will generate human-readable data from any object. For example, if you have this code in a view:
29

30
```html+erb
31
<%= debug @article %>
32 33
<p>
  <b>Title:</b>
34
  <%= @article.title %>
35
</p>
36
```
37 38 39

You'll see something like this:

40
```yaml
41
--- !ruby/object Article
42 43 44 45 46 47 48 49 50 51 52
attributes:
  updated_at: 2008-09-05 22:55:47
  body: It's a very helpful guide for debugging your Rails app.
  title: Rails debugging guide
  published: t
  id: "1"
  created_at: 2008-09-05 22:55:47
attributes_cache: {}


Title: Rails debugging guide
53
```
54

55
### `to_yaml`
56

Z
Zachary Scott 已提交
57
Alternatively, calling `to_yaml` on any object converts it to YAML. You can pass this converted object into the `simple_format` helper method to format the output. This is how `debug` does its magic.
58

59
```html+erb
60
<%= simple_format @article.to_yaml %>
61 62
<p>
  <b>Title:</b>
63
  <%= @article.title %>
64
</p>
65
```
66

67
The above code will render something like this:
68

69
```yaml
70
--- !ruby/object Article
71 72 73 74 75 76 77 78 79 80
attributes:
updated_at: 2008-09-05 22:55:47
body: It's a very helpful guide for debugging your Rails app.
title: Rails debugging guide
published: t
id: "1"
created_at: 2008-09-05 22:55:47
attributes_cache: {}

Title: Rails debugging guide
81
```
82

83
### `inspect`
84

85
Another useful method for displaying object values is `inspect`, especially when working with arrays or hashes. This will print the object value as a string. For example:
86

87
```html+erb
88 89 90
<%= [1, 2, 3, 4, 5].inspect %>
<p>
  <b>Title:</b>
91
  <%= @article.title %>
92
</p>
93
```
94

95
Will render:
96

97
```
98 99 100
[1, 2, 3, 4, 5]

Title: Rails debugging guide
101
```
102

103 104
The Logger
----------
105 106 107

It can also be useful to save information to log files at runtime. Rails maintains a separate log file for each runtime environment.

108
### What is the Logger?
109

110
Rails makes use of the `ActiveSupport::Logger` class to write log information. Other loggers, such as `Log4r`, may also be substituted.
111

112
You can specify an alternative logger in `config/application.rb` or any other environment file, for example:
113

114
```ruby
115 116
config.logger = Logger.new(STDOUT)
config.logger = Log4r::Logger.new("Application Log")
117
```
118

119
Or in the `Initializer` section, add _any_ of the following
120

121
```ruby
122 123
Rails.logger = Logger.new(STDOUT)
Rails.logger = Log4r::Logger.new("Application Log")
124
```
125

V
Vijay Dev 已提交
126
TIP: By default, each log is created under `Rails.root/log/` and the log file is named after the environment in which the application is running.
127

128
### Log Levels
129

130
When something is logged, it's printed into the corresponding log if the log
131
level of the message is equal to or higher than the configured log level. If you
132 133 134 135 136 137
want to know the current log level, you can call the `Rails.logger.level`
method.

The available log levels are: `:debug`, `:info`, `:warn`, `:error`, `:fatal`,
and `:unknown`, corresponding to the log level numbers from 0 up to 5,
respectively. To change the default log level, use
138

139
```ruby
140
config.log_level = :warn # In any environment initializer, or
141
Rails.logger.level = 0 # at any time
142
```
143

144
This is useful when you want to log under development or staging without flooding your production log with unnecessary information.
145

146
TIP: The default Rails log level is `debug` in all environments.
147

148
### Sending Messages
149

150
To write in the current log use the `logger.(debug|info|warn|error|fatal)` method from within a controller, model or mailer:
151

152
```ruby
153 154 155
logger.debug "Person attributes hash: #{@person.attributes.inspect}"
logger.info "Processing the request..."
logger.fatal "Terminating application, raised unrecoverable error!!!"
156
```
157 158 159

Here's an example of a method instrumented with extra logging:

160
```ruby
161
class ArticlesController < ApplicationController
162 163 164
  # ...

  def create
165
    @article = Article.new(article_params)
166
    logger.debug "New article: #{@article.attributes.inspect}"
R
Robin Dupret 已提交
167
    logger.debug "Article should be valid: #{@article.valid?}"
168 169 170

    if @article.save
      logger.debug "The article was saved and now the user is going to be redirected..."
171
      redirect_to @article, notice: 'Article was successfully created.'
172
    else
173
      render :new
174 175 176 177
    end
  end

  # ...
178 179 180 181 182

  private
    def article_params
      params.require(:article).permit(:title, :body, :published)
    end
183
end
184
```
185

J
Jonathan Roes 已提交
186
Here's an example of the log generated when this controller action is executed:
187

188
```
189 190 191 192
Started POST "/articles" for 127.0.0.1 at 2017-08-20 20:53:10 +0900
Processing by ArticlesController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"xhuIbSBFytHCE1agHgvrlKnSVIOGD6jltW2tO+P6a/ACjQ3igjpV4OdbsZjIhC98QizWH9YdKokrqxBCJrtoqQ==", "article"=>{"title"=>"Debugging Rails", "body"=>"I'm learning how to print in logs!!!", "published"=>"0"}, "commit"=>"Create Article"}
New article: {"id"=>nil, "title"=>"Debugging Rails", "body"=>"I'm learning how to print in logs!!!", "published"=>false, "created_at"=>nil, "updated_at"=>nil}
R
Robin Dupret 已提交
193
Article should be valid: true
194 195 196
   (0.1ms)  BEGIN
  SQL (0.4ms)  INSERT INTO "articles" ("title", "body", "published", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["title", "Debugging Rails"], ["body", "I'm learning how to print in logs!!!"], ["published", "f"], ["created_at", "2017-08-20 11:53:10.010435"], ["updated_at", "2017-08-20 11:53:10.010435"]]
   (0.3ms)  COMMIT
197
The article was saved and now the user is going to be redirected...
198 199
Redirected to http://localhost:3000/articles/1
Completed 302 Found in 4ms (ActiveRecord: 0.8ms)
200
```
201

J
Jonathan Roes 已提交
202
Adding extra logging like this makes it easy to search for unexpected or unusual behavior in your logs. If you add extra logging, be sure to make sensible use of log levels to avoid filling your production logs with useless trivia.
V
Vijay Dev 已提交
203

204
### Tagged Logging
205

206
When running multi-user, multi-account applications, it's often useful
Y
Yves Senn 已提交
207
to be able to filter the logs using some custom rules. `TaggedLogging`
208
in Active Support helps you do exactly that by stamping log lines with subdomains, request ids, and anything else to aid debugging such applications.
V
Vijay Dev 已提交
209

210
```ruby
V
Vijay Dev 已提交
211 212 213 214
logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
logger.tagged("BCX") { logger.info "Stuff" }                            # Logs "[BCX] Stuff"
logger.tagged("BCX", "Jason") { logger.info "Stuff" }                   # Logs "[BCX] [Jason] Stuff"
logger.tagged("BCX") { logger.tagged("Jason") { logger.info "Stuff" } } # Logs "[BCX] [Jason] Stuff"
215
```
216

217
### Impact of Logs on Performance
218 219
Logging will always have a small impact on the performance of your Rails app,
        particularly when logging to disk. Additionally, there are a few subtleties:
220 221 222 223 224

Using the `:debug` level will have a greater performance penalty than `:fatal`,
      as a far greater number of strings are being evaluated and written to the
      log output (e.g. disk).

225
Another potential pitfall is too many calls to `Logger` in your code:
226 227 228 229 230

```ruby
logger.debug "Person attributes hash: #{@person.attributes.inspect}"
```

231
In the above example, there will be a performance impact even if the allowed
R
Robin Dupret 已提交
232 233
output level doesn't include debug. The reason is that Ruby has to evaluate
these strings, which includes instantiating the somewhat heavy `String` object
234
and interpolating the variables.
R
Robin Dupret 已提交
235
Therefore, it's recommended to pass blocks to the logger methods, as these are
236
only evaluated if the output level is the same as — or included in — the allowed level
237 238 239
(i.e. lazy loading). The same code rewritten would be:

```ruby
V
Vipul A M 已提交
240
logger.debug {"Person attributes hash: #{@person.attributes.inspect}"}
241 242
```

243 244
The contents of the block, and therefore the string interpolation, are only
evaluated if debug is enabled. This performance savings are only really
245 246
noticeable with large amounts of logging, but it's a good practice to employ.

247
Debugging with the `byebug` gem
248
---------------------------------
249

250 251 252 253 254
When your code is behaving in unexpected ways, you can try printing to logs or
the console to diagnose the problem. Unfortunately, there are times when this
sort of error tracking is not effective in finding the root cause of a problem.
When you actually need to journey into your running source code, the debugger
is your best companion.
255

256 257
The debugger can also help you if you want to learn about the Rails source code
but don't know where to start. Just debug any request to your application and
258 259
use this guide to learn how to move from the code you have written into the
underlying Rails code.
260

261
### Setup
262

263 264
You can use the `byebug` gem to set breakpoints and step through live code in
Rails. To install it, just run:
265

P
Prem Sichanugrist 已提交
266
```bash
267
$ gem install byebug
268
```
269

270 271
Inside any Rails application you can then invoke the debugger by calling the
`byebug` method.
272

273 274
Here's an example:

275
```ruby
276 277
class PeopleController < ApplicationController
  def new
278
    byebug
279 280 281
    @person = Person.new
  end
end
282
```
283

284
### The Shell
285

286 287 288 289
As soon as your application calls the `byebug` method, the debugger will be
started in a debugger shell inside the terminal window where you launched your
application server, and you will be placed at the debugger's prompt `(byebug)`.
Before the prompt, the code around the line that is about to be run will be
290
displayed and the current line will be marked by '=>', like this:
291

292
```
293
[1, 10] in /PathTo/project/app/controllers/articles_controller.rb
294
    3:
295 296
    4:   # GET /articles
    5:   # GET /articles.json
297 298
    6:   def index
    7:     byebug
299
=>  8:     @articles = Article.find_recent
300 301 302
    9:
   10:     respond_to do |format|
   11:       format.html # index.html.erb
303
   12:       format.json { render json: @articles }
304

305
(byebug)
306
```
307

308 309 310
If you got there by a browser request, the browser tab containing the request
will be hung until the debugger has finished and the trace has finished
processing the entire request.
311

312 313 314
For example:

```bash
315
=> Booting Puma
316
=> Rails 5.1.0 application starting in development on http://0.0.0.0:3000
317
=> Run `rails server -h` for more startup options
318
Puma starting in single mode...
319
* Version 3.4.0 (ruby 2.3.1-p112), codename: Owl Bowl Brawl
320
* Min threads: 5, max threads: 5
321 322
* Environment: development
* Listening on tcp://localhost:3000
323
Use Ctrl-C to stop
324 325
Started GET "/" for 127.0.0.1 at 2014-04-11 13:11:48 +0200
  ActiveRecord::SchemaMigration Load (0.2ms)  SELECT "schema_migrations".* FROM "schema_migrations"
326
Processing by ArticlesController#index as HTML
327

328
[3, 12] in /PathTo/project/app/controllers/articles_controller.rb
329
    3:
330 331
    4:   # GET /articles
    5:   # GET /articles.json
332 333
    6:   def index
    7:     byebug
334
=>  8:     @articles = Article.find_recent
335 336 337
    9:
   10:     respond_to do |format|
   11:       format.html # index.html.erb
338
   12:       format.json { render json: @articles }
339
(byebug)
340
```
341

342
Now it's time to explore your application. A good place to start is
343 344
by asking the debugger for help. Type: `help`

345
```
346
(byebug) help
347

348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
  break      -- Sets breakpoints in the source code
  catch      -- Handles exception catchpoints
  condition  -- Sets conditions on breakpoints
  continue   -- Runs until program ends, hits a breakpoint or reaches a line
  debug      -- Spawns a subdebugger
  delete     -- Deletes breakpoints
  disable    -- Disables breakpoints or displays
  display    -- Evaluates expressions every time the debugger stops
  down       -- Moves to a lower frame in the stack trace
  edit       -- Edits source files
  enable     -- Enables breakpoints or displays
  finish     -- Runs the program until frame returns
  frame      -- Moves to a frame in the call stack
  help       -- Helps you using byebug
  history    -- Shows byebug's history of commands
  info       -- Shows several informations about the program being debugged
  interrupt  -- Interrupts the program
  irb        -- Starts an IRB session
  kill       -- Sends a signal to the current process
  list       -- Lists lines of source code
  method     -- Shows methods of an object, class or module
  next       -- Runs one or more lines of code
  pry        -- Starts a Pry session
  quit       -- Exits byebug
  restart    -- Restarts the debugged program
  save       -- Saves current byebug session to a file
  set        -- Modifies byebug settings
  show       -- Shows byebug settings
  source     -- Restores a previously saved byebug session
  step       -- Steps into blocks or methods one or more times
  thread     -- Commands to manipulate threads
  tracevar   -- Enables tracing of a global variable
  undisplay  -- Stops displaying all or some expressions when program stops
  untracevar -- Stops tracing a global variable
  up         -- Moves to a higher frame in the stack trace
  var        -- Shows variables and its values
  where      -- Displays the backtrace
385

386
(byebug)
387
```
388

389
To see the previous ten lines you should type `list-` (or `l-`).
390

391
```
392
(byebug) l-
393

394 395 396
[1, 10] in /PathTo/project/app/controllers/articles_controller.rb
   1  class ArticlesController < ApplicationController
   2    before_action :set_article, only: [:show, :edit, :update, :destroy]
397
   3
398 399
   4    # GET /articles
   5    # GET /articles.json
400 401
   6    def index
   7      byebug
402
   8      @articles = Article.find_recent
403 404
   9
   10      respond_to do |format|
405
```
406

407 408 409
This way you can move inside the file and see the code above the line where you
added the `byebug` call. Finally, to see where you are in the code again you can
type `list=`
410

411
```
412
(byebug) list=
413

414
[3, 12] in /PathTo/project/app/controllers/articles_controller.rb
415
    3:
416 417
    4:   # GET /articles
    5:   # GET /articles.json
418 419
    6:   def index
    7:     byebug
420
=>  8:     @articles = Article.find_recent
421 422 423
    9:
   10:     respond_to do |format|
   11:       format.html # index.html.erb
424
   12:       format.json { render json: @articles }
425
(byebug)
426
```
427

428
### The Context
429

430 431
When you start debugging your application, you will be placed in different
contexts as you go through the different parts of the stack.
432

433 434 435
The debugger creates a context when a stopping point or an event is reached. The
context has information about the suspended program which enables the debugger
to inspect the frame stack, evaluate variables from the perspective of the
436
debugged program, and know the place where the debugged program is stopped.
437

438 439 440 441
At any time you can call the `backtrace` command (or its alias `where`) to print
the backtrace of the application. This can be very helpful to know how you got
where you are. If you ever wondered about how you got somewhere in your code,
then `backtrace` will supply the answer.
442

443
```
444
(byebug) where
445
--> #0  ArticlesController.index
446 447
      at /PathToProject/app/controllers/articles_controller.rb:8
    #1  ActionController::BasicImplicitRender.send_action(method#String, *args#Array)
448
      at /PathToGems/actionpack-5.1.0/lib/action_controller/metal/basic_implicit_render.rb:4
449
    #2  AbstractController::Base.process_action(action#NilClass, *args#Array)
450
      at /PathToGems/actionpack-5.1.0/lib/abstract_controller/base.rb:181
451
    #3  ActionController::Rendering.process_action(action, *args)
452
      at /PathToGems/actionpack-5.1.0/lib/action_controller/metal/rendering.rb:30
453
...
454
```
455

456
The current frame is marked with `-->`. You can move anywhere you want in this
457
trace (thus changing the context) by using the `frame n` command, where _n_ is
458 459
the specified frame number. If you do that, `byebug` will display your new
context.
460

461
```
462
(byebug) frame 2
463

464
[176, 185] in /PathToGems/actionpack-5.1.0/lib/abstract_controller/base.rb
465 466 467 468 469 470 471 472 473 474
   176:       # is the intended way to override action dispatching.
   177:       #
   178:       # Notice that the first argument is the method to be dispatched
   179:       # which is *not* necessarily the same as the action name.
   180:       def process_action(method_name, *args)
=> 181:         send_action(method_name, *args)
   182:       end
   183:
   184:       # Actually call the method associated with the action. Override
   185:       # this method if you wish to change how action methods are called,
475
(byebug)
476
```
477

478 479
The available variables are the same as if you were running the code line by
line. After all, that's what debugging is.
480

481 482 483 484
You can also use `up [n]` and `down [n]` commands in order to change the context
_n_ frames up or down the stack respectively. _n_ defaults to one. Up in this
case is towards higher-numbered stack frames, and down is towards lower-numbered
stack frames.
485

486
### Threads
487

488
The debugger can list, stop, resume and switch between running threads by using
R
Robin Dupret 已提交
489
the `thread` command (or the abbreviated `th`). This command has a handful of
490
options:
491

492
* `thread`: shows the current thread.
493 494 495 496 497
* `thread list`: is used to list all threads and their statuses. The current
thread is marked with a plus (+) sign.
* `thread stop n`: stops thread _n_.
* `thread resume n`: resumes thread _n_.
* `thread switch n`: switches the current thread context to _n_.
498

499 500
This command is very helpful when you are debugging concurrent threads and need
to verify that there are no race conditions in your code.
501

502
### Inspecting Variables
503

504 505
Any expression can be evaluated in the current context. To evaluate an
expression, just type it!
506

R
Robin Dupret 已提交
507
This example shows how you can print the instance variables defined within the
508
current context:
509

510
```
511
[3, 12] in /PathTo/project/app/controllers/articles_controller.rb
512
    3:
513 514
    4:   # GET /articles
    5:   # GET /articles.json
515 516
    6:   def index
    7:     byebug
517
=>  8:     @articles = Article.find_recent
518 519 520
    9:
   10:     respond_to do |format|
   11:       format.html # index.html.erb
521
   12:       format.json { render json: @articles }
522

523
(byebug) instance_variables
524 525 526
[:@_action_has_layout, :@_routes, :@_request, :@_response, :@_lookup_context,
 :@_action_name, :@_response_body, :@marked_for_same_origin_verification,
 :@_config]
527
```
528

529 530 531 532
As you may have figured out, all of the variables that you can access from a
controller are displayed. This list is dynamically updated as you execute code.
For example, run the next line using `next` (you'll learn more about this
command later in this guide).
533

534
```
535
(byebug) next
536

537 538
[5, 14] in /PathTo/project/app/controllers/articles_controller.rb
   5     # GET /articles.json
539 540
   6     def index
   7       byebug
541
   8       @articles = Article.find_recent
542 543 544
   9
=> 10       respond_to do |format|
   11         format.html # index.html.erb
545
   12         format.json { render json: @articles }
546 547 548 549
   13      end
   14    end
   15
(byebug)
550
```
551 552 553

And then ask again for the instance_variables:

554
```
555
(byebug) instance_variables
556 557 558
[:@_action_has_layout, :@_routes, :@_request, :@_response, :@_lookup_context,
 :@_action_name, :@_response_body, :@marked_for_same_origin_verification,
 :@_config, :@articles]
559
```
560

561 562
Now `@articles` is included in the instance variables, because the line defining
it was executed.
563

564
TIP: You can also step into **irb** mode with the command `irb` (of course!).
565
This will start an irb session within the context you invoked it.
566

567
The `var` method is the most convenient way to show variables and their values.
568
Let's have `byebug` help us with it.
569

570
```
571
(byebug) help var
572 573 574 575 576 577 578 579 580 581 582 583 584

  [v]ar <subcommand>

  Shows variables and its values


  var all      -- Shows local, global and instance variables of self.
  var args     -- Information about arguments of the current scope
  var const    -- Shows constants of an object.
  var global   -- Shows global variables.
  var instance -- Shows instance variables of self or a specific object.
  var local    -- Shows local variables in current scope.

585
```
586

587
This is a great way to inspect the values of the current context variables. For
588
example, to check that we have no local variables currently defined:
589

590
```
591
(byebug) var local
592
(byebug)
593
```
594 595 596

You can also inspect for an object method this way:

597
```
598
(byebug) var instance Article.new
599 600 601
@_start_transaction_state = {}
@aggregation_cache = {}
@association_cache = {}
602 603 604 605 606 607 608
@attributes = #<ActiveRecord::AttributeSet:0x007fd0682a9b18 @attributes={"id"=>#<ActiveRecord::Attribute::FromDatabase:0x007fd0682a9a00 @name="id", @value_be...
@destroyed = false
@destroyed_by_association = nil
@marked_for_destruction = false
@new_record = true
@readonly = false
@transaction_state = nil
609
```
610

611
You can also use `display` to start watching variables. This is a good way of
612
tracking the values of a variable while the execution goes on.
613

614
```
615 616
(byebug) display @articles
1: @articles = nil
617
```
618

619
The variables inside the displayed list will be printed with their values after
620
you move in the stack. To stop displaying a variable use `undisplay n` where
621
_n_ is the variable number (1 in the last example).
622

623
### Step by Step
624

625
Now you should know where you are in the running trace and be able to print the
626
available variables. But let's continue and move on with the application
627
execution.
628

629
Use `step` (abbreviated `s`) to continue running your program until the next
630 631 632
logical stopping point and return control to the debugger. `next` is similar to
`step`, but while `step` stops at the next line of code executed, doing just a
single step, `next` moves to the next line without descending inside methods.
633

634
For example, consider the following situation:
635

636
```
637
Started GET "/" for 127.0.0.1 at 2014-04-11 13:39:23 +0200
638
Processing by ArticlesController#index as HTML
639

640
[1, 6] in /PathToProject/app/models/article.rb
641
   1: class Article < ApplicationRecord
642 643 644 645 646
   2:   def self.find_recent(limit = 10)
   3:     byebug
=> 4:     where('created_at > ?', 1.week.ago).limit(limit)
   5:   end
   6: end
647

648
(byebug)
649
```
650

651 652 653
If we use `next`, we won't go deep inside method calls. Instead, `byebug` will
go to the next line within the same context. In this case, it is the last line
of the current method, so `byebug` will return to the next line of the caller
R
Robin Dupret 已提交
654 655
method.

656
```
657
(byebug) next
658
[4, 13] in /PathToProject/app/controllers/articles_controller.rb
659 660
    4:   # GET /articles
    5:   # GET /articles.json
661
    6:   def index
662
    7:     @articles = Article.find_recent
663 664 665
    8:
=>  9:     respond_to do |format|
   10:       format.html # index.html.erb
666
   11:       format.json { render json: @articles }
667 668 669
   12:     end
   13:   end

670
(byebug)
671
```
672

673 674
If we use `step` in the same situation, `byebug` will literally go to the next
Ruby instruction to be executed -- in this case, Active Support's `week` method.
675

676
```
677
(byebug) step
678

679
[49, 58] in /PathToGems/activesupport-5.1.0/lib/active_support/core_ext/numeric/time.rb
680 681 682 683 684
   49:
   50:   # Returns a Duration instance matching the number of weeks provided.
   51:   #
   52:   #   2.weeks # => 14 days
   53:   def weeks
685
=> 54:     ActiveSupport::Duration.weeks(self)
686 687 688 689
   55:   end
   56:   alias :week :weeks
   57:
   58:   # Returns a Duration instance matching the number of fortnights provided.
690
(byebug)
691
```
692

693
This is one of the best ways to find bugs in your code.
694

695 696
TIP: You can also use `step n` or `next n` to move forward `n` steps at once.

697
### Breakpoints
698

699 700
A breakpoint makes your application stop whenever a certain point in the program
is reached. The debugger shell is invoked in that line.
701

702 703
You can add breakpoints dynamically with the command `break` (or just `b`).
There are 3 possible ways of adding breakpoints manually:
704

705 706 707 708
* `break n`: set breakpoint in line number _n_ in the current source file.
* `break file:n [if expression]`: set breakpoint in line number _n_ inside
file named _file_. If an _expression_ is given it must evaluated to _true_ to
fire up the debugger.
709 710
* `break class(.|\#)method [if expression]`: set breakpoint in _method_ (. and
\# for class and instance method respectively) defined in _class_. The
711
_expression_ works the same way as with file:n.
712

713 714
For example, in the previous situation

715
```
716
[4, 13] in /PathToProject/app/controllers/articles_controller.rb
717 718
    4:   # GET /articles
    5:   # GET /articles.json
719
    6:   def index
720
    7:     @articles = Article.find_recent
721 722 723
    8:
=>  9:     respond_to do |format|
   10:       format.html # index.html.erb
724
   11:       format.json { render json: @articles }
725 726 727 728
   12:     end
   13:   end

(byebug) break 11
V
Vipul A M 已提交
729
Successfully created breakpoint with id 1
730

731
```
732

733 734
Use `info breakpoints` to list breakpoints. If you supply a number, it lists
that breakpoint. Otherwise it lists all breakpoints.
735

736
```
737
(byebug) info breakpoints
738
Num Enb What
739
1   y   at /PathToProject/app/controllers/articles_controller.rb:11
740
```
741

742
To delete breakpoints: use the command `delete n` to remove the breakpoint
743 744
number _n_. If no number is specified, it deletes all breakpoints that are
currently active.
745

746
```
747 748
(byebug) delete 1
(byebug) info breakpoints
749
No breakpoints.
750
```
751 752 753

You can also enable or disable breakpoints:

754 755
* `enable breakpoints [n [m [...]]]`: allows a specific breakpoint list or all
breakpoints to stop your program. This is the default state when you create a
756
breakpoint.
757 758
* `disable breakpoints [n [m [...]]]`: make certain (or all) breakpoints have
no effect on your program.
759

760
### Catching Exceptions
761

762 763 764
The command `catch exception-name` (or just `cat exception-name`) can be used to
intercept an exception of type _exception-name_ when there would otherwise be no
handler for it.
765

766
To list all active catchpoints use `catch`.
767

768
### Resuming Execution
769

770 771 772
There are two ways to resume execution of an application that is stopped in the
debugger:

773 774 775 776 777 778 779 780 781
* `continue [n]`: resumes program execution at the address where your script last
stopped; any breakpoints set at that address are bypassed. The optional argument
`n` allows you to specify a line number to set a one-time breakpoint which is
deleted when that breakpoint is reached.
* `finish [n]`: execute until the selected stack frame returns. If no frame
number is given, the application will run until the currently selected frame
returns. The currently selected frame starts out the most-recent frame or 0 if
no frame positioning (e.g up, down or frame) has been performed. If a frame
number is given it will run until the specified frame returns.
782

783
### Editing
784 785 786

Two commands allow you to open code from the debugger into an editor:

787 788
* `edit [file:n]`: edit file named _file_ using the editor specified by the
EDITOR environment variable. A specific line _n_ can also be given.
789

790
### Quitting
791

J
Jon Atack 已提交
792 793
To exit the debugger, use the `quit` command (abbreviated to `q`). Or, type `q!`
to bypass the `Really quit? (y/n)` prompt and exit unconditionally.
794

795 796
A simple quit tries to terminate all threads in effect. Therefore your server
will be stopped and you will have to start it again.
797

798
### Settings
799

800
`byebug` has a few available options to tweak its behavior:
801

802 803 804 805 806 807
```
(byebug) help set

  set <setting> <value>

  Modifies byebug settings
808

809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832
  Boolean values take "on", "off", "true", "false", "1" or "0". If you
  don't specify a value, the boolean setting will be enabled. Conversely,
  you can use "set no<setting>" to disable them.

  You can see these environment settings with the "show" command.

  List of supported settings:

  autosave       -- Automatically save command history record on exit
  autolist       -- Invoke list command on every stop
  width          -- Number of characters per line in byebug's output
  autoirb        -- Invoke IRB on every stop
  basename       -- <file>:<line> information after every stop uses short paths
  linetrace      -- Enable line execution tracing
  autopry        -- Invoke Pry on every stop
  stack_on_error -- Display stack trace when `eval` raises an exception
  fullpath       -- Display full file names in backtraces
  histfile       -- File where cmd history is saved to. Default: ./.byebug_history
  listsize       -- Set number of source lines to list by default
  post_mortem    -- Enable/disable post-mortem mode
  callstyle      -- Set how you want method call parameters to be displayed
  histsize       -- Maximum number of commands that can be stored in byebug history
  savefile       -- File where settings are saved to. Default: ~/.byebug_save
```
833

834 835
TIP: You can save these settings in an `.byebugrc` file in your home directory.
The debugger reads these global settings when it starts. For example:
836

P
Prem Sichanugrist 已提交
837
```bash
838
set callstyle short
839
set listsize 25
840
```
841

842 843 844 845 846 847 848 849 850
Debugging with the `web-console` gem
------------------------------------

Web Console is a bit like `byebug`, but it runs in the browser. In any page you
are developing, you can request a console in the context of a view or a
controller. The console would be rendered next to your HTML content.

### Console

851
Inside any controller action or view, you can invoke the console by
852 853 854 855 856
calling the `console` method.

For example, in a controller:

```ruby
857
class PostsController < ApplicationController
858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876
  def new
    console
    @post = Post.new
  end
end
```

Or in a view:

```html+erb
<% console %>

<h2>New Post</h2>
```

This will render a console inside your view. You don't need to care about the
location of the `console` call; it won't be rendered on the spot of its
invocation but next to your HTML content.

877
The console executes pure Ruby code: You can define and instantiate
878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898
custom classes, create new models and inspect variables.

NOTE: Only one console can be rendered per request. Otherwise `web-console`
will raise an error on the second `console` invocation.

### Inspecting Variables

You can invoke `instance_variables` to list all the instance variables
available in your context. If you want to list all the local variables, you can
do that with `local_variables`.

### Settings

* `config.web_console.whitelisted_ips`: Authorized list of IPv4 or IPv6
addresses and networks (defaults: `127.0.0.1/8, ::1`).
* `config.web_console.whiny_requests`: Log a message when a console rendering
is prevented (defaults: `true`).

Since `web-console` evaluates plain Ruby code remotely on the server, don't try
to use it in production.

899 900
Debugging Memory Leaks
----------------------
901

902
A Ruby application (on Rails or not), can leak memory — either in the Ruby code
903
or at the C code level.
904

905 906
In this section, you will learn how to find and fix such leaks by using tool
such as Valgrind.
907

908
### Valgrind
909

910 911
[Valgrind](http://valgrind.org/) is an application for detecting C-based memory
leaks and race conditions.
912

913 914 915 916
There are Valgrind tools that can automatically detect many memory management
and threading bugs, and profile your programs in detail. For example, if a C
extension in the interpreter calls `malloc()` but doesn't properly call
`free()`, this memory won't be available until the app terminates.
917

918 919 920
For further information on how to install Valgrind and use with Ruby, refer to
[Valgrind and Ruby](http://blog.evanweaver.com/articles/2008/02/05/valgrind-and-ruby/)
by Evan Weaver.
921

922 923
Plugins for Debugging
---------------------
924

925 926 927 928 929 930
There are some Rails plugins to help you to find errors and debug your
application. Here is a list of useful plugins for debugging:

* [Footnotes](https://github.com/josevalim/rails-footnotes) Every Rails page has
footnotes that give request information and link back to your source via
TextMate.
931
* [Query Trace](https://github.com/ruckus/active-record-query-trace/tree/master) Adds query
932
origin tracing to your logs.
933
* [Query Reviewer](https://github.com/nesquena/query_reviewer) This Rails plugin
934 935 936 937 938 939 940 941 942 943 944
not only runs "EXPLAIN" before each of your select queries in development, but
provides a small DIV in the rendered output of each page with the summary of
warnings for each query that it analyzed.
* [Exception Notifier](https://github.com/smartinez87/exception_notification/tree/master)
Provides a mailer object and a default set of templates for sending email
notifications when errors occur in a Rails application.
* [Better Errors](https://github.com/charliesome/better_errors) Replaces the
standard Rails error page with a new one containing more contextual information,
like source code and variable inspection.
* [RailsPanel](https://github.com/dejan/rails_panel) Chrome extension for Rails
development that will end your tailing of development.log. Have all information
945
about your Rails app requests in the browser — in the Developer Tools panel.
946 947
Provides insight to db/rendering/total times, parameter list, rendered views and
more.
948
* [Pry](https://github.com/pry/pry) An IRB alternative and runtime developer console.
949

950 951
References
----------
952

953
* [byebug Homepage](https://github.com/deivid-rodriguez/byebug)
954
* [web-console Homepage](https://github.com/rails/web-console)