Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

INCOMPATIBLE CHANGE: "finish" works like gdb - stop just before the

most recent method finishes. Will now accept a number which stops that
many frames completed. (Note that return line numbers will be funny,
the first line of the method until Ruby 1.8.7.)



git-svn-id: svn://rubyforge.org/var/svn/ruby-debug/trunk@756 453b2852-3d18-0410-866e-d09c099698e4
  • Loading branch information...
commit a3a0ddd59c78af82452ba74a17ee6b307b8daa55 1 parent 40bfc8c
rockyb authored
View
6 CHANGES
@@ -24,6 +24,8 @@
* split of line caching to an external gem. We now only allow setting
breakpoints on lines where it makes sense to do so.
+ * Incompatible enhancement: even return/end will now call event handler
+
- bin/rdebug
* "rdebug --post-mortem" now really catches uncaught exceptions and
@@ -68,6 +70,10 @@
* rdebug command history can be displayed with "show commands". Fix a bug
in history saving.
+ * INCOMPATIBLE CHANGE: "finish" works like gdb - stop just before the most
+ recent method finishes. Will now accept a number which stops that many
+ frames completed.
+
- Emacs interaction drastically reworked, expanded, and improved.
0.10.0
View
19 cli/ruby-debug/commands/finish.rb
@@ -4,17 +4,16 @@ class FinishCommand < Command # :nodoc:
self.need_context = true
def regexp
- /^\s*fin(?:ish)?$/
+ /^\s*fin(?:ish)? (?:\s+(.*))?$/x
end
def execute
- if @state.frame_pos == @state.context.stack_size - 1
- print "\"finish\" not meaningful in the outermost frame.\n"
- else
- @state.context.stop_frame = @state.frame_pos
- @state.frame_pos = 0
- @state.proceed
- end
+ max_frame = @state.context.stack_size
+ frame_pos = get_int(@match[1], "Finish", 0, max_frame-1, 0)
+ return nil unless frame_pos
+ @state.context.stop_frame = frame_pos
+ @state.frame_pos = 0
+ @state.proceed
end
class << self
@@ -24,7 +23,9 @@ def help_command
def help(cmd)
%{
- fin[ish]\treturn to outer frame
+ fin[ish] [frame-number]\tExecute until selected stack frame returns.
+If no frame number is given, we run until most-recent frame returns. This is the same as
+value 1. If a frame number is given we run until frames returns.
}
end
end
View
5 cli/ruby-debug/processor.rb
@@ -170,6 +170,11 @@ def at_line(context, file, line)
end
protect :at_line
+ def at_return(context, file, line)
+ context.stop_frame = -1
+ process_commands(context, file, line)
+ end
+
private
# The prompt shown before reading a command.
View
14 doc/ruby-debug.texi
@@ -2618,13 +2618,21 @@ argument @var{count} is a repeat count, as for @code{step}.
@node Finish
@subsubsection Finish (@samp{finish})
@table @code
-@kindex finish
-@item finish
-Continue running until just after the method or function returns.
+@kindex finish @ovar{frame-number}
+@item finish @ovar{frame-number}
+Execute until selected stack frame returns. If no frame number is
+given, we run until most-recent frame returns. This is the same as
+value 0. If a frame number is given we run until @var{frame} frames
+returns.
If you want instead to terminate the program and debugger entirely,
use @code{quit} (@pxref{Quitting the debugger, ,Quitting the debugger}).
+@emph{Note:\/} Releases before Ruby version 1.8.7 show the return line
+as the first line of the method. Starting with version 1.8.7, the last
+line executed will be shown as the return
+line. @url{http://rubyforge.org/tracker/?func=detail&atid=22040&aid=18749&group_id=426}
+
@end table
@node Continue
View
38 ext/ruby_debug.c
@@ -78,9 +78,10 @@ static VALUE cDebugThread;
static VALUE rb_mObjectSpace;
-static ID idAtLine;
static ID idAtBreakpoint;
static ID idAtCatchpoint;
+static ID idAtLine;
+static ID idAtReturn;
static ID idAtTracing;
static ID idList;
@@ -465,6 +466,26 @@ call_at_line(VALUE context, debug_context_t *debug_context, VALUE file, VALUE li
return rb_protect(call_at_line_unprotected, args, 0);
}
+static VALUE
+call_at_return_unprotected(VALUE args)
+{
+ VALUE context;
+ context = *RARRAY(args)->ptr;
+ return rb_funcall2(context, idAtReturn, RARRAY(args)->len - 1, RARRAY(args)->ptr + 1);
+}
+
+static VALUE
+call_at_return(VALUE context, debug_context_t *debug_context, VALUE file, VALUE line)
+{
+ VALUE args;
+
+ last_debugged_thnum = debug_context->thnum;
+ save_current_position(debug_context);
+
+ args = rb_ary_new3(3, context, file, line);
+ return rb_protect(call_at_return_unprotected, args, 0);
+}
+
static void
save_call_frame(rb_event_t event, VALUE self, char *file, int line, ID mid, debug_context_t *debug_context)
{
@@ -829,8 +850,15 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
{
if(debug_context->stack_size == debug_context->stop_frame)
{
- debug_context->stop_next = 1;
- debug_context->stop_frame = 0;
+ if(debug_context->stack_size == 0)
+ save_call_frame(event, self, file, line, mid, debug_context);
+ else
+ set_frame_source(event, debug_context, self, file, line, mid);
+ binding = self? create_binding(self) : Qnil;
+ save_top_binding(debug_context, binding);
+ call_at_return(context, debug_context, rb_str_new2(file),
+ INT2FIX(line));
+ debug_context->dest_frame = -1;
}
while(debug_context->stack_size > 0)
{
@@ -838,7 +866,6 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
if(debug_context->frames[debug_context->stack_size].orig_id == mid)
break;
}
- CTX_FL_SET(debug_context, CTX_FL_ENABLE_BKPT);
break;
}
case RUBY_EVENT_CLASS:
@@ -1512,7 +1539,7 @@ context_step_over(int argc, VALUE *argv, VALUE self)
* call-seq:
* context.stop_frame(frame)
*
- * Stops when a frame with number +frame+ is activated. Implements +up+ and +down+ commands.
+ * Stops when a frame with number +frame+ is activated. Implements +finish+ and +next+ commands.
*/
static VALUE
context_stop_frame(VALUE self, VALUE frame)
@@ -2252,6 +2279,7 @@ Init_ruby_debug()
idAtBreakpoint = rb_intern("at_breakpoint");
idAtCatchpoint = rb_intern("at_catchpoint");
idAtLine = rb_intern("at_line");
+ idAtReturn = rb_intern("at_return");
idAtTracing = rb_intern("at_tracing");
idList = rb_intern("list");
View
4 lib/ruby-debug-base.rb
@@ -50,6 +50,10 @@ def at_tracing(file, line)
def at_line(file, line)
handler.at_line(self, file, line)
end
+
+ def at_return(file, line)
+ handler.at_return(self, file, line)
+ end
end
@reload_source_on_change = false
View
1  rdbg.rb
@@ -1,4 +1,5 @@
#!/usr/bin/env ruby
+#!/usr/bin/env ruby
# $Id$
# Use this to run rdebug without installing it. We assume that the
Please sign in to comment.
Something went wrong with that request. Please try again.