Rails 调试

看到还有开发人员读到这篇,起到了一些作用,并且回复了,实在是感动。一转眼,3年多过去了。想想写这篇的时候,已经今非昔比,感慨啊。不废话了,回来说rails调试

当前的情况是,Ruby1.9.3-194p Rails3.2.8
流行的调试工具gem是 debugger

这个debugger更新的目的是,解决ruby1.9后的更新问题,兼容debugger和rvm的问题

未来的趋势的 pry
rails部分用 pry-nav
Ruby代码   收藏代码
  1. gem 'pry'  
  2. gem 'pry-remote'  
  3. gem 'pry-nav'  

基本上的使用非常简单,所有的alias都在,怎么用debugger就怎么用pry,当然,pry有些advance功能。
回头看看有没有好的pry总结, 先留个链接,有时间了我就更新一个介绍。

不知道下次再更新这篇的时候。。。。。

祝福,看到本篇的ruby攻城狮,前程似锦
-------------------------时空小分割-------------------------



快写完的时候想说
       今天是清明节,大放假的,我基本上没干什么别的.希望诸位,看到这篇文章的人们,能够有点收获吧. 这样我还欣慰点, 我的时间就没有白白浪费.

    这真是一篇又臭又长的文章啊.一边调试一边写已经,好几个,好几个小时了...

   基本上可以用来当rails调试中文指南,或者ruby-dubug的中文手册了.


Ruby代码   收藏代码
  1. $ rdebug test.rb   



  本篇主要是为了说明如何进行Rails调试的.但ruby-debug本身不是Rails的插件,也就是说ruby-debug是调试ruby程序.

1. 安装ruby-debug

那么,安装自然,就不是Rails的插件安装,下载gem包,或者直接gem安装如下:

Linux代码   收藏代码
  1. gem install ruby-debug -y  


2. 在rails中如何配置

修改环境配置文件:
Ruby代码   收藏代码
  1. # config/environments/development.rb   
  2. config.breakpoint_server = true  
  3. require "ruby-debug"  


