cldwalker/debugger

officially support ruby 2.X

Closed this issue · 57 comments

I do not forsee spending anytime on this in the near future. Any pull requests to help make this happen would be greatly appreciated by the ruby community.
#68 gets 2.0.0 partially working but the test suite does not work. I will not consider 2.0.0 officially supported or close this ticket until tests are passing. Here is what I see when I run tests:

$ rake
** Invoke default (first_time)
** Invoke test (first_time)
** Execute test
/Users/me/Developer/.rbenv/versions/2.0.0-p0/bin/ruby -I"lib" -I"/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib" "/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib/rake/rake_test_loader.rb" "test/breakpoints_test.rb" "test/conditions_test.rb" "test/continue_test.rb" "test/display_test.rb" "test/edit_test.rb" "test/eval_test.rb" "test/finish_test.rb" "test/frame_test.rb" "test/help_test.rb" "test/info_test.rb" "test/irb_test.rb" "test/jump_test.rb" "test/kill_test.rb" "test/list_test.rb" "test/method_test.rb" "test/post_mortem_test.rb" "test/quit_test.rb" "test/reload_test.rb" "test/restart_test.rb" "test/save_test.rb" "test/set_test.rb" "test/show_test.rb" "test/source_test.rb" "test/stepping_test.rb" "test/thread_test.rb" "test/tmate_test.rb" "test/trace_test.rb" "test/variables_test.rb" 
/Users/me/code/gems/debugger/lib/ruby_debug.bundle: warning: already initialized constant Debugger::VERSION
/Users/me/code/gems/debugger/lib/debugger/version.rb:4: warning: previous definition of VERSION was here
Run options: --seed 21745

# Running tests:

................................................................S.....dyld: lazy symbol binding failed: Symbol not found: _rb_vm_get_sourceline
  Referenced from: /Users/me/code/gems/debugger/lib/ruby_debug.bundle
  Expected in: flat namespace

dyld: Symbol not found: _rb_vm_get_sourceline
  Referenced from: /Users/me/code/gems/debugger/lib/ruby_debug.bundle
  Expected in: flat namespace

rake aborted!
Command failed with status (): [/Users/me/Developer/.rbenv/versions/2.0.0-...]
/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib/rake/file_utils.rb:53:in `block in create_shell_runner'
/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib/rake/file_utils.rb:45:in `call'
/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib/rake/file_utils.rb:45:in `sh'
/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib/rake/file_utils_ext.rb:39:in `sh'
/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib/rake/file_utils.rb:82:in `ruby'
/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib/rake/file_utils_ext.rb:39:in `ruby'
/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib/rake/testtask.rb:99:in `block (2 levels) in define'
/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib/rake/file_utils_ext.rb:60:in `verbose'
/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib/rake/testtask.rb:98:in `block in define'
/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib/rake/task.rb:205:in `call'
/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib/rake/task.rb:205:in `block in execute'
/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib/rake/task.rb:200:in `each'
/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib/rake/task.rb:200:in `execute'
/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib/rake/task.rb:158:in `block in invoke_with_call_chain'
/Users/me/Developer/.rbenv/versions/2.0.0-p0/lib/ruby/2.0.0/monitor.rb:211:in `mon_synchronize'
/Users/me/code/gems/debugger/bundle/ruby/2.0.0/gems/rake-0.9.2.2/lib/rake/task.rb:151:in `invoke_with_call_chain'

Also, a bug ticket on debuggers and ruby 2.0, https://bugs.ruby-lang.org/issues/7214, from #44

An example of failing to install in #66

You might want to look at https://github.com/denofevil/debase. It's pretty minimal implementation of ruby-debug-base for 2.0 that ruby-debug-ide (used by RubyMine) gem is using to debug 2.0.0. Only methods used by ruby-debug-ide are currently implemented, but it's open for pull requests.

This might be helpful: http://www.ruby-forum.com/topic/4407089

tl;dr: the new TracePoint functionality should be used: http://www.ruby-doc.org/core-2.0/TracePoint.html

I wonder if this would make it possible to write a debugger without having to compile anything. I'll investigate.

@bcardarella it it possible to write a debugger without having to compile anything. The problem is that this debugger will be slow as hell. I've implemented debase in pure ruby for the beginning, then I ran test suite from depot project measuring execution time. Here are results from my experiments:

none ruby-debug-base pure-ruby debase
1 3.67 5.857 47.521
2 3.664 5.923 47.88
3 3.713 6.014 48.071
4 3.697 5.868
5 3.738 5.963
6 3.653 5.906
7 3.78 5.896
8 3.753 5.918
9 3.746 5.905
10 3.767 5.898

Times are in seconds, none represents normal run of the tests without any debugger at all.
There were no breakpoints, no catchpoints, etc. Debuggers were just capturing context info (such as file, line, binding).
Execution overhead of pure-ruby implementation is simply not acceptable

