 +thread_add_trace_func(rb_thread_t *th, VALUE trace, rb_event_flag_t events)
  {
      if (!rb_obj_is_proc(trace)) {
- 	rb_raise(rb_eTypeError, "trace_func needs to be Proc");
+-	rb_raise(rb_eTypeError, "trace_func needs to be Proc");
++        rb_raise(rb_eTypeError, "trace_func needs to be Proc");
      }
  
 -    rb_threadptr_add_event_hook(th, call_trace_func, RUBY_EVENT_ALL, trace);

+    }
+
+    if (NIL_P(trace)) {
+	return Qnil;
+    }
+
+    if (!rb_obj_is_proc(trace)) {
+	rb_raise(rb_eTypeError, "trace_func needs to be Proc");
+    }
+
+    {
+	rb_thread_t *th           = GET_THREAD(); /* main thread */
+	th->trace_skip_insn_count = 2;
+	th->tracing               = -1;
+	rb_add_event_hook(call_trace_func, mask, trace);
+    }
+    
+    return trace;

  *
  *  Establishes _proc_ as the handler for tracing, or disables
  *  tracing if the parameter is +nil+. _proc_ takes up
@@ -3898,79 +3964,88 @@
  *  <code>line</code> (execute code on a new line), <code>raise</code>
  *  (raise an exception), and <code>return</code> (return from a Ruby
  *  method). Tracing is disabled within the context of _proc_.