增加断点
在需要调试的代码部分增加debugger
Ruby代码   收藏代码
  1. def new   
  2.  @story = Story.new(params[:story])   
  3.  @story.user = @current_user   
  4.   
  5.  if request.post? and @story.save   
  6.    debugger   
  7.    @story.tag_with params[:tagsif params[:tags]   
  8.    flash[:notice] = "Story submission succeeded"   
  9.    redirect_to :action => 'index'   
  10.  end   
  11. end  


启动运行

Ruby代码   收藏代码
  1. ruby script/server -e development  





调试运行界面



基本命令详解
1. help
第一个,最重要的命令
Ruby代码   收藏代码
  1. (rdb:5) help  
  2. ruby-debug help v0.10.3  

你可以用help cmd看cmd命令的内容详情

这里说明我的ruby-debug是0.10.3版.这个版本的一些命令已经和之前版本的命令差很多了.

2. list

用来浏览代码列表和目前断点的位置
Ruby代码   收藏代码
  1. (rdb:2) list  
  2. [54, 63] in ./script/../config/../app/controllers/user_controller.rb  
  3.    54      end  
  4.    55    end  
  5.    56    
  6.    57    def login  
  7.    58      debugger  
  8. => 59      user = User.auth(@params['login'], @params['pwd'])  
  9.    60      if user  
  10.    61        @session[USER_PARAM] = user  
  11.    62        set_filter(user)  
  12.    63      else  


多次打list可以看下面的代码.
Ruby代码   收藏代码
  1. l[ist]          #列出当前代码,再次输入,列出后面代码  
  2. l[ist] -        #列出当前代码,往前的代码  
  3. l[ist] =        #列出当前行代码  
  4. l[ist] nn-mm    #列出给定行的代码  


3. where

用于查看当前程序运行的堆栈情况
Ruby代码   收藏代码
  1. (rdb:2) where  
  2. --> #1 ./script/../config/../app/controllers/user_controller.rb:59:in `login'  
  3.     #2 /usr/.../action_controller/base.rb:910:in `perform_action_without_filters'  
  4.     #3 /usr/.../action_controller/filters.rb:368:in `perform_action_without_benchmark'  
  5.     #4 /usr/.../action_controller/benchmarking.rb:69:in `measure'  
  6.     #5 /usr/.../action_controller/benchmarking.rb:69:in `perform_action_without_rescue'  
  7.     #6 /usr/.../action_controller/rescue.rb:82:in `perform_action'  
  8.     ...  


4. up/down

使用up和down命令可以在之前的where显示的堆栈中进行调试.并可以结合list和察看变量的方法,进行动态的调试.
如下:

Ruby代码   收藏代码
  1. (rdb:2) up 2  
  2. #3 /usr/.../action_controller/filters.rb:368:in `perform_action_without_benchmark'  
  3. (rdb:2) l  
  4. [363, 372] in /usr/.../action_controller/filters.rb  
  5.    363    
  6.    364        def perform_action_with_filters  
  7.    365          before_action_result = before_action  
  8.    366    
  9.    367          unless before_action_result == false || performed?  
  10. => 368            perform_action_without_filters  
  11.    369            after_action  
  12.    370          end  
  13.    371    
  14.    372          @before_filter_chain_aborted = (before_action_result == false)  
  15. (rdb:2) before_action_result  
  16. [:verify_login:verify_access]  
  17. (rdb:2) performed?  
  18. false  
  19. (rdb:2) down 2  


5. step/next

Ruby代码   收藏代码
  1. s[tep][+-]?[ nnn]         
  2.                 #nnn 表示次数  
  3.                 #'+' 强制向其它线程  
  4.                 #'-' 和上面相反并且禁用掉force_stepping setting.  

单步执行,使用next命令向下执行而不进入命令本身.这两个都支持一个数字的参数表明执行多少:


Ruby代码   收藏代码
  1. (rdb:2) s  
  2. script/../config/../app/models/user.rb:27:    find :first,   
  3. (rdb:2) l  
  4. [22, 31] in script/../config/../app/models/user.rb  
  5.    22    def status_name  
  6.    23      STATUS_NAMES[self.status]  
  7.    24    end  
  8.    25    
  9.    26    def self.auth(login, pwd)  
  10. => 27      find :first,   
  11.    28        :conditions => ["login = ? AND pwd = ? AND status = ?",   
  12.    29                      login, pwd, ACTIVE]  
  13.    30    end  
  14.    31    
  15.    32    def is_admin?  


6. Thread

Ruby代码   收藏代码
  1. th[read] l[ist]                # 列出所有的线程  
  2. th[read] stop <nnn>            # 停止指定线程  
  3. th[read] resume <nnn>          # 恢复指定线程  
  4. th[read] [sw[itch]] <nnn>      # 切换执行环境到指定线程  
  5. th[read] [cur[rent]]           # 显示当前线程  


用列出和切换线程,示例如下:
Ruby代码   收藏代码
  1. (rdb:2) thread list  
  2.  1 #<Thread:0x1f17c4 sleep> /usr/local/lib/ruby/1.8/webrick/server.rb:91  
  3. +2 #<Thread:0x4b3b2b8 run> script/../config/../app/models/user.rb:27  
  4.  31 #<Thread:0x4b61238 sleep> /usr/local/lib/ruby/1.8/drb/drb.rb:944  
  5. (rdb:2)  
  6. By the way, the debugger prompt also shows the current thread number (rdb:2).  


7. var

Ruby代码   收藏代码
  1. v[ar] cl[ass]                   #显示当前上下文的所有类变量  
  2. v[ar] c[onst] <object>          #显示当前上下文的常数对象  
  3. v[ar] g[lobal]                  #显示当前上下文的全局变量  
  4. v[ar] i[nstance] <object>       #显示当前上下文的当前对象的实例变量  
  5. v[ar] l[ocal]                   #显示当前上下文的所有局部变量  


这个命令相当的强大,比起breakpoint的params来说,也是经常用到的.显示当前上下文的变量参数情况.例子如下:
Ruby代码   收藏代码
  1. (rdb:2) var local  
  2.   login => "admin"  
  3.   pwd => "letmein"  
  4. (rdb:2) var global  
  5.   $! => nil  
  6.   $" => ["rubygems.rb", "rbconfig.rb", "rubygems/rubygems_version.rb",   
  7. ...  


8. breakpoint
Ruby代码   收藏代码
  1. b[reak] file:line [if expr] #在expr的条件下,设在文件的第几行设置断点  
  2. b[reak] class(.|#)method [if expr] #在expr成立条件下,设置断点在类的方法下  


在特点条件的断点,也是很方便的地方.示例如下:

Ruby代码   收藏代码
  1. #以下代码由夜鸣猪@javaeye奉献  
  2. (rdb:1) l #list的简写,显示当前位置  
  3.    26      #breakpoint  
  4.    27      @current_item = @cart.add_product(product)  
  5.    28      debugger  
  6. => 29        respond_to do |format|  
  7.    30          format.js if request.xhr?  
  8.    31          format.html {redirect_to_index}  
  9.    32        end  
  10.    33    rescue ActiveRecord::RecordNotFound  
  11. (rdb:1) where  
  12. --> #0 StoreController.add_to_cart  
  13.        at line D:/RORWS/depot_t/app/controllers/store_controller.rb:29  
  14. Warning: saved frames may be incomplete; compare with caller(0).  
  15. (rdb:1) b 30 #在第30行设置断点  
  16. Breakpoint 1 file D:/RORWS/depot_t/app/controllers/store_controller.rb, line 30  
  17. (rdb:1) c #continue的缩写,推出debug环境执行  
  18. Breakpoint 1 at store_controller.rb:30 #断点调试,中断了  
  19. D:/RORWS/depot_t/app/controllers/store_controller.rb:30  
  20. format.js if request.xhr?  
  21. (rdb:1) l #再看一下位置  
  22. [25, 34] in D:/RORWS/depot_t/app/controllers/store_controller.rb  
  23.    25      product = Product.find(params[:id])  
  24.    26      #breakpoint  
  25.    27      @current_item = @cart.add_product(product)  
  26.    28      debugger  
  27.    29        respond_to do |format|  
  28. => 30          format.js if request.xhr?  
  29.    31          format.html {redirect_to_index}  
  30.    32        end  
  31.    33    rescue ActiveRecord::RecordNotFound  
  32.    34      logger.error("Attempt to access invalid product #{params[:id]}")  
  33. (rdb:2) b 72 if params['user'] == 'admin' #在admin的条件下设置断点  
  34. Set breakpoint 1 at ./script/.../controllers/user_controller.rb:69  
  35. To list all breakpoints use break command without parameters:  
  36. (rdb:1) info break # 显示当前都设置了什么断点  
  37. Num Enb What  
  38.   1 y   at store_controller.rb:30  
  39.         breakpoint already hit 1 time  


9. continue

这个简单继续执行
Ruby代码   收藏代码
  1. (rdb:2) cont  
  2. 127.0.0.1 - - [11/07/2006:15:09 EDT] "POST /user/login HTTP/1.1" 302 96  
  3. http://localhost:3000/bug/list -> /user/login  
  4. 127.0.0.1 - - [11/07/2006:15:12 EDT] "GET /bug/list HTTP/1.1" 200 3830  
  5. http://localhost:3000/bug/list -> /bug/list  


10. delete

Ruby代码   收藏代码
  1. del[ete][ nnn...]       #删除指定或者所有breakpoints  


11. save
Ruby代码   收藏代码
  1. save [FILE]  


将当前debugger的状态保存成为文件,保存的状态,包括所有设定breakpoints,设定, 捕获的断点.不写文件名会假定生成一个.
使用source命令,得到相关信息.
12. catch
Ruby代码   收藏代码
  1. cat[ch]          #等同与 "info catch"  
  2. cat[ch] <exception-name>      #拦截<exception-name>所指定的异常  


13. backtrace
Ruby代码   收藏代码
  1. bt|backtrace            #where - display的别名  
  2. (rdb:8) backtrace  
  3. --> #0 StoreController.add_to_cart  
  4.        at line D:/RORWS/depot_t/app/controllers/store_controller.rb:29  
  5.     #1 Kernel.send  
  6.        at line c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/base.rb:1253  
  7.     #2 ActionController::Base.perform_action_without_filters  
  8.        at line c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/base.rb:1253  
  9.     #3 ActionController::Filters::InstanceMethods.call_filters(chain#ActionController::Fil...,...)  
  10.        at line c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/filters.rb:617  


显示所有堆栈的执行信息.使用"up" and "down" 可以调试和改变在堆栈的执行.当前的位置使用-->符号表明.

14. edit
修改特定文件.如果没有任何参数,则显示当前最近修改的行.用FILE:LINENUM的格式指定修改的文件和行号.以便一即使修改

15. quit
Ruby代码   收藏代码
  1. q[uit] [unconditionally]        #从调试环境推出.  
  2. exit    #就是quit命令的别名  


通常情况下,退出之前会有,确认提示. 然而,如果quit命令使用了参数"unconditionally",将不会有提示信息.


16. set

设定ruby-debug的环境,Boolean变量可以设定为on off或者1 0.设定变量可以用show显示
Ruby代码   收藏代码
  1. set annotate # 设定注释等级  
  2. set args # 设定变量列表,用来传递给运行环境  
  3. set autoeval # 在不能直接输出的表达式,进行eval计算  
  4. set autolist # 在每个breakpoint时执行list  
  5. set autoirb # 任何时候只要stop则执行irb  
  6. set autoreload # 当代码有修改的时候,从新load  
  7. set basename # 设定basename只显示文件名  
  8. set callstyle # 设定显示变量格式  
  9. set debuggertesting # 用于测试debugger自身  
  10. set forcestep # 保证'next/step'命令总是能向新行移动  
  11. set fullpath # 在frames中显示文件的完整路径名  
  12. set history # Generic command for setting command history parameters  
  13. set keep-frame-bindings # Save frame binding on each call  
  14. set linetrace+ # Set line execution tracing to show different lines  
  15. set linetrace # Set line execution tracing  
  16. set listsize # Set number of source lines to list by default  
  17. set trace # Display stack trace when 'eval' raises exception  
  18. set width # Number of characters the debugger thinks are in a line  

17. info

显示相关信息

Ruby代码   收藏代码
  1. info args # Argument variables of current stack frame  
  2. info breakpoints  # 显示当前所有断点的状态  
  3. info catch # 可以被捕获的Exceptions,通过catch命令设定  
  4. info display  # 程序结束时的输出  
  5. info file # 关于读取文件的内容  
  6. info files # 关于读取文件的时间和名字等信息  
  7. info global_variables # 所有全局变量  
  8. info instance_variables # 当前frame的示例变量  
  9. info line # 当前文件的当前行有关信息  
  10. info locals # 局部变量信息  
  11. info program # 程序执行状态信息  
  12. info stack # 相关stack信息  
  13. info thread # Thread相关信息  
  14. info threads # Thread相关信息  
  15. info variables # 局部变量示例变量信息  


18. show
Ruby代码   收藏代码
  1. show annotate # 显示注释级别  
  2. show args # 显示当程序要执行时的参数列表  
  3. show autoeval # 是否显示当遇到不识别命令  
  4. show autolist # 显示是否自动list的设定  
  5. show autoirb # 显示是否有设定autoirb  
  6. show autoreload # 显示是否有设定autoreload  
  7. show basename # Show if basename used in reporting files  
  8. show callstyle # Show paramater style used showing call frames  
  9. show commands # Show the history of commands you typed  
  10. show forcestep # Show if sure 'next/step' forces move to a new line  
  11. show fullpath # Show if full file names are displayed in frames  
  12. show history # Generic command for showing command history parameters  
  13. show keep-frame-bindings # Save frame binding on each call  
  14. show linetrace # 显示行执行信息  
  15. show linetrace+ # Show if consecutive lines should be different are shown in tracing  
  16. show listsize # Show number of source lines to list by default  
  17. show port # Show server port  
  18. show post-mortem # Show whether we go into post-mortem debugging on an uncaught exception  
  19. show trace # Show if a stack trace is displayed when 'eval' raises exception  
  20. show version # 显示debug版本号  
  21. show width # 显示调试信息的行字数  



19. condition

Ruby代码   收藏代码
  1. Condition breakpoint-number expression  


给特定的brakepoint添加,执行条件.如果,expression为空,那么断点执行的约束,取消
20. eval
Ruby代码   收藏代码
  1. e[val] expression   #    计算表达式的值并输出  
  2.                     #    可以做为p别名.  

* 提示 - 如果,想要设定为自动调用eval进行,表达式计算.需要设定autoeval 使用命令
Ruby代码   收藏代码
  1. use 'set autoeval'  

21. reload
Ruby代码   收藏代码
  1. r[eload]        forces source code reloading  

22. ps
Ruby代码   收藏代码
  1. ps expression   #计算数组,集合,序列,表达式组的值,并序列化输出  

23. undisplay
Ruby代码   收藏代码
  1. undisp[lay][ nnn]  

取消一些表达式的输出
引用

Arguments are the code numbers of the expressions to stop displaying.
No argument means cancel all automatic-display expressions.
"delete display" has the same effect as this command.
Do "info display" to see current list of code numbers.

24. irb
Ruby代码   收藏代码
  1. irb    # 打开一个(IRB) 环境  

25. finish

Ruby代码   收藏代码
  1. fin[ish] [frame-number] #Execute until selected stack frame returns.  


引用
If no frame number is given, we 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 we run until that frame
returns.

你可能感兴趣的:(on,Ruby,Rails)