class Byebug::InfoCommand
Implements byebug “info” command.
def execute
def execute return print_subcmds(Subcommands) unless @match[1] args = @match[1].split(/[ \t]+/) param = args.shift subcmd = find(Subcommands, param) if subcmd send("info_#{subcmd.name}", *args) else errmsg "Unknown info command #{param}\n" end end
def help(args)
def help(args) # specific subcommand help if args[1] subcmd = find(Subcommands, args[1]) return "Invalid \"info\" subcommand \"#{args[1]}\"." unless subcmd str = subcmd.short_help + '.' if 'file' == subcmd.name and args[2] subsubcmd = find(InfoFileSubcommands, args[2]) return str += "\nInvalid \"file\" attribute \"#{args[2]}\"." \ unless subsubcmd str += "\n" + subsubcmd.short_help + '.' else str += "\n" + subcmd.long_help if subcmd.long_help end return str end # general help s = %{ Generic command for showing things about the program being debugged. -- List of info subcommands: -- } for subcmd in Subcommands do s += "info #{subcmd.name} -- #{subcmd.short_help}\n" end return s end
def help_command
def help_command 'info' end
def info_args(*args)
def info_args(*args) unless @state.context print "No frame selected.\n" return end locals = @state.context.frame_locals(@state.frame_pos) args = @state.context.frame_args(@state.frame_pos) args.each do |name| s = "#{name} = #{locals[name].inspect}" pad_with_dots(s) print "#{s}\n" end end
def info_breakpoints(*args)
def info_breakpoints(*args) unless @state.context print "info breakpoints not available here.\n" return end unless Byebug.breakpoints.empty? brkpts = Byebug.breakpoints.sort_by{|b| b.id} unless args.empty? indices = args.map{|a| a.to_i} brkpts = brkpts.select{|b| indices.member?(b.id)} if brkpts.empty? errmsg "No breakpoints found among list given.\n" return end end print "Num Enb What\n" brkpts.each do |b| if b.expr.nil? print "%3d %s at %s:%s\n", b.id, (b.enabled? ? 'y' : 'n'), b.source, b.pos else print "%3d %s at %s:%s if %s\n", b.id, (b.enabled? ? 'y' : 'n'), b.source, b.pos, b.expr end hits = b.hit_count if hits > 0 s = (hits > 1) ? 's' : '' print "\tbreakpoint already hit #{hits} time#{s}\n" end end else print "No breakpoints.\n" end end
def info_display(*args)
def info_display(*args) unless @state.context print "info display not available here.\n" return end if @state.display.find{|d| d[0]} print "Auto-display expressions now in effect:\n" print "Num Enb Expression\n" n = 1 for d in @state.display print "%3d: %s %s\n", n, (d[0] ? 'y' : 'n'), d[1] if d[0] != nil n += 1 end else print "There are no auto-display expressions now.\n" end end
def info_file(*args)
def info_file(*args) return info_files unless args[0] file = args[0] param = args[1] ? args[1] : 'basic' subcmd = find(InfoFileSubcommands, param) return errmsg "Invalid parameter #{param}\n" unless subcmd unless LineCache::cached?(file) unless LineCache::cached_script?(file) return print "File #{file} is not cached\n" end LineCache::cache(file, Command.settings[:reload_source_on_change]) end print "File #{file}" path = LineCache.path(file) if %w(all basic path).member?(subcmd.name) and path != file print " - #{path}" end print "\n" if %w(all basic lines).member?(subcmd.name) lines = LineCache.size(file) print "\t %d lines\n", lines if lines end if %w(all breakpoints).member?(subcmd.name) breakpoints = LineCache.trace_line_numbers(file) if breakpoints print "\tbreakpoint line numbers:\n" print columnize(breakpoints.to_a.sort, self.class.settings[:width]) end end if %w(all mtime).member?(subcmd.name) stat = LineCache.stat(file) print "\t%s\n", stat.mtime if stat end if %w(all sha1).member?(subcmd.name) print "\t%s\n", LineCache.sha1(file) end end
def info_files(*args)
def info_files(*args) files = LineCache::cached_files files += SCRIPT_LINES__.keys unless 'stat' == args[0] files.uniq.sort.each do |file| stat = LineCache::stat(file) path = LineCache::path(file) print "File %s", file if path and path != file print " - %s\n", path else print "\n" end print "\t%s\n", stat.mtime if stat end end
def info_global_variables(*args)
def info_global_variables(*args) unless @state.context errmsg "info global_variables not available here.\n" return end var_global end
def info_instance_variables(*args)
def info_instance_variables(*args) unless @state.context print "info instance_variables not available here.\n" return end obj = debug_eval('self') var_list(obj.instance_variables) end
def info_line(*args)
def info_line(*args) unless @state.context errmsg "info line not available here.\n" return end print "Line %d of \"%s\"\n", @state.line, @state.file end
def info_locals(*args)
def info_locals(*args) unless @state.context errmsg "info line not available here.\n" return end locals = @state.context.frame_locals(@state.frame_pos) locals.keys.sort.each do |name| ### FIXME: make a common routine begin s = "#{name} = #{locals[name].inspect}" rescue begin s = "#{name} = #{locals[name].to_s}" rescue s = "*Error in evaluation*" end end pad_with_dots(s) print "#{s}\n" end end
def info_program(*args)
def info_program(*args) if not @state.context print "The program being debugged is not being run.\n" return elsif @state.context.dead? print "The program crashed.\n" if Byebug.last_exception print("Exception: #{Byebug.last_exception.inspect}\n") end return end print "Program stopped. " case @state.context.stop_reason when :step print "It stopped after stepping, next'ing or initial start.\n" when :breakpoint print("It stopped at a breakpoint.\n") when :catchpoint print("It stopped at a catchpoint.\n") else print "unknown reason: %s\n" % @state.context.stop_reason.to_s end end
def info_stack(*args)
def info_stack(*args) if not @state.context errmsg "info stack not available here.\n" return end print_backtrace end
def info_variables(*args)
def info_variables(*args) if not @state.context errmsg "info variables not available here.\n" return end obj = debug_eval('self') locals = @state.context.frame_locals(@state.frame_pos) locals[:self] = @state.context.frame_self(@state.frame_pos) locals.keys.sort.each do |name| next if name =~ /^__dbg_/ # skip byebug pollution ### FIXME: make a common routine begin s = "#{name} = #{locals[name].inspect}" rescue begin s = "#{name} = #{locals[name].to_s}" rescue s = "#{name} = *Error in evaluation*" end end pad_with_dots(s) s.gsub!('%', '%%') # protect against printf format strings print "#{s}\n" end var_list(obj.instance_variables, obj.instance_eval{binding()}) var_class_self end
def regexp
def regexp /^\s* i(?:nfo)? (?:\s+(.*))?$/ix end