From b31cd4d2c57f7daa2dfe6a4743f7240bd971b9de Mon Sep 17 00:00:00 2001 From: Jason Laster Date: Sun, 29 Jul 2012 20:25:48 -0400 Subject: [PATCH 1/4] add support for a frame_manager --- lib/pry-debugger/before_session_hook.rb | 26 +++++++++++++++++++++++++ lib/pry-debugger/cli.rb | 1 + lib/pry-debugger/pry_ext.rb | 9 +++++++++ 3 files changed, 36 insertions(+) create mode 100644 lib/pry-debugger/before_session_hook.rb diff --git a/lib/pry-debugger/before_session_hook.rb b/lib/pry-debugger/before_session_hook.rb new file mode 100644 index 000000000..d2f85bc6f --- /dev/null +++ b/lib/pry-debugger/before_session_hook.rb @@ -0,0 +1,26 @@ +module PryDebugger + class BeforeSessionHook + + def caller_bindings(target) + + bindings = binding.callers + + start_frames = bindings.each_with_index.select do |b, i| + (b.frame_type == :method && + b.eval("self.class") == Debugger::Context && + b.eval("__method__") == :at_line) + end + + start_frame_index = start_frames.first.last + bindings = bindings.drop(start_frame_index + 1) + + bindings + end + + def call(output, target, _pry_) + return if binding.callers.map(&:frame_description).include?("start") + bindings = caller_bindings(target) + PryStackExplorer.create_and_push_frame_manager bindings, _pry_, :initial_frame => 0 + end + end +end \ No newline at end of file diff --git a/lib/pry-debugger/cli.rb b/lib/pry-debugger/cli.rb index bb4a7c70d..c35b532da 100644 --- a/lib/pry-debugger/cli.rb +++ b/lib/pry-debugger/cli.rb @@ -11,5 +11,6 @@ # require 'pry-debugger/base' +require 'pry-debugger/before_session_hook.rb' require 'pry-debugger/pry_ext' require 'pry-debugger/commands' diff --git a/lib/pry-debugger/pry_ext.rb b/lib/pry-debugger/pry_ext.rb index 4ff9bd3f7..ac7d22a41 100644 --- a/lib/pry-debugger/pry_ext.rb +++ b/lib/pry-debugger/pry_ext.rb @@ -20,3 +20,12 @@ def start(target = TOPLEVEL_BINDING, options = {}) end end end + +if Pry.plugins.include?("stack_explorer") + Pry.config.hooks.add_hook(:before_session, :debugger_frame_manager, PryDebugger::BeforeSessionHook.new) + + # move default to the back of before_session + default = Pry.config.hooks.get_hook(:before_session, :default) + Pry.config.hooks.delete_hook(:before_session, :default) + Pry.config.hooks.add_hook(:before_session, :default, default) +end From 28695e390ae0d911573ec45ee6ce788de1ca3a2e Mon Sep 17 00:00:00 2001 From: Jason Laster Date: Sun, 29 Jul 2012 21:02:21 -0400 Subject: [PATCH 2/4] add require for version --- lib/pry-debugger/cli.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pry-debugger/cli.rb b/lib/pry-debugger/cli.rb index c35b532da..6d0487ca8 100644 --- a/lib/pry-debugger/cli.rb +++ b/lib/pry-debugger/cli.rb @@ -14,3 +14,4 @@ require 'pry-debugger/before_session_hook.rb' require 'pry-debugger/pry_ext' require 'pry-debugger/commands' +require 'pry-debugger/version' \ No newline at end of file From b3355d8afe89b798c574403fcf1b91faad81d9eb Mon Sep 17 00:00:00 2001 From: Jason Laster Date: Tue, 31 Jul 2012 21:07:19 -0400 Subject: [PATCH 3/4] update finish to respect current frame --- lib/pry-debugger/commands.rb | 5 ++++- lib/pry-debugger/processor.rb | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/pry-debugger/commands.rb b/lib/pry-debugger/commands.rb index 379da0050..15359bd01 100644 --- a/lib/pry-debugger/commands.rb +++ b/lib/pry-debugger/commands.rb @@ -205,11 +205,14 @@ def process helpers do def breakout_navigation(action, times = nil) + + binding_stack_index = PryStackExplorer.frame_manager(_pry_).binding_index _pry_.binding_stack.clear # Clear the binding stack. throw :breakout_nav, { # Break out of the REPL loop and :action => action, # signal the tracer. :times => times, - :pry => _pry_ + :pry => _pry_, + :binding_stack_index => binding_stack_index } end diff --git a/lib/pry-debugger/processor.rb b/lib/pry-debugger/processor.rb index 7bca83ef1..aee4b8bc2 100644 --- a/lib/pry-debugger/processor.rb +++ b/lib/pry-debugger/processor.rb @@ -9,6 +9,7 @@ def initialize Debugger.handler = self @always_enabled = false @delayed = Hash.new(0) + @binding_stack_index = 0 end # Wrap a Pry REPL to catch navigational commands and act on them. @@ -21,6 +22,7 @@ def run(initial = true, &block) times = (command[:times] || 1).to_i # Command argument times = 1 if times <= 0 + @binding_stack_index = command[:binding_stack_index] if [:step, :next, :finish].include? command[:action] @pry = command[:pry] # Pry instance to resume after stepping @@ -135,7 +137,7 @@ def step_over(lines) # Execute until current frame returns. def finish - Debugger.current_context.stop_frame = 0 + Debugger.current_context.stop_frame = @binding_stack_index end # Cleanup when debugging is stopped and execution continues. From 11002258777caa6fc4c8fb5282060c2e09b0db60 Mon Sep 17 00:00:00 2001 From: Jason Laster Date: Tue, 31 Jul 2012 21:36:15 -0400 Subject: [PATCH 4/4] add finish option, banner, small tweaks --- lib/pry-debugger/commands.rb | 30 ++++++++++++++++++++++-------- lib/pry-debugger/processor.rb | 6 +++--- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/lib/pry-debugger/commands.rb b/lib/pry-debugger/commands.rb index 15359bd01..87f268724 100644 --- a/lib/pry-debugger/commands.rb +++ b/lib/pry-debugger/commands.rb @@ -19,7 +19,7 @@ module PryDebugger def process check_file_context - breakout_navigation :step, args.first + breakout_navigation :step, :times => args.first end end @@ -41,7 +41,7 @@ def process def process check_file_context - breakout_navigation :next, args.first + breakout_navigation :next, :times => args.first end end @@ -49,9 +49,25 @@ def process create_command 'finish' do description 'Execute until current stack frame returns.' + banner <<-BANNER + Usage: finish [frame-number] + + Return the current or selected stack frame. + + Examples: + + finish Return from the current frame + finish 2 Return from the 2nd stack frame + BANNER + + def process check_file_context - breakout_navigation :finish + + frame_manager = PryStackExplorer.frame_manager(_pry_) + binding_index = (args.first || frame_manager.binding_index).to_i + + breakout_navigation :finish, :binding_index => binding_index end end @@ -204,15 +220,13 @@ def process helpers do - def breakout_navigation(action, times = nil) - - binding_stack_index = PryStackExplorer.frame_manager(_pry_).binding_index + def breakout_navigation(action, opts={}) _pry_.binding_stack.clear # Clear the binding stack. throw :breakout_nav, { # Break out of the REPL loop and :action => action, # signal the tracer. - :times => times, + :times => opts[:times], :pry => _pry_, - :binding_stack_index => binding_stack_index + :binding_index => opts[:binding_index] } end diff --git a/lib/pry-debugger/processor.rb b/lib/pry-debugger/processor.rb index aee4b8bc2..ff38560a6 100644 --- a/lib/pry-debugger/processor.rb +++ b/lib/pry-debugger/processor.rb @@ -9,7 +9,7 @@ def initialize Debugger.handler = self @always_enabled = false @delayed = Hash.new(0) - @binding_stack_index = 0 + @binding_index = 0 end # Wrap a Pry REPL to catch navigational commands and act on them. @@ -22,7 +22,7 @@ def run(initial = true, &block) times = (command[:times] || 1).to_i # Command argument times = 1 if times <= 0 - @binding_stack_index = command[:binding_stack_index] + @binding_index = command[:binding_index] if [:step, :next, :finish].include? command[:action] @pry = command[:pry] # Pry instance to resume after stepping @@ -137,7 +137,7 @@ def step_over(lines) # Execute until current frame returns. def finish - Debugger.current_context.stop_frame = @binding_stack_index + Debugger.current_context.stop_frame = @binding_index end # Cleanup when debugging is stopped and execution continues.