Resets PryDebug to its default state.
# File lib/pry_debug.rb, line 86 def clean_up @breakpoints = [] @breakpoint_count = -1 @file = nil Thread.list.each do |th| th[:__pry_debug_stepped_file] = nil th[:__pry_debug_stepping] = false th[:__pry_debug_exception_binding] = nil th[:__pry_debug_last_exception] = nil end @break_on_raise = false @debugging = false @will_load = true @mutex = Mutex.new end
@return [Binding, nil] Binding where the exception was raised, if still in
memory.
# File lib/pry_debug.rb, line 79 def context_of_exception(ex) if ex.equal? last_exception exception_binding end end
@return [Binding, nil] Binding where last_exception was raised
# File lib/pry_debug.rb, line 42 def exception_binding Thread.current[:__pry_debug_exception_binding] end
# File lib/pry_debug.rb, line 46 def exception_binding=(b) Thread.current[:__pry_debug_exception_binding] = b end
@return [Exception, nil] Last exception that PryDebug has heard of
# File lib/pry_debug.rb, line 51 def last_exception Thread.current[:__pry_debug_last_exception] end
# File lib/pry_debug.rb, line 55 def last_exception=(ex) Thread.current[:__pry_debug_last_exception] = ex end
@return [Array<LineBreakpoint>] Breakpoints on a line
# File lib/pry_debug.rb, line 68 def line_breakpoints breakpoints.select { |bp| bp.is_a? LineBreakpoint } end
@return [Array<MethodBreakpoint>] Breakpoints on a method
# File lib/pry_debug.rb, line 73 def method_breakpoints breakpoints.select { |bp| bp.is_a? MethodBreakpoint } end
@return [String, nil] If not nil, the file where PryDebug needs to stop
(implying that next was called)
# File lib/pry_debug.rb, line 24 def stepped_file Thread.current[:__pry_debug_stepped_file] end
# File lib/pry_debug.rb, line 28 def stepped_file=(val) Thread.current[:__pry_debug_stepped_file] = val end
# File lib/pry_debug.rb, line 267 def add_line_breakpoint(file, line) bp = LineBreakpoint.new(PryDebug.breakpoint_count += 1, file, line) PryDebug.breakpoints << bp bp end
# File lib/pry_debug.rb, line 273 def add_method_breakpoint(klass, method, class_method) bp = MethodBreakpoint.new(PryDebug.breakpoint_count += 1, klass, method, class_method) PryDebug.breakpoints << bp bp end
Starts the debguger.
@param [true, false] load_file When set to false, PryDebug won't load
a file, and simply enable the tracing and let the user setup breakpoints.
# File lib/pry_debug.rb, line 115 def start(load_file = true) PryDebug.will_load = load_file # Importing user-defined commands. # NB: what about commands defined in both sets? Currently, user-defined # commands override PryDebug's. What about doing it the other way around? Pry.load_rc if Pry.config.should_load_rc # user might change Pry.commands Pry.config.should_load_rc = false # avoid loading config twice ShortCommands.import Pry.commands loop do should_start = catch(:start_debugging!) do Pry.start(TOPLEVEL_BINDING, :commands => ShortCommands) end if should_start == :now! set_trace_func trace_proc PryDebug.debugging = true return unless load_file begin load PryDebug.file rescue SystemExit # let this go rescue Exception => ex set_trace_func nil puts "unrescued exception: #{ex.class}: #{ex.message}" if binding = PryDebug.context_of_exception(ex) msg = "returning back to where the exception was raised" start_pry binding, nil, msg else msg = "context of the exception is unknown, starting pry into\n" msg << "the exception." start_pry ex, nil, msg end end PryDebug.last_exception = PryDebug.exception_binding = nil PryDebug.debugging = false set_trace_func nil puts "execution terminated" else break # debugger wasn't started, leave now end end end
Starts Pry with access to ShortCommands @param [Binding, object] binding Context to go to @param [String, nil] file Current file. Used for the next command. @param [String, nil] header Line to print before starting the debugger
# File lib/pry_debug.rb, line 170 def start_pry(binding, file = nil, header = nil) PryDebug.synchronize do puts header if header ret = catch(:resume_debugging!) do Pry.start(binding, :commands => ShortCommands) end if ret == :next PryDebug.stepped_file = file end # In case trace_func was changed set_trace_func trace_proc end end
# File lib/pry_debug.rb, line 187 def synchronize(&block) PryDebug.mutex.synchronize(&block) end
# File lib/pry_debug.rb, line 197 def trace_func(event, file, line, method, binding, klass) # Ignore events in this file return if file && File.expand_path(file) == DefinitionFile case event when 'line' if PryDebug.stepped_file == file PryDebug.stepped_file = nil start_pry binding, file, "stepped at #{file}:#{line} in #{Thread.current}" elsif PryDebug.stepping PryDebug.stepping = false start_pry binding, file, "stepped at #{file}:#{line} in #{Thread.current}" elsif bp = PryDebug.line_breakpoints.find { |b| b.is_at?(file, line, binding) } start_pry binding, file, "reached #{bp} in #{Thread.current}" end when 'c-call', 'call' return unless Module === klass # Whether we are calling a class method or an instance method, klass # is the same thing, making it harder to guess if it's a class or an # instance method. # # In case of C method calls, self cannot be trusted. Both will be tried, # unless we can find out there is only an instance method of that name # using instance_methods. # # Otherwise, assume it's an instance method if self is_a? klass # # Notice that since self could be a BasicObject, it may not respond to # is_a? (even when not breaking on BasicObject#thing, this code may be # triggered). class_method, try_both = if event == "call" [!(klass === binding.eval("self")), false] else if (klass.instance_methods & klass.methods).include? method [false, true] elsif klass.instance_methods.include? method [false, false] elsif klass.methods.include? method [true, false] else # should never happen [false, true] end end bp = PryDebug.method_breakpoints.find do |b| if try_both b.is_at?(klass, method.to_s, true, binding) || b.is_at?(klass, method.to_s, false, binding) else b.is_at?(klass, method.to_s, class_method, binding) end end if bp start_pry binding, file, "reached #{bp} in #{Thread.current}" end when 'raise' return unless $! PryDebug.last_exception = $! PryDebug.exception_binding = binding if PryDebug.break_on_raise msg = "exception raised in #{Thread.current}: #{$!.class}: #{$!.message} " start_pry binding, file, msg end end end
Generated with the Darkfish Rdoc Generator 2.