Permalink
Browse files

app/frame.rb: Add direct recursion in stack frame and give a count of…

… repeated frames. Was floor rounding halfway frame point when should have been ceiling rounding.

source.rb: called ruby_syntax incorrectly.
app/options.rb: bump version number
  • Loading branch information...
rocky committed Oct 29, 2011
1 parent 5eeaed8 commit a4b3d00bde94ad250087e6cebeeccb21a9bf9ea3
Showing with 134 additions and 8 deletions.
  1. +24 −6 app/frame.rb
  2. +1 −1 app/options.rb
  3. +1 −0 app/run.rb
  4. +1 −1 processor/command/info_subcmd/source.rb
  5. +10 −0 test/example/factorial.rb
  6. +97 −0 test/functional/test-recursive-bt.rb
View
@@ -156,13 +156,20 @@ def format_stack_entry(frame, opts={})
return s
end
# Return true if frame1 and frame2 are at the same place.
# We use this for example in detecting tail recursion.
def location_equal(frame1, frame2)
frame1 && frame2 && frame1.source_location == frame2.source_location &&
frame1.pc_offset == frame2.pc_offset &&
frame1.source_container == frame2.source_container
end
def offset_for_return(event)
raise RuntimeError unless %w(return c-return).member?(event)
# FIXME: C calls have a RubyVM::Env added to the stack.
# Where? Why?
'return' == event ? 1 : 4
end
module_function :offset_for_return
def param_names(iseq, start, stop, prefix='')
start.upto(stop).map do |i|
@@ -180,18 +187,30 @@ def print_stack_entry(frame, i, prefix=' ', opts={})
end
def print_stack_trace_from_to(from, to, frame, opts)
last_frame = nil
# TODO: handle indirect recursion.
direct_recursion_count = 0
from.upto(to) do |i|
prefix = (i == opts[:current_pos]) ? '-->' : ' '
prefix += ' #%d ' % [i]
print_stack_entry(frame, i, prefix, opts)
if location_equal(last_frame, frame)
direct_recursion_count += 1
else
if direct_recursion_count > 0
msg("... above line repeated #{direct_recursion_count} times")
direct_recursion_count = 0
end
prefix = (i == opts[:current_pos]) ? '-->' : ' '
prefix += ' #%d ' % [i]
print_stack_entry(frame, i, prefix, opts)
end
last_frame = frame
frame = frame.prev
end
end
# Print `count' frame entries
def print_stack_trace(frame, opts={})
opts = DEFAULT_STACK_TRACE_SETTINGS.merge(opts)
halfstack = opts[:maxstack] / 2
halfstack = (opts[:maxstack]+1) / 2
n = frame.stack_size
n = [n, opts[:count]].min if opts[:count]
if n > (halfstack * 2)
@@ -212,7 +231,6 @@ def set_return_value(frame, event, value)
def value_returned(frame, event)
frame.sp(offset_for_return(event))
end
module_function :value_returned
end
end
View
@@ -8,7 +8,7 @@
class Trepan
require_relative 'default'
VERSION = '0.1.4'
VERSION = '0.1.5dev'
PROGRAM = 'trepan'
def self.show_version
View
@@ -71,6 +71,7 @@ def ruby_syntax_errors(prog_script)
end
return nil
end
module_function :ruby_syntax_errors
end
if __FILE__ == $0
@@ -49,7 +49,7 @@ def run(args)
max_line = LineCache::size(canonic_name)
msg 'File has %d lines.' % max_line if max_line
msg('SHA1 is %s.' % LineCache::sha1(canonic_name))
syntax_errors = Trepan::ruby_syntax_errors(canonic_name)
syntax_errors = Trepanning::ruby_syntax_errors(canonic_name)
if syntax_errors
msg('Not a syntactically-correct Ruby program.')
else
View
@@ -0,0 +1,10 @@
def factorial(n)
if n > 0
return n * factorial(n-1)
else
return 1
end
end
n = ARGV[0] || 5
puts "#{n}! is #{factorial(5)}"
@@ -0,0 +1,97 @@
#!/usr/bin/env ruby
require 'test/unit'
require 'trace'
require_relative 'fn_helper'
class TestRecursiveBt < Test::Unit::TestCase
include FnTestHelper
def test_recursive_backtrace
cmds = [
'set events line',
'set basename on',
'step',
'bt 1',
'step',
'step',
'bt 2',
'step',
'step',
'bt 3',
'step',
'step',
'step',
'bt 5',
'step',
'step',
'step',
'bt 7',
]
d = strarray_setup(cmds)
d.start
##############################
def factorial(n)
if n > 0
return n * factorial(n-1)
else
return 1
end
end
z = factorial(5)
##############################
d.stop
out =
["-- ",
"def factorial(n)",
"Trace events we may stop on:",
"\tbrkpt, line",
"basename is on.",
"-- ",
"z = factorial(5)",
"--> #0 METHOD TestRecursiveBt#test_recursive_backtrace() in file test-recursive-bt.rb at line 42",
"-- ",
"if n > 0",
"-- ",
"return n * factorial(n-1)",
"--> #0 METHOD TestRecursiveBt#factorial(n) in file test-recursive-bt.rb at line 37",
" #1 METHOD TestRecursiveBt#test_recursive_backtrace() in file test-recursive-bt.rb at line 42",
"-- ",
"if n > 0",
"-- ",
"return n * factorial(n-1)",
"--> #0 METHOD TestRecursiveBt#factorial(n) in file test-recursive-bt.rb at line 37",
" #1 METHOD TestRecursiveBt#factorial(n) in file test-recursive-bt.rb at line 37",
" #2 METHOD TestRecursiveBt#test_recursive_backtrace() in file test-recursive-bt.rb at line 42",
"-- ",
"if n > 0",
"-- ",
"return n * factorial(n-1)",
"-- ",
"if n > 0",
"--> #0 METHOD TestRecursiveBt#factorial(n) in file test-recursive-bt.rb at line 36",
" #1 METHOD TestRecursiveBt#factorial(n) in file test-recursive-bt.rb at line 37",
"... above line repeated 2 times",
" #4 METHOD TestRecursiveBt#test_recursive_backtrace() in file test-recursive-bt.rb at line 42",
"-- ",
"return n * factorial(n-1)",
"-- ",
"if n > 0",
"-- ",
"return n * factorial(n-1)",
"--> #0 METHOD TestRecursiveBt#factorial(n) in file test-recursive-bt.rb at line 37",
" #1 METHOD TestRecursiveBt#factorial(n) in file test-recursive-bt.rb at line 37",
"... above line repeated 3 times",
" #5 METHOD TestRecursiveBt#test_recursive_backtrace() in file test-recursive-bt.rb at line 42",
" #6 METHOD TestRecursiveBt#run(runner) in file unit.rb at line 695",
"-- ",
"if n > 0",
"-- ",
"return 1",
"-- ",
"d.stop"]
compare_output(out, d, cmds)
end
end

0 comments on commit a4b3d00

Please sign in to comment.