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
Processing ArticlesController#create (for 127.0.0.1 at 2008-09-08 11:52:54) [POST]
190 191
  Session ID: BAh7BzoMY3NyZl9pZCIlMDY5MWU1M2I1ZDRjODBlMzkyMWI1OTg2NWQyNzViZjYiCmZsYXNoSUM6J0FjdGl
vbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhhc2h7AAY6CkB1c2VkewA=--b18cd92fba90eacf8137e5f6b3b06c4d724596a4
192
  Parameters: {"commit"=>"Create", "article"=>{"title"=>"Debugging Rails",
193
 "body"=>"I'm learning how to print in logs!!!", "published"=>"0"},
194 195
 "authenticity_token"=>"2059c1286e93402e389127b1153204e0d1e275dd", "action"=>"create", "controller"=>"articles"}
New article: {"updated_at"=>nil, "title"=>"Debugging Rails", "body"=>"I'm learning how to print in logs!!!",
R
Robin Dupret 已提交
196 197
 "published"=>false, "created_at"=>nil}
Article should be valid: true
198
  Article Create (0.000443)   INSERT INTO "articles" ("updated_at", "title", "body", "published",
199 200
 "created_at") VALUES('2008-09-08 14:52:54', 'Debugging Rails',
 'I''m learning how to print in logs!!!', 'f', '2008-09-08 14:52:54')
201 202 203
The article was saved and now the user is going to be redirected...
Redirected to # Article:0x20af760>
Completed in 0.01224 (81 reqs/sec) | DB: 0.00044 (3%) | 302 Found [http://localhost/articles]
204
```
205

J
Jonathan Roes 已提交
206
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 已提交
207

208
### Tagged Logging
209

210
When running multi-user, multi-account applications, it's often useful
Y
Yves Senn 已提交
211
to be able to filter the logs using some custom rules. `TaggedLogging`
212
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 已提交
213

214
```ruby
V
Vijay Dev 已提交
215 216 217 218
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"
219
```
220

221
### Impact of Logs on Performance
222 223
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:
224 225 226 227 228

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).

229
Another potential pitfall is too many calls to `Logger` in your code:
230 231 232 233 234

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

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

```ruby
V
Vipul A M 已提交
244
logger.debug {"Person attributes hash: #{@person.attributes.inspect}"}
245 246
```

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

251
Debugging with the `byebug` gem
252
---------------------------------
253

254 255 256 257 258
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.
259

260 261
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
262 263
use this guide to learn how to move from the code you have written into the
underlying Rails code.
264

265
### Setup
266

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

P
Prem Sichanugrist 已提交
270
```bash
271
$ gem install byebug
272
```
273

274 275
Inside any Rails application you can then invoke the debugger by calling the
`byebug` method.
276

277 278
Here's an example:

279
```ruby
280 281
class PeopleController < ApplicationController
  def new
282
    byebug
283 284 285
    @person = Person.new
  end
end
286
```
287

288
### The Shell
289

290 291 292 293
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
294
displayed and the current line will be marked by '=>', like this:
295

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

309
(byebug)
310
```
311

312 313 314
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.
315

316 317 318
For example:

```bash
319
=> Booting Puma
320
=> Rails 5.1.0 application starting in development on http://0.0.0.0:3000
321
=> Run `rails server -h` for more startup options
322
Puma starting in single mode...
323
* Version 3.4.0 (ruby 2.3.1-p112), codename: Owl Bowl Brawl
324
* Min threads: 5, max threads: 5
325 326
* Environment: development
* Listening on tcp://localhost:3000
327
Use Ctrl-C to stop
328 329
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"
330
Processing by ArticlesController#index as HTML
331

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

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

349
```
350
(byebug) help
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 385 386 387 388
  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
389

390
(byebug)
391
```
392

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

395
```
396
(byebug) l-
397

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

411 412 413
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=`
414

415
```
416
(byebug) list=
417

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

432
### The Context
433

434 435
When you start debugging your application, you will be placed in different
contexts as you go through the different parts of the stack.
436

437 438 439
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
440
debugged program, and know the place where the debugged program is stopped.
441

442 443 444 445
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.
446

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

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

465
```
466
(byebug) frame 2
467

468
[176, 185] in /PathToGems/actionpack-5.1.0/lib/abstract_controller/base.rb
469 470 471 472 473 474 475 476 477 478
   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,
479
(byebug)
480
```
481

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

485 486 487 488
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.
489

490
### Threads
491

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

496
* `thread`: shows the current thread.
497 498 499 500 501
* `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_.
502

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

506
### Inspecting Variables
507

508 509
Any expression can be evaluated in the current context. To evaluate an
expression, just type it!
510

R
Robin Dupret 已提交
511
This example shows how you can print the instance variables defined within the
512
current context:
513

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

527
(byebug) instance_variables
528 529 530
[:@_action_has_layout, :@_routes, :@_request, :@_response, :@_lookup_context,
 :@_action_name, :@_response_body, :@marked_for_same_origin_verification,
 :@_config]
531
```
532

533 534 535 536
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).
537

