diff options
Diffstat (limited to 'lib/debug.rb')
-rw-r--r-- | lib/debug.rb | 233 |
1 files changed, 120 insertions, 113 deletions
diff --git a/lib/debug.rb b/lib/debug.rb index 4c3ad2f099..45ec05ff01 100644 --- a/lib/debug.rb +++ b/lib/debug.rb @@ -1,22 +1,12 @@ - class DEBUGGER__ - - def max(a,b) - if (a<b); b; else a; end - end - - def min(a,b) - if (a<=b); a; else b; end - end - trap("INT") { DEBUGGER__::CONTEXT.interrupt } - $DEBUG = TRUE + $DEBUG = true def initialize @break_points = [] @stop_next = 1 @frames = [nil] - @frame_pos = nil # nil means not '0' but `unknown'. @last_file = nil + @last = [nil, nil] @scripts = {} end @@ -41,16 +31,17 @@ class DEBUGGER__ end def debug_command(file, line, id, binding) + frame_pos = 0 binding_file = file binding_line = line - debug_line = {} + previus_line = nil if (ENV['EMACS'] == 't') STDOUT.printf "\032\032%s:%d:\n", binding_file, binding_line else STDOUT.printf "%s:%d:%s", binding_file, binding_line, line_at(binding_file, binding_line) end - @frames[-1] = binding + @frames[0] = binding STDOUT.print "(rdb:-) " STDOUT.flush while input = STDIN.gets @@ -60,10 +51,10 @@ class DEBUGGER__ else DEBUG_LAST_CMD[0] = input end - case input - when /^b(reak)?\s+(([^:\n]+:)?.+)/ - pos = $2 + case input + when /^b(?:reak)?\s+((?:[^:\n]+:)?.+)/ + pos = $1 if pos.index ":" file, pos = pos.split(":") end @@ -78,15 +69,15 @@ class DEBUGGER__ pname @break_points.push [file, pos] - when /^b(reak)?$/ + when /^b(?:reak)?$/, /^i(?:nfo) b(?:reak)?$/ n = 0 for f, p in @break_points STDOUT.printf "%d %s:%s\n", n, f, p n += 1 end - when /^del(ete)?(\s+(\d+))?$/ - pos = $3 + when /^del(?:ete)?(?:\s+(\d+))?$/ + pos = $1 unless pos STDOUT.print "clear all breakpoints? (y/n) " STDOUT.flush @@ -107,99 +98,111 @@ class DEBUGGER__ end end - when /^c(ont)?$/ + when /^c(?:ont)?$/ return - when /^s(tep)?\s*(\d+)?$/ - if $2 - lev = Integer($2) + when /^s(?:tep)?\s*(\d+)?$/ + if $1 + lev = Integer($1) else lev = 1 end @stop_next = lev return - when /^n(ext)?\s*(\d+)?$/ - if $2 - lev = Integer($2) + when /^n(?:ext)?\s*(\d+)?$/ + if $1 + lev = Integer($1) else lev = 1 end @stop_next = lev - @no_step = @frames.size + @no_step = @frames.size - frame_pos return - when /^i(?:nfo)?/, /^w(?:here)?/ - fs = @frames.size - tb = caller(0)[-fs..-1].reverse - unless @frame_pos; @frame_pos = fs - 1; end - - (fs-1).downto(0){ |i| - if (@frame_pos == i) - STDOUT.printf "--> frame %d:%s\n", i, tb[i] + when /^w(?:here)?$/, /^f(?:rame)?$/ + at = caller(0) + 0.upto( @frames.size - 1 ) do |n| + if ( frame_pos == n ) + STDOUT.printf "--> #%d %s\n", n, at[-(@frames.size - n)] else - STDOUT.printf " frame %d:%s\n", i, tb[i] + STDOUT.printf " #%d %s\n", n, at[-(@frames.size - n)] end - } - - when /^l(ist)?$/ - fs = @frames.size - tb = caller(0)[-fs..-1].reverse - unless @frame_pos; @frame_pos = fs - 1; end - - file, line, func = tb[@frame_pos].split(":") - line = line.to_i - b = line - 1 - e = line + 9 - line_at(file, line) - if lines = @scripts[file] and lines != TRUE - lines = [0] + lines # Simple offset adjust - b = max(0, b); e = min(lines.size-1, e) - for l in b..e - if (l == line) - STDOUT.printf "--> %5d %s", l, lines[l] - else - STDOUT.printf " %5d %s", l, lines[l] - end - end - else - STDOUT.printf "no sourcefile available for %s\n", file end - when /^d(?:own)?\s*(\d+)??$/ - if $1; lev = Integer($1); else lev = 1; end - unless @frame_pos; @frame_pos = 0; end - @frame_pos -= lev - if @frame_pos < 0 - STDOUT.print "at stack bottom\n" - @frame_pos = 0 - else - STDOUT.printf "at level %d\n", @frame_pos + when /^l(?:ist)?(?:\s+(.+))?$/ + if !$1 + b = previus_line ? previus_line + 10 : binding_line - 5 + e = b + 9 + elsif $1 == '-' + b = previus_line ? previus_line - 10 : binding_line - 5 + e = b + 9 + else + b, e = $1.split(/[-,]/) + if e + b = Integer(b) + e = Integer(e) + else + b = Integer(b) - 5 + e = b + 9 + end + end + previus_line = b + STDOUT.printf "[%d, %d] in %s\n", b, e, binding_file + line_at(binding_file, binding_line) + if lines = @scripts[binding_file] and lines != true + n = 0 + b.upto(e) do |n| + if n > 0 && lines[n-1] + if ( n == binding_line ) + STDOUT.printf "=> %d %s\n", n, lines[n-1].chomp + else + STDOUT.printf " %d %s\n", n, lines[n-1].chomp + end + end + end + else + STDOUT.printf "no sourcefile available for %s\n", binding_file + end + + when /^up\s*(\d+)?$/ + previus_line = nil + if $1 + lev = Integer($1) + else + lev = 1 + end + frame_pos += lev + if frame_pos >= @frames.size + frame_pos = @frames.size - 1 + STDOUT.print "at toplevel\n" end - binding = @frames[@frame_pos] - - when /^u(?:p)?\s*(\d+)?$/ - if $1; lev = Integer($1); else lev = 1; end - unless @frame_pos; @frame_pos = @frames.size - 1; end - @frame_pos += lev - p @frame_pos - if @frame_pos >= @frames.size - STDOUT.print "at toplevel\n" - @frame_pos = nil - else - binding = @frames[@frame_pos] - frame_info = caller(4)[-(@frame_pos+1)] - STDOUT.print "at #{frame_info}\n" - frame_info.sub( /:in `.*'$/, '' ) =~ /^(.*):(\d+)$/ #` - binding_file, binding_line = $1, $2.to_i - binding = @frames[@frame_pos] + binding = @frames[frame_pos] + info, binding_file, binding_line = frame_info(frame_pos) + STDOUT.printf "#%d %s\n", frame_pos, info + + when /^down\s*(\d+)?$/ + previus_line = nil + if $1 + lev = Integer($1) + else + lev = 1 + end + frame_pos -= lev + if frame_pos < 0 + frame_pos = 0 + STDOUT.print "at stack bottom\n" end + binding = @frames[frame_pos] + info, binding_file, binding_line = frame_info(frame_pos) + STDOUT.printf "#%d %s\n", frame_pos, info - when /^f(inish)?/ - @finish_pos = @frames.size + when /^fi(?:nish)?$/ + @finish_pos = @frames.size - frame_pos + frame_pos = 0 return - when /^q(uit)?$/ + when /^q(?:uit)?$/ STDOUT.print "really quit? (y/n) " STDOUT.flush input = STDIN.gets.chop! @@ -217,22 +220,28 @@ class DEBUGGER__ end end + def frame_info(pos = 0) + info = caller(0)[-(@frames.size - pos)] + info.sub( /:in `.*'$/, '' ) =~ /^(.*):(\d+)$/ #` + [info, $1, $2.to_i] + end + def line_at(file, line) lines = @scripts[file] if lines - return "\n" if lines == TRUE + return "\n" if lines == true line = lines[line-1] return "\n" unless line return line end save = $DEBUG begin - $DEBUG = FALSE + $DEBUG = false f = open(file) lines = @scripts[file] = f.readlines rescue $DEBUG = save - @scripts[file] = TRUE + @scripts[file] = true return "\n" end line = lines[line-1] @@ -254,15 +263,14 @@ class DEBUGGER__ index = @break_points.index([file, pos]) STDOUT.printf "Breakpoint %d, %s at %s:%s\n", index, debug_funcname(id), file, pos - return TRUE + return true end - return FALSE + return false end def excn_handle(file, line, id, binding) fs = @frames.size tb = caller(0)[-fs..-1] - unless @frame_pos; @frame_pos = fs - 1; end STDOUT.printf "%s\n", $! for i in tb @@ -271,11 +279,15 @@ class DEBUGGER__ debug_command(file, line, id, binding) end - def trace_func(event, file, line, id, binding) - if event == 'line' - if @no_step == nil or @no_step >= @frames.size + case event + when 'line' + if !@no_step or @frames.size == @no_step @stop_next -= 1 + elsif @frames.size < @no_step + @stop_next = 0 # break here before leaving... + else + # nothing to do. skipped. end if @stop_next == 0 if [file, line] == @last @@ -289,31 +301,26 @@ class DEBUGGER__ if check_break_points(file, line, binding, id) debug_command(file, line, id, binding) end - end - if event == 'call' - @frames.push binding + when 'call' + @frames.unshift binding if check_break_points(file, id.id2name, binding, id) debug_command(file, line, id, binding) end - end - if event == 'class' - @frames.push binding - end + when 'class' + @frames.unshift binding - if event == 'return' or event == 'end' - if @finish_pos == @frames.size + when 'return', 'end' + if @frames.size == @finish_pos @stop_next = 1 end - @frames.pop - end + @frames.shift - if event == 'raise' - # @frames.push binding + when 'raise' excn_handle(file, line, id, binding) - end + end @last_file = file end |