How do I configure ruby to enter the debugger on Ctrl-C (SIGINT)?

后端 未结 2 1538
星月不相逢
星月不相逢 2020-12-11 23:12

I\'d like to enter the debugger upon typing ctrl-C (or sending a SIGINT). I have installed the debugger (I\'m running Ruby 1.9.3) and verified that it works. I\'ve added t

相关标签:
2条回答
  • 2020-12-11 23:34

    You may try to use GDB wrapper for Ruby (GitHub).

    Install on Linux via:

    sudo apt-get install gdb python-dev ncurses-dev ruby-rvm
    gem install gdb.rb
    

    Basic usage:

    require 'gdb'
    
    # create a new GDB::Ruby instance and attach it to
    # pid 12345
    gdb = GDB::Ruby.new(12345)
    
    # print the (ruby) backtrace of the remote process
    gdb.backtrace.each { |line| puts line }
    
    # show the current local variables, and their values
    p gdb.local_variables
    
    # evaluate arbitrary ruby code in the remote process
    p gdb.eval('%(pid #{$$})')
    
    # show how many instances of each class exist in the
    # remote process
    p gdb.object_space
    
    # raise an exception in the remote process
    gdb.raise Exception, "go boom!"
    
    # close the connection to the remote process
    gdb.quit
    

    Or to debug the hung process, attach it via:

    rvmsudo gdb.rb PID
    

    then:

    # in gdb get a ruby stacktrace with file names and line numbers
    # here I'm filtering by files that are actually in my app dir
    (gdb) ruby eval caller.select{|l| l =~ /app\//}
    

    Source: Using gdb to inspect a hung ruby process

    Some alternatives:

    • rbtrace - like strace, but for ruby code (usage: rbtrace -p <PID> --firehose).
    • debug.rb script by tmm1 (author of gdb.rb) which can help to debug a process using strace/gdb.

    See also:

    • Debugging Ruby Tools
    • Check why ruby script hangs
    0 讨论(0)
  • 2020-12-11 23:35

    If you want to trap SIGINT while running in the console, the short answer is: you cannot unless you monkey-patch IRB. Every Ruby app (whether padrino, or rails or whatnot) that uses the console will end up calling usr/lib/ruby/1.9.1/irb.rb, and in IRB.start, it does:

    trap("SIGINT") do
      irb.signal_handle
    end
    

    ... just before entering the main loop. This will override any trap("SIGINT") you might have put in your startup code.

    But if you want to trap SIGINT in a script file (for example, if you want to profile your code as described by Mike Dunlavey here), you can create a script file such as:

    # File: profile_complex_operation.rb
    trap("SIGINT") { debugger }
    MyApp.complex_operation
    

    and then invoke it as in:

    $ ruby profile_complex_operation.rb
    

    Now, when you hit ^C (or send SIGINT from another process), it will enter the debugger.

    0 讨论(0)
提交回复
热议问题