diff options
Diffstat (limited to 'lib/debug.rb')
| -rw-r--r-- | lib/debug.rb | 126 |
1 files changed, 43 insertions, 83 deletions
diff --git a/lib/debug.rb b/lib/debug.rb index 9ae119f8fb..5cbd7f7aab 100644 --- a/lib/debug.rb +++ b/lib/debug.rb @@ -2,6 +2,8 @@ # Copyright (C) 2000 Information-technology Promotion Agency, Japan # Copyright (C) 2000-2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org> +require 'continuation' + if $SAFE > 0 STDERR.print "-r debug.rb is not available in safe mode\n" exit 1 @@ -19,45 +21,6 @@ end SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__ class DEBUGGER__ -class Mutex - def initialize - @locker = nil - @waiting = [] - @locked = false; - end - - def locked? - @locked - end - - def lock - return if Thread.critical - return if @locker == Thread.current - while (Thread.critical = true; @locked) - @waiting.push Thread.current - Thread.stop - end - @locked = true - @locker = Thread.current - Thread.critical = false - self - end - - def unlock - return if Thread.critical - return unless @locked - unless @locker == Thread.current - raise RuntimeError, "unlocked by other" - end - Thread.critical = true - t = @waiting.shift - @locked = false - @locker = nil - Thread.critical = false - t.run if t - self - end -end MUTEX = Mutex.new class Context @@ -118,13 +81,14 @@ class Context end def check_suspend - return if Thread.critical - while (Thread.critical = true; @suspend_next) - DEBUGGER__.waiting.push Thread.current - @suspend_next = false - Thread.stop + while MUTEX.synchronize { + if @suspend_next + DEBUGGER__.waiting.push Thread.current + @suspend_next = false + true + end + } end - Thread.critical = false end def trace? @@ -183,7 +147,7 @@ class Context def var_list(ary, binding) ary.sort! for v in ary - stdout.printf " %s => %s\n", v, eval(v, binding).inspect + stdout.printf " %s => %s\n", v, eval(v.to_s, binding).inspect end end @@ -256,7 +220,7 @@ class Context def debug_command(file, line, id, binding) MUTEX.lock unless defined?($debugger_restart) and $debugger_restart - callcc{|c| $debugger_restart = c} + callcc{|c| $debugger_restart = c} end set_last_thread(Thread.current) frame_pos = 0 @@ -333,9 +297,9 @@ class Context if break_points.find{|b| b[1] == 0} n = 1 stdout.print "Breakpoints:\n" - for b in break_points + break_points.each do |b| if b[0] and b[1] == 0 - stdout.printf " %d %s:%s\n", n, b[2], b[3] + stdout.printf " %d %s:%s\n", n, b[2], b[3] end n += 1 end @@ -629,7 +593,6 @@ EOHELP def display_list(b, e, file, line) stdout.printf "[%d, %d] in %s\n", b, e, file if lines = SCRIPT_LINES__[file] and lines != true - n = 0 b.upto(e) do |n| if n > 0 && lines[n-1] if n == line @@ -748,10 +711,7 @@ EOHELP end @frames.shift - when 'end' - @frames.shift - - when 'raise' + when 'raise' excn_handle(file, line, id, binding) end @@ -790,13 +750,12 @@ class << DEBUGGER__ end def set_trace( arg ) - saved_crit = Thread.critical - Thread.critical = true - make_thread_list - for th, in @thread_list - context(th).set_trace arg + MUTEX.synchronize do + make_thread_list + for th, in @thread_list + context(th).set_trace arg + end end - Thread.critical = saved_crit arg end @@ -805,31 +764,29 @@ class << DEBUGGER__ end def suspend - saved_crit = Thread.critical - Thread.critical = true - make_thread_list - for th, in @thread_list - next if th == Thread.current - context(th).set_suspend - end - Thread.critical = saved_crit + MUTEX.synchronize do + make_thread_list + for th, in @thread_list + next if th == Thread.current + context(th).set_suspend + end + end # Schedule other threads to suspend as soon as possible. - Thread.pass unless Thread.critical + Thread.pass end def resume - saved_crit = Thread.critical - Thread.critical = true - make_thread_list - for th, in @thread_list - next if th == Thread.current - context(th).clear_suspend - end - waiting.each do |th| - th.run - end - waiting.clear - Thread.critical = saved_crit + MUTEX.synchronize do + make_thread_list + @thread_list.each do |th,| + next if th == Thread.current + context(th).clear_suspend + end + waiting.each do |th| + th.run + end + waiting.clear + end # Schedule other threads to restart as soon as possible. Thread.pass end @@ -847,7 +804,7 @@ class << DEBUGGER__ end def get_thread(num) - th = @thread_list.index(num) + th = @thread_list.key(num) unless th @stdout.print "No thread ##{num}\n" throw :debug_error @@ -921,7 +878,7 @@ class << DEBUGGER__ @stdout.print "Already stopped.\n" else thread_list(@thread_list[th]) - context(th).suspend + context(th).suspend end when /^resume\s+(\d+)/ @@ -941,6 +898,9 @@ end stdout.printf "Debug.rb\n" stdout.printf "Emacs support available.\n\n" +RubyVM::InstructionSequence.compile_option = { + trace_instruction: true +} set_trace_func proc { |event, file, line, id, binding, klass, *rest| DEBUGGER__.context.trace_func event, file, line, id, binding, klass } |