@denofevil, isn't the reason ruby-debug was written in C primarily to access the rb_event_hook API that was only exposed in C? The new TracePoint API is just a Ruby wrapper for rb_event_hook (as far as i can tell) and should be more or less as fast as a pure C calls -- the overhead to previous pure ruby implementations was the constant and unnecessary binding creation in set_trace_func

@banister, part of ruby-debug is mostly true, but remember that this event hook is executed on every ruby event. This means that it's executed multiple times per one line. I've tried running pure ruby implementation with JRuby and got quite good results (very close to ruby-debug-base-java), but for MRI it was still slow. I've done benchmarking on 2.0.0-preview2, may be performance is better with final. BTW rb_tracearg_binding is creating new binding. We can try reverting to ruby-debug/debase@1b3f8a2 and replacing set_trace_func with TracePoint to check if it's fast enough

+1

+1

For the love of god, please stop with the endless +1 s it's the most retarded meme ever to infect github!

banister sorry - it's nothing more than a bump and a subscription to the issues - I found that github's thread watch function is not the most reliable thing in the world - doesn't always shoot an email to me unless I'm subscribed to an issue, didn't mean to irritate anyone.

I am change something to compatible ruby 2.0.0-p0. https://github.com/windwiny/debugger

^ What he means is that he may have fixed it so that debugger now works for Ruby 2.0.0-p0.

I can confirm that windwiny's patch seems to make it work on Ruby 2.0.0

Awesome, good job windwiny.Could we get this PR'd and pushed up to rubygems?

@windwiny I think you should create a real Pull Request

Can I also suggest a major version bump of the gem so it is clear this is
for 2.0 only

On Friday, March 1, 2013, Edwardzyc wrote:

Awesome, good job windwiny.Could we get this PR'd and pushed up to
rubygems?


Reply to this email directly or view it on GitHubhttps://github.com//issues/47#issuecomment-14295845
.


Brian Cardarella
Principal at DockYard
Visit us: http://dockyard.com
Call us: (855) DOCK-YRD
Follow me on Twitter: http://twitter.com/bcardarella
Follow us on Twitter: http://twitter.com/DockYard

@bcardarella afaict he's using #ifdef so it should work fine for 1.9.3 and 2.0

same as Issue #67 problem

+1 and thanks for all of your hard work in general. If writing a poem would help move things along, lemme know and I'll bust out a haiku.

Would love a poem :)

Though I'm not helping...

On Tue, Mar 5, 2013 at 1:06 PM, Jonathan E. Magen
notifications@github.comwrote:

+1 and thanks for all of your hard work in general. If writing a poem
would help move things along, lemme know and I'll bust out a haiku.


Reply to this email directly or view it on GitHubhttps://github.com//issues/47#issuecomment-14465167
.

I've released 1.4.0 which merges #68 to partially support 2.0.0. I will not consider 2.0.0 support official until tests can run. I've updated this card's description

How to install this version?

rubygems.org took some time to update but now gem install debugger works as expected

+1
I just tried debugger 1.4.0 along with ruby 2.0.0p0 and Rails 3.2.12. Installation is fine, no errors with the 1.4.0 version. When I'm hooking into a controller action, the debugger is started. I can step, next, continue etc. When I start irb I can act as usual. But when quiting irb with quit or exit I still get the

(rdb:1) irb
2.0.0-p0 :001 > quit
dyld: lazy symbol binding failed: Symbol not found: _rb_vm_get_sourceline
  Referenced from: /usr/local/rvm/gems/ruby-2.0.0-p0@apono/bundler/gems/debugger-e98dc5762a48/lib/ruby_debug.bundle
  Expected in: flat namespace

dyld: Symbol not found: _rb_vm_get_sourceline
  Referenced from: /usr/local/rvm/gems/ruby-2.0.0-p0@apono/bundler/gems/debugger-e98dc5762a48/lib/ruby_debug.bundle
  Expected in: flat namespace

Trace/BPT trap: 5

error, and Rails crashes and quits. I don't know why, maybe it's a Rails related issue. Any ideas?

Nono, it's a debugger issue. That's why @cldwalker talked about "partial support" when he released this version.

So I've been working for the last days on Ruby 2.0 support for debugger. Today I debugged a personal project for a couple hours using my changes and found myself really happy because everything worked as I expected (obviously I focused on getting the commands I use the most to work). This is the current state of the test suite

    356 tests, 389 assertions, 38 failures, 0 errors, 33 skips

The 33 skips are mostly skipped post_mortem mode and threading tests. Those parts of the gem I dropped them.

