From c101164b0225b777b2d8521fad29352087b996e3 Mon Sep 17 00:00:00 2001 From: matz Date: Mon, 25 Dec 2000 07:31:43 +0000 Subject: cvs.netlab.co.jp last commit git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1078 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/debug.rb | 186 +++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 143 insertions(+), 43 deletions(-) diff --git a/lib/debug.rb b/lib/debug.rb index b6968cc338..3281f7b4e9 100644 --- a/lib/debug.rb +++ b/lib/debug.rb @@ -91,22 +91,54 @@ class DEBUGGER__ @finish_pos = 0 @trace = false @catch = "StandardError" + @suspend_next = false end def stop_next(n=1) @stop_next = n end + def suspend + @suspend_next = true + end + + def check_suspend + while (Thread.critical = true; @suspend_next) + waiting.push Thread.current + @suspend_next = false + Thread.stop + end + Thread.critical = false + end + + def trace? + @trace + end + + def set_trace(arg) + @trace = arg + end + def stdout DEBUGGER__.stdout end + def break_points DEBUGGER__.break_points end + def display DEBUGGER__.display end + def waiting + DEBUGGER__.waiting + end + + def set_trace_all(arg) + DEBUGGER__.set_trace(arg) + end + def debug_eval(str, binding) begin val = eval(str, binding) @@ -218,7 +250,8 @@ class DEBUGGER__ end @frames[0] = [binding, file, line, id] display_expressions(binding) - while input = readline("(rdb:%d) "%thnum(), true) + prompt = true + while prompt and input = readline("(rdb:%d) "%thnum(), true) catch(:debug_error) do if input == "" input = DEBUG_LAST_CMD[0] @@ -228,18 +261,24 @@ class DEBUGGER__ end case input - when /^\s*tr(?:ace)?(?:\s+(on|off))?$/ - if defined?( $1 ) + when /^\s*tr(?:ace)?(?:\s+(on|off))?(?:\s+(all))?$/ + if defined?( $2 ) if $1 == 'on' - @trace = true + set_trace_all true else - @trace = false + set_trace_all false + end + elsif defined?( $1 ) + if $1 == 'on' + set_trace true + else + set_trace false end end - if @trace - stdout.print "Trace on\n" + if trace? + stdout.print "Trace on.\n" else - stdout.print "Trace off\n" + stdout.print "Trace off.\n" end when /^\s*b(?:reak)?\s+((?:.*?+:)?.+)$/ @@ -336,8 +375,7 @@ class DEBUGGER__ end when /^\s*c(?:ont)?$/ - MUTEX.unlock - return + prompt = false when /^\s*s(?:tep)?(?:\s+(\d+))?$/ if $1 @@ -346,7 +384,7 @@ class DEBUGGER__ lev = 1 end @stop_next = lev - return + prompt = false when /^\s*n(?:ext)?(?:\s+(\d+))?$/ if $1 @@ -356,7 +394,7 @@ class DEBUGGER__ end @stop_next = lev @no_step = @frames.size - frame_pos - return + prompt = false when /^\s*w(?:here)?$/, /^\s*f(?:rame)?$/ display_frames(frame_pos) @@ -417,8 +455,7 @@ class DEBUGGER__ else @finish_pos = @frames.size - frame_pos frame_pos = 0 - MUTEX.unlock - return + prompt = false end when /^\s*cat(?:ch)?(?:\s+(.+))?$/ @@ -440,8 +477,10 @@ class DEBUGGER__ end when /^\s*q(?:uit)?$/ - input = readline("really quit? (y/n) ", false) - exit if input == "y" + input = readline("Really quit? (y/n) ", false) + if input == "y" + exit! # exit -> exit!: No graceful way to stop threads... + end when /^\s*v(?:ar)?\s+/ debug_variable_info($', binding) @@ -451,8 +490,7 @@ class DEBUGGER__ when /^\s*th(?:read)?\s+/ if DEBUGGER__.debug_thread_info($', binding) == :cont - MUTEX.unlock - return + prompt = false end when /^\s*p\s+/ @@ -467,6 +505,8 @@ class DEBUGGER__ end end end + MUTEX.unlock + DEBUGGER__.resume_all_thread end def debug_print_help @@ -492,7 +532,8 @@ Commands up[ nn] move to higher frame down[ nn] move to lower frame fin[ish] return to outer frame - tr[ace][ (on|off)] set trace mode + tr[ace] (on|off) set trace mode of current thread + tr[ace] (on|off) all set trace mode of all threads q[uit] exit from debugger v[ar] g[lobal] show global variables v[ar] l[ocal] show local variables @@ -501,11 +542,10 @@ Commands m[ethod] i[nstance] show methods of object m[ethod] show instance methods of class or module th[read] l[ist] list all threads - th[read] c[ur[rent]] show current threads - th[read] stop thread nnn - th[read] stop alias for th[read] - th[read] c[ur[rent]] alias for th[read] - th[read] resume run thread nnn + th[read] c[ur[rent]] show current thread + th[read] [sw[itch]] switch thread context to nnn + th[read] stop stop thread nnn + th[read] resume resume thread nnn p expression evaluate expression and print its value h[elp] print this help evaluate @@ -587,7 +627,7 @@ EOHELP end def check_break_points(file, pos, binding, id) - MUTEX.lock # Stop all threads before 'line' and 'call'. + return false if break_points.empty? file = File.basename(file) n = 1 for b in break_points @@ -604,7 +644,6 @@ EOHELP end n += 1 end - MUTEX.unlock return false end @@ -616,7 +655,6 @@ EOHELP end if @catch and ($!.type.ancestors.find { |e| e.to_s == @catch }) - MUTEX.lock fs = @frames.size tb = caller(0)[-fs..-1] if tb @@ -624,12 +662,14 @@ EOHELP stdout.printf "\tfrom %s\n", i end end + DEBUGGER__.suspend_all_thread debug_command(file, line, id, binding) end end def trace_func(event, file, line, id, binding, klass) - Tracer.trace_func(event, file, line, id, binding) if @trace + Tracer.trace_func(event, file, line, id, binding, klass) if trace? + DEBUGGER__.context(Thread.current).check_suspend @file = file @line = line case event @@ -647,6 +687,7 @@ EOHELP @stop_next = 1 else @no_step = nil + DEBUGGER__.suspend_all_thread debug_command(file, line, id, binding) @last = [file, line] end @@ -656,6 +697,7 @@ EOHELP @frames.unshift [binding, file, line, id] if check_break_points(file, id.id2name, binding, id) or check_break_points(klass.to_s, id.id2name, binding, id) + DEBUGGER__.suspend_all_thread debug_command(file, line, id, binding) end @@ -682,19 +724,20 @@ EOHELP end end - trap("INT") { DEBUGGER__.interrupt } -# $DEBUG = true + trap("INT") { DEBUGGER__.interrupt } @last_thread = Thread::main @max_thread = 1 @thread_list = {Thread::main => 1} @break_points = [] @display = [] + @waiting = [] @stdout = STDOUT class <