summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--lib/debug.rb106
-rw-r--r--lib/tracer.rb6
-rw-r--r--parse.y37
-rw-r--r--thread.c46
5 files changed, 107 insertions, 98 deletions
diff --git a/ChangeLog b/ChangeLog
index f9b8bdacb4..ce78f09f48 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/parse.y b/parse.y
index 21d9fd1f53..5bd59c69dd 100644
--- a/parse.y
+++ b/parse.y
@@ -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 {
diff --git a/thread.c b/thread.c
index b4043bf3d3..02cf11e15d 100644
--- a/thread.c
+++ b/thread.c
@@ -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;
}
/*