Now the issue for me is how to share my work. This is what I did: my first attemp was to fork debugger and try to modify it, but I didn't know where to begin. Then I tried to use debase as a starting point (as it already uses the new API) and that worked better. So I ended up (not the best choice I think) having a local git repo which is kind of a fork of debase on the C extension part (ext directory) and a fork of debugger on the "gem" part (lib/ and test/ dirs). And it's quite different from both projects: I deleted a lot of old stuff, drop post_mortem and thread functionality and changed minor things. I would like to make a proper pull request for debugger but I would also like to keep the gem as it is for personal use and share it as well. That, plus my reduced knowledge and unexperience using github make me quite unsure on how to proceed. Suggestions?

Please excuse me for the overlong comment...

@deivid-rodriguez Thanks for your interest but I'll be using #69 to make debugger more 2.0 compatible. Specifically with this commit ko1@eb3f718 . I hope you'll understand since Koichi, YARV's creator, knows ruby quite well :)

It's alright! Of course I understand :)

I'll just release it as a new gem then, someone might find it useful while ruby 2.0 support arrives to debugger!

EDIT: Ouch! I thought this was a WIP but it's already done! Your reference mislead me because it's actually in a later commit where he adds the 2.0 support... Anyways, problem solved, thanks Koichi!! :)

I'm having issues with "next" instead acting like "step", which makes the debugger pretty useless. debugger v 1.5.0

I can confirm I've seen this too.

nfm commented

Yes, "next" always does a "step" for me in 2.0.0.

This is the gem I mention in my previous message: byebug. Hope you find it useful until 2.0 support gets merged into debugger. Salute.

For debugger 2.0 I'm bringing in ruby 2 support from @ko1's fork. @ko1 has done most of the gritty work for upgrading to 2.0 and has asked to remove depending on debugger-ruby_core_source. This will introduce a breaking change to 1.9 users as they will need to explicitly add debugger-ruby_core_source as a dependency. After that, everything else should work fine for 1.9 users. My question to you all: do you think it's better to preemptively tell users of this change in a post_install_message e.g. 1.5.1 or to just announce it in a post_install_message for 2.0.0?

You should have the ability to do a conditional dependency for debugger-ruby_core_source so it just works as expected for both

See http://en.m.wikibooks.org/wiki/Ruby_Programming/RubyGems#section_3

Sent from Mailbox for iPhone

On Tue, Apr 2, 2013 at 8:39 AM, Gabriel Horner notifications@github.com
wrote:

For debugger 2.0 I'm bringing in ruby 2 support from @ko1's fork. @ko1 has done most of the gritty work for upgrading to 2.0 and has asked to remove depending on debugger-ruby_core_source. This will introduce a breaking change to 1.9 users as they will need to explicitly add debugger-ruby_core_source as a dependency. After that, everything else should work fine for 1.9 users. My question to you all: do you think it's better to preemptively tell users of this change in a post_install_message e.g. 1.5.1 or to just announce it in a post_install_message for 2.0.0?

Reply to this email directly or view it on GitHub:
#47 (comment)

I fixed the _rb_vm_get_sourceline problem by reinstating the following line from 1.9.3:

In vm_backtrace.c:
RUBY_FUNC_EXPORTED int rb_vm_get_sourceline(const rb_control_frame_t *cfp);

Komodo is now debugging a ruby 2.0 "hello world" program. Time to try some more complex stuff.

In my optimism I've submitted a patch at https://bugs.ruby-lang.org/issues/8243

I now hit a seg fault while evaluating @state.context[i].frame_line(pos) ... just when I thought my work was done here.

Here's what's going on in context_frame_line when I step over a raise statement (expecting to land at an exception handler) at this code:

if ((cfp->iseq != NULL) && (pc >= cfp->iseq->iseq_encoded) && (pc < cfp->iseq->iseq_encoded +   
    cfp->iseq->iseq_size)) {

Normal:

pc: 0x7f7332269420, cfp->iseq->iseq_encoded:0x7f73322693c0,
cfp->iseq->iseq_size:19 (add size + encoded:0x7f7332269458)

After stepping over the raise stmt:

pc: 0x7f7332269980, cfp->iseq->iseq_encoded:0x8750,
cfp->iseq->iseq_size:839635600 (add size + encoded:0x3fb99905f1bd0)

Looks like the cfp->iseq structure contains garbage, or more likely cfp does.

Here's the code btw:

puts "exception test"
begin
raise "oh nooo"
rescue => msg
print "Caught an exception: #{msg}\n"
end

Set a breakpoint at line 3 and step after that.

The Komodo debugger has no problem distinguishing step from next, so it's more likely the client code than this library. I didn't test the new version of rdebug though.

I don't understand. What client library? 

On Wed, Apr 10, 2013 at 1:21 PM, ericpromislow notifications@github.com
wrote:

The Komodo debugger has no problem distinguishing step from next, so it's more likely the client code than this library. I didn't test the new version of rdebug though.

Reply to this email directly or view it on GitHub:
#47 (comment)

By "client code", I meant the code that loads this library. It could be bin/rdebug right here, or any other debugger that uses this code to get at ruby_debug.so

koichi's fork handles exception handlers correctly, but it returns an empty hash for context_frame_locals, and seg faults elsewhere (I haven't narrowed down where). The main difference is that koichi's code maintains a list of inspected frames, which seems to avoid the reason for the crash I see in exception handlers, where we loop through control frames that contain apparent garbage.

