summaryrefslogtreecommitdiff
path: root/lib/debug.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/debug.rb')
-rw-r--r--lib/debug.rb126
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
}