diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | lib/debug.rb | 106 | ||||
-rw-r--r-- | lib/tracer.rb | 6 | ||||
-rw-r--r-- | parse.y | 37 | ||||
-rw-r--r-- | thread.c | 46 |
5 files changed, 107 insertions, 98 deletions
@@ -1,3 +1,13 @@ +Mon Jun 18 16:57:24 2007 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * parse.y (yycompile): disable trace while creating ruby_debug_lines. + [ruby-talk:253586] + + * thread.c (ruby_suppress_tracing): new function to call a function + with suppressing trace. + + * lib/debug.rb, lib/tracer.rb: for YARV. + Mon Jun 18 13:54:36 2007 Nobuyoshi Nakada <nobu@ruby-lang.org> * eval.c (ruby_cleanup): return EXIT_FAILURE if any exceptions occured diff --git a/lib/debug.rb b/lib/debug.rb index 9ae119f8fb..1b5f2a2bb6 100644 --- a/lib/debug.rb +++ b/lib/debug.rb @@ -19,45 +19,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 +79,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? @@ -790,13 +752,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 +766,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 + for th, in @thread_list + 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 @@ -944,4 +903,7 @@ stdout.printf "Emacs support available.\n\n" set_trace_func proc { |event, file, line, id, binding, klass, *rest| DEBUGGER__.context.trace_func event, file, line, id, binding, klass } +VM::InstructionSequence.compile_option = { + trace_instruction: true +} end diff --git a/lib/tracer.rb b/lib/tracer.rb index 22f32bf222..5b3983bb9f 100644 --- a/lib/tracer.rb +++ b/lib/tracer.rb @@ -118,8 +118,8 @@ class Tracer return unless p.call event, file, line, id, binding, klass end - saved_crit = Thread.critical - Thread.critical = true + # saved_crit = Thread.critical + # Thread.critical = true stdout.printf("#%d:%s:%d:%s:%s: %s", get_thread_no, file, @@ -127,7 +127,7 @@ class Tracer klass || '', EVENT_SYMBOL[event], get_line(file, line)) - Thread.critical = saved_crit + # Thread.critical = saved_crit end Single = new @@ -4584,26 +4584,35 @@ parser_yyerror(struct parser_params *parser, const char *msg) static void parser_prepare(struct parser_params *parser); #ifndef RIPPER +VALUE ruby_suppress_tracing(VALUE (*func)(ANYARGS), VALUE arg); + +static VALUE +debug_lines(VALUE f) +{ + if (rb_const_defined_at(rb_cObject, rb_intern("SCRIPT_LINES__"))) { + VALUE hash = rb_const_get_at(rb_cObject, rb_intern("SCRIPT_LINES__")); + if (TYPE(hash) == T_HASH) { + VALUE fname = rb_str_new2((const char *)f); + VALUE lines = rb_hash_aref(hash, fname); + if (NIL_P(lines)) { + lines = rb_ary_new(); + rb_hash_aset(hash, fname, lines); + } + return lines; + } + } + return 0; +} + static NODE* yycompile(struct parser_params *parser, const char *f, int line) { int n; const char *kcode_save; - if (!compile_for_eval && rb_safe_level() == 0 && - rb_const_defined(rb_cObject, rb_intern("SCRIPT_LINES__"))) { - VALUE hash, fname; - - hash = rb_const_get(rb_cObject, rb_intern("SCRIPT_LINES__")); - if (TYPE(hash) == T_HASH) { - fname = rb_str_new2(f); - ruby_debug_lines = rb_hash_aref(hash, fname); - if (NIL_P(ruby_debug_lines)) { - ruby_debug_lines = rb_ary_new(); - rb_hash_aset(hash, fname, ruby_debug_lines); - } - } - if (line > 1) { + if (!compile_for_eval && rb_safe_level() == 0) { + ruby_debug_lines = ruby_suppress_tracing(debug_lines, (VALUE)f); + if (ruby_debug_lines && line > 1) { VALUE str = rb_str_new(0,0); n = line - 1; do { @@ -2789,17 +2789,47 @@ get_event_name(rb_event_flag_t event) } } +VALUE ruby_suppress_tracing(VALUE (*func)(ANYARGS), VALUE arg); + +struct call_trace_func_args { + rb_event_flag_t event; + VALUE proc; + VALUE self; + ID id; + VALUE klass; +}; + +static VALUE +call_trace_proc(VALUE args) +{ + struct call_trace_func_args *p = (struct call_trace_func_args *)args; + VALUE eventname = rb_str_new2(get_event_name(p->event)); + VALUE filename = rb_str_new2(rb_sourcefile()); + int line = rb_sourceline(); + + return rb_proc_call(p->proc, rb_ary_new3(6, + eventname, filename, INT2FIX(line), + p->id ? ID2SYM(p->id) : Qnil, + p->self ? rb_binding_new() : Qnil, + p->klass ? p->klass : Qnil)); +} + static void call_trace_func(rb_event_flag_t event, VALUE proc, VALUE self, ID id, VALUE klass) { + struct call_trace_func_args args = {event, proc, self, id, klass}; + ruby_suppress_tracing(call_trace_proc, (VALUE)&args); +} + +VALUE +ruby_suppress_tracing(VALUE (*func)(ANYARGS), VALUE arg) +{ rb_thread_t *th = GET_THREAD(); int state, raised; - VALUE eventname = rb_str_new2(get_event_name(event)); - VALUE filename = rb_str_new2(rb_sourcefile()); - int line = rb_sourceline(); + VALUE result = Qnil; if (th->tracing) { - return; + return Qnil; } else { th->tracing = 1; @@ -2809,11 +2839,7 @@ call_trace_func(rb_event_flag_t event, VALUE proc, VALUE self, ID id, VALUE klas PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { - proc_invoke(proc, rb_ary_new3(6, - eventname, filename, INT2FIX(line), - id ? ID2SYM(id) : Qnil, - self ? rb_binding_new() : Qnil, - klass ? klass : Qnil), Qundef, 0); + result = (*func)(arg); } if (raised) { @@ -2825,6 +2851,8 @@ call_trace_func(rb_event_flag_t event, VALUE proc, VALUE self, ID id, VALUE klas if (state) { JUMP_TAG(state); } + + return result; } /* |