Is the debugger broken?

Hi rubyists,

Is it just me or does the debugger not work the way it is supposed to?

The command n[ext] is supposed to step over methods, but I find that it digs
into “require” methods. There are also problems with loops.

I searched the archives, but did not find much relevant discussion. How do you
guys use the debugger?

···


Gavin Sinclair Software Engineer
Sydney, Australia Soyabean Software Pty Ltd

Hi,

From: Gavin Sinclair [mailto:gsinclair@soyabean.com.au]
Sent: Wednesday, October 16, 2002 5:55 PM

Is it just me or does the debugger not work the way it is supposed to?

The command n[ext] is supposed to step over methods, but I
find that it digs
into “require” methods.

It is expected behaviour because the current debugger does
not trace ‘require’ c-call and c-return. For workaround,
set bp at the next line of require and go.

There are also problems with loops.

Yes it has a limitation about tracing ruby’s block
(especially, one-line block). Would you please post an
example which causes loops problem?

Regards,
// NaHi

Hi rubyists,

Is it just me or does the debugger not work the way it is supposed to?

The command n[ext] is supposed to step over methods, but I find that it digs
into “require” methods. There are also problems with loops.

I searched the archives, but did not find much relevant discussion. How do
you
guys use the debugger?

I just found another problem. In my TestUnit test case, I have the following
code:

