From: "NAKAMURA, Hiroshi" Date: 1999-07-15T23:25:57+09:00 Subject: [ruby-dev:7323] [Patch] debug.rb なひです. > From: Yukihiro Matsumoto [mailto:matz@netlab.co.jp] > Sent: Thursday, July 15, 1999 6:13 PM > |ついでにlist -やlist連打機能もなくなっているので, > |そのうちまたPatchを作ろうかと思っています. > |が,なんか,Michaelさんに申し訳ないような気がして躊躇していたり.^^; > | > |gdb形式に戻したら怒るかなー.うーん. > > patchは歓迎します。gdb形式で構いません。つーのも、それがある > べき姿だからです。Michaelさんには...私から説明しましょう。 gdbに近いかどうか検証の余地はありますが,とりあえずup/downを元に戻し, またこれまでに実装済みだった部分を追加しました. ついでに混乱の元となっていた(?), caller(0)と@framesの順序について,同じ順序になるように @framesを入れ替えました. というわけで1.3.5からのPatchですが,まだ満足に検証してないので, もし試す方が居らっしゃる場合は,ご注意ください.^^; もう少し実装したい機能があるので, それが終わったらまたPatch出します... けっこうでかいス.^^; # Michaelの言う「例外からの復帰」は,interpreterの助け無しには # 難しそうですね...元々「いちかばちか」になるし. ## って話は元のMLでやんなさい > なひ / / / Index: debug.rb =================================================================== RCS file: /home/cvs/ruby/lib/debug.rb,v retrieving revision 1.1.1.2.2.4 diff -u -r1.1.1.2.2.4 debug.rb --- debug.rb 1999/07/15 07:59:58 1.1.1.2.2.4 +++ debug.rb 1999/07/15 14:14:59 @@ -1,22 +1,12 @@ - class DEBUGGER__ - - def max(a,b) - if (a 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] - 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 + STDOUT.printf " #%d %s\n", n, at[-(@frames.size - n)] 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 - - when /^f(inish)?/ - @finish_pos = @frames.size + binding = @frames[frame_pos] + info, binding_file, binding_line = frame_info(frame_pos) + STDOUT.printf "#%d %s\n", frame_pos, info + + 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,6 +220,12 @@ 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 @@ -262,7 +271,6 @@ 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 @@ 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 @@ 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