538
```
539
(byebug) next
540

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

And then ask again for the instance_variables:

558
```
559
(byebug) instance_variables
560 561 562
[:@_action_has_layout, :@_routes, :@_request, :@_response, :@_lookup_context,
 :@_action_name, :@_response_body, :@marked_for_same_origin_verification,
 :@_config, :@articles]
563
```
564

565 566
Now `@articles` is included in the instance variables, because the line defining
it was executed.
567

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

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

574
```
575
(byebug) help var
576 577 578 579 580 581 582 583 584 585 586 587 588

  [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.

589
```
590

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

594
```
595
(byebug) var local
596
(byebug)
597
```
598 599 600

You can also inspect for an object method this way:

601
```
602
(byebug) var instance Article.new
603 604 605
@_start_transaction_state = {}
@aggregation_cache = {}
@association_cache = {}
606 607 608 609 610 611 612
@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
613
```
614

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

618
```
619 620
(byebug) display @articles
1: @articles = nil
621
```
622

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

627
### Step by Step
628

629
Now you should know where you are in the running trace and be able to print the
630
available variables. But let's continue and move on with the application
631
execution.
632

633
Use `step` (abbreviated `s`) to continue running your program until the next
634 635 636
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.
637

638
For example, consider the following situation:
639

640
```
641
Started GET "/" for 127.0.0.1 at 2014-04-11 13:39:23 +0200
642
Processing by ArticlesController#index as HTML
643

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

652
(byebug)
653
```
654

655 656 657
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 已提交
658 659
method.

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

674
(byebug)
675
```
676

677 678
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.
679

680
```
681
(byebug) step
682

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

697
This is one of the best ways to find bugs in your code.
698

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

701
### Breakpoints
702

703 704
A breakpoint makes your application stop whenever a certain point in the program
is reached. The debugger shell is invoked in that line.
705

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

709 710 711 712
* `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.
713 714
* `break class(.|\#)method [if expression]`: set breakpoint in _method_ (. and
\# for class and instance method respectively) defined in _class_. The
715
_expression_ works the same way as with file:n.
716

717 718
For example, in the previous situation

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

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

735
```
736

737 738
Use `info breakpoints` to list breakpoints. If you supply a number, it lists
that breakpoint. Otherwise it lists all breakpoints.
739

740
```
741
(byebug) info breakpoints
742
Num Enb What
743
1   y   at /PathToProject/app/controllers/articles_controller.rb:11
744
```
745

746
To delete breakpoints: use the command `delete n` to remove the breakpoint
747 748
number _n_. If no number is specified, it deletes all breakpoints that are
currently active.
749

750
```
751 752
(byebug) delete 1
(byebug) info breakpoints
753
No breakpoints.
754
```
755 756 757

You can also enable or disable breakpoints:

758 759
* `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
760
breakpoint.
761 762
* `disable breakpoints [n [m [...]]]`: make certain (or all) breakpoints have
no effect on your program.
763

764
### Catching Exceptions
765

766 767 768
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.
769

770
To list all active catchpoints use `catch`.
771

772
### Resuming Execution
773

774 775 776
There are two ways to resume execution of an application that is stopped in the
debugger:

777 778 779 780 781 782 783 784 785
* `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.
786

787
### Editing
788 789 790

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

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

794
### Quitting
795

J
Jon Atack 已提交
796 797
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.
798

799 800
A simple quit tries to terminate all threads in effect. Therefore your server
will be stopped and you will have to start it again.
801

802
### Settings
803

804
`byebug` has a few available options to tweak its behavior:
805

806 807 808 809 810 811
```
(byebug) help set

  set <setting> <value>

  Modifies byebug settings
812

813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836
  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
```
837

838 839
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:
840

P
Prem Sichanugrist 已提交
841
```bash
842
set callstyle short
843
set listsize 25
844
```
845

846 847 848 849 850 851 852 853 854
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

855
Inside any controller action or view, you can invoke the console by
856 857 858 859 860
calling the `console` method.

For example, in a controller:

```ruby
861
class PostsController < ApplicationController
862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880
  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.

881
The console executes pure Ruby code: You can define and instantiate
882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902
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.

903 904
Debugging Memory Leaks
----------------------
905

906
A Ruby application (on Rails or not), can leak memory — either in the Ruby code
907
or at the C code level.
908

909 910
In this section, you will learn how to find and fix such leaks by using tool
such as Valgrind.
911

912
### Valgrind
913

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

917 918 919 920
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.
921

922 923 924
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.
925

926 927
Plugins for Debugging
---------------------
928

929 930 931 932 933 934
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.
935
* [Query Trace](https://github.com/ruckus/active-record-query-trace/tree/master) Adds query
936
origin tracing to your logs.
937
* [Query Reviewer](https://github.com/nesquena/query_reviewer) This Rails plugin
938 939 940 941 942 943 944 945 946 947 948
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
949
about your Rails app requests in the browser — in the Developer Tools panel.
950 951
Provides insight to db/rendering/total times, parameter list, rendered views and
more.
952
* [Pry](https://github.com/pry/pry) An IRB alternative and runtime developer console.
953

954 955
References
----------
956

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