def test_get_all_backend_ids
clear_test_table()
# …
assert(expected_result == actual_result,
“Failed to grab correct backend IDs: #{actual_result.join(”\n")}")
end

The line that says “clear_test_table()” is line 139. I want to set a
breakpoint there. The transcript of my debugging session is below. Long story
short: the debugger failed to stop at the prescribed breakpoint. It
definitely passed through it, because that very method was judged by TestUnit
to have failed.

It’s pointless me posting all my source code for inspection, because it’s long
and dependent on database operations. I want to know if other people have had
similar experiences of breakpoints not being honoured. If it is useful, I can
later try to produce a small program that reproduces the error.

Gavin

···

From: “Gavin Sinclair” gsinclair@soyabean.com.au

===========================

ruby -rdebug tc_ad020-scraper.rb
Debug.rb
Emacs support available.

tc_ad020-scraper.rb:3:require “test/unit”
(rdb:1) break 139
Set breakpoint 1 at tc_ad020-scraper.rb:139
(rdb:1) break
Breakpoints:
1 tc_ad020-scraper.rb:139

(rdb:1) cont
Loaded suite tc_ad020-scraper
Started…

Failure occurred in test_get_all_backend_ids(TC_AD020Scraper)
[tc_ad020-scraper.rb:143]: Failed to grab correct backend IDs:
<1001448506: 2002-10-07 23:25:37:939>
<1001448502: 2002-10-07 23:25:02:952>
<1001448501: 2002-10-07 23:24:59:645>
<1001448493: 2002-10-07 23:24:43:816>
[…]
[…]
Finished in 10.952977 seconds.
9 runs, 19 assertions, 2 failures, 0 errors

Hi,

From: Gavin Sinclair [mailto:gsinclair@soyabean.com.au]
Sent: Wednesday, October 16, 2002 5:55 PM

Is it just me or does the debugger not work the way it is supposed to?

The command n[ext] is supposed to step over methods, but I
find that it digs
into “require” methods.

It is expected behaviour because the current debugger does
not trace ‘require’ c-call and c-return. For workaround,
set bp at the next line of require and go.

There are also problems with loops.

Yes it has a limitation about tracing ruby’s block
(especially, one-line block). Would you please post an
example which causes loops problem?

I’ll look out for it. It may take me a few days, but I will get back to you.

Regards,
// NaHi

SiGa :slight_smile:

···

From: “NAKAMURA, Hiroshi” nahi@keynauts.com

NAKAMURA, Hiroshi wrote:

There are also problems with loops.

Yes it has a limitation about tracing ruby’s block
(especially, one-line block). Would you please post an
example which causes loops problem?

Actually, any one line loop makes the debugger enter in a endless
loop. try a simple thing like:

1 while true
2 i=1
3 done

And go through it with [n]ext.

This is a problem I have long observed while working on the FreeRIDE
debugger. If my memory is correct the problem is that the tracer
always stays on line 2 and there is some test in the trace_func
function of the debugger forcing another step when we stay on the same
line which of course causes an endless loop.

One way this can be fixed is that the tracer should really go through
the while statement for each loop. However it will not solve the
problem for code like:

i=0
while ((i=i.next) < 1000)
done

In this case the debugger go trough the 1000 iterations without stopping

Hope this helps. I think that if we could find a way to fix the one
line loop that would be great because one-line loop are quite frequent.

Laurent

Hi,

There are also problems with loops.

Yes it has a limitation about tracing ruby’s block
(especially, one-line block). Would you please post an
example which causes loops problem?

Hmmm… I was going from memory when writing “there are problems with loops”.
My actual problems are with iterators. For example:

1 require ‘find’
2
3 Find.find(“.”) do |path|
4 puts path
5 end

Now, if your debugger is pointed to line 3, and you want to move to line 4,
what do you do?

  1. You can’t go “next”; that skips the “find” method (including the inline
    proc) and takes you beyond line 5.
  2. You can’t go “step”; that takes you into the “find” method.
  3. You can’t go “next 4”; that bypasses lline 4 for the same reason as (1)
  4. You can’t go “step 4”; that acts like (2)
  5. You CAN go “break 4”, but …

… that is no way to run a debugger. Using iterators is very common in Ruby
programming. While defining breakpoints to step through iterator code in a
logical fashion may (and it’s a stretch) be acceptable once or twice, it is too
painful when you have nested iterators.

i.e. we have a C-like debugger for a non-C-like language.

// NaHi

Gavin

···

From: “NAKAMURA, Hiroshi” nahi@keynauts.com

I had the same experience especially with the debugger and TestUnit.
But I didn’t have the time to investigate why the debugger skipped my
breakpoints. So I continued using my beloved debug-by-logging methology.

-billy.

···

On Mon, Oct 21, 2002 at 02:44:13PM +0900, Gavin Sinclair wrote:

The line that says “clear_test_table()” is line 139. I want to set a
breakpoint there. The transcript of my debugging session is below. Long story
short: the debugger failed to stop at the prescribed breakpoint. It
definitely passed through it, because that very method was judged by TestUnit
to have failed.

It’s pointless me posting all my source code for inspection, because it’s long
and dependent on database operations. I want to know if other people have had
similar experiences of breakpoints not being honoured. If it is useful, I can
later try to produce a small program that reproduces the error.


Meisterbohne Söflinger Straße 100 Tel: +49-731-399 499-0
eLösungen 89077 Ulm Fax: +49-731-399 499-9

Hi,

From: Gavin Sinclair [mailto:gsinclair@soyabean.com.au]
Sent: Wednesday, October 16, 2002 11:09 PM

It is expected behaviour because the current debugger does
not trace ‘require’ c-call and c-return. For workaround,
set bp at the next line of require and go.

Here is another workaround for debug.rb in 1.6 althourgh
I don’t want to commit such an ad-hoc code in the source.

— /usr/local/lib/ruby/1.6/debug.rb 2002-04-01 22:16:16.000000000
+0900
+++ debug.rb 2002-10-17 16:58:34.000000000 +0900
@@ -716,5 +716,18 @@ EOHELP

   when 'c-call'
  •   frame_set_pos(file, line)
    
  •   if id == :require and klass == Kernel
    
  •     @frames.unshift [binding, file, line, id]
    
  •   else
    
  •     frame_set_pos(file, line)
    
  •   end
    
···
  •  when 'c-return'
    
  •   if id == :require and klass == Kernel
    
  •     if @frames.size == @finish_pos
    
  •       @stop_next = 1
    
  •       @finish_pos = 0
    
  •     end
    
  •     @frames.shift
    
  •   end
    
     when 'class'
    

// NaHi

SiGa :slight_smile:

Found a crowd. :slight_smile:

Regards,
// NAKAMURA, Hiroshi, aka NaHi or nakahiro

… that is no way to run a debugger. Using iterators is very common in Ruby
programming. While defining breakpoints to step through iterator code in a
logical fashion may (and it’s a stretch) be acceptable once or twice, it is
too
painful when you have nested iterators.

i.e. we have a C-like debugger for a non-C-like language.

I’d like to follow up my own post with a constructive suggestion. How about
adding these commands to the debugger:

1 nl: goes to next physical line of file, no matter what

2 step method: steps into given method

The first one would be useful for stepping through code containing iterators
that, according to [ruby-talk:53622], is not adequately debuggable with the
current command set. This could be implemented by setting a breakpoint for the
next line, continuing, and discarding the breakpoint.

The second one is an unrelated suggestion that would ease the debugging of
lines containing several methods. For example:

arr.map { |x| f(x) }.reject { |x| predicate?(x) }.sort { |a,b| order(a) <=>

order(b) }

There are three user-defined methods in that one line: f, predicate?, and
order. If you wanted to step into :order, then you would have to step through
:f and :predicate? first, or set a breakpoint at the beginning of the
definition of :order. It would be nicer to be able to say “step order” - “s o”
for short - to achieve this instead. This would be easy to implement as well:
the “step” command clearly must know what it’s stepping into.

Gavin

···

From: “Gavin Sinclair” gsinclair@soyabean.com.au [snipped]

I’ve just run into this problem this morning. The pattern I seem to be
seeing is this:

- breakpoints set in main file work
- breakpoint set by specifiying 

	b file.rb:<lineno>

  seem to work

- breakpoints set in different file upon stepping into that file like so

	b <lineno>

  do not seem to work

- breakpoint set by specifying Class::method

	b Foo::bar

  do not seem to work

Jim

···

On Mon, 21 Oct 2002 18:15:15 +0900 Philipp Meier meier@meisterbohne.de wrote:

On Mon, Oct 21, 2002 at 02:44:13PM +0900, Gavin Sinclair wrote:

The line that says “clear_test_table()” is line 139. I want to set a
breakpoint there. The transcript of my debugging session is below. Long story
short: the debugger failed to stop at the prescribed breakpoint. It
definitely passed through it, because that very method was judged by TestUnit
to have failed.

It’s pointless me posting all my source code for inspection, because it’s long
and dependent on database operations. I want to know if other people have had
similar experiences of breakpoints not being honoured. If it is useful, I can
later try to produce a small program that reproduces the error.

I had the same experience especially with the debugger and TestUnit.
But I didn’t have the time to investigate why the debugger skipped my
breakpoints. So I continued using my beloved debug-by-logging methology.