Could someone provide a test case or a simple program for the next/step issue you are having? I would like to try it against my fork because I'm not experiencing the issue and my tests are passing. Thanks.

I'm back to using cldwalker's ruby_debug.so, and given that I can do some things in Ruby in 2.0 that I couldn't do in 1.x, like Thread#backtrace_locations, I no longer need to call context_frame_line, and therefore no longer have that dependency on rb_vm_get_sourceline.

@deivid-rodriguez I am running Ruby 2.0.0-p0 via RVM on latest Mac OS X Lion, and tried to reproduce this bug via a simple Ruby script, but was unable to do so. So @ericpromislow might have a point about it being the client library. For me, next behaves like step when I invoke the debugger when working on Rails 2.3.13 applications.

I can reproduce it with a vanilla app:

$ ruby -v
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-darwin12.2.1]

2.0.0-p0 ~#$ rails new tmp_debugger
2.0.0-p0 ~#$ cd tmp_debugger/
2.0.0-p0 tmp_debugger#$ bundle install
2.0.0-p0 tmp_debugger#$ rails g controller welcome index
2.0.0-p0 tmp_debugger#$ edit app/controllers/welcome_controller.rb 

change file to:

require 'debugger'
class WelcomeController < ApplicationController
  def index
    debugger
    next_over_me
    next_over_me
  end

  def next_over_me
    [1,2,3].inject {|s,a|
      s+a
    }
  end
end

then

2.0.0-p0 tmp_debugger#$ edit Gemfile

uncomment:

gem 'debugger'

then

2.0.0-p0 tmp_debugger#$ bundle install
2.0.0-p0 tmp_debugger#$ # start server then hit http://localhost:3001/welcome/index
2.0.0-p0 tmp_debugger#$ rails s -p3001
=> Booting WEBrick

[0, 9] in /Users/steven/tmp_debugger/app/controllers/welcome_controller.rb
   1  require 'debugger'
   2  class WelcomeController < ApplicationController
   3    def index
   4      debugger
=> 5      next_over_me
   6      next_over_me
   7    end
   8  
   9    def next_over_me
(rdb:1) n
/Users/steven/tmp_debugger/app/controllers/welcome_controller.rb:10
[1,2,3].inject {|s,a|

[5, 14] in /Users/steven/tmp_debugger/app/controllers/welcome_controller.rb
   5      next_over_me
   6      next_over_me
   7    end
   8  
   9    def next_over_me
=> 10      [1,2,3].inject {|s,a|             # <------------ wtf?!
   11        s+a
   12      }
   13    end
   14  end
(rdb:1) n
/Users/steven/tmp_debugger/app/controllers/welcome_controller.rb:11
s+a

Let's cut out the rails stuff:

def foo
  debugger
  next_over_me
  next_over_me
end

def next_over_me
  puts "nexted"
end

foo

#/tmp rdebug debug_test.rb

/private/tmp/debug_test.rb:1
def foo

(rdb:1) c
/private/tmp/debug_test.rb:3
next_over_me

(rdb:1) list
[-2, 7] in /private/tmp/debug_test.rb
   1  def foo
   2    debugger
=> 3    next_over_me
   4    next_over_me
   5  end
   6  
   7  def next_over_me
(rdb:1) n
/private/tmp/debug_test.rb:8
puts "nexted"

(rdb:1) list
[3, 12] in /private/tmp/debug_test.rb
   3    next_over_me
   4    next_over_me
   5  end
   6  
   7  def next_over_me
=> 8    puts "nexted"
   9  end
   10  
   11  foo

Thanks! So I can confirm this works in byebug but it doesn't work in both debugger and debugger2. I will have a look at it once debugger2 gets merged into debugger.

byebug looks like a win for me. Swapping debugger out until this is fixed. On the downside, it looks like Pry depends on/uses debugger, because it remains affected.

@kwerle I would like to help with that issue but this is getting a bit off-topic, so you can open an issue at byebug and we can discuss it there if you wish. Salute.

Confirmed that next does not work with ruby 2. Using byebug, it's working like a charm. When the patch for debugger?

Confirmed as well for me: 'next' does not work with ruby 2, performs a 'step'. Using byebug, it's working like a charm. But wishing for the canonical debugger to return ?

+1

+1

Closing since I'm scoping debugger to just 1.9.2 and 1.9.3. For more see #125 (comment)