[ruby/irb] Improve help message for no meta commands
[ruby.git] / trace_point.rb
blobb136e9b399dbe6dd9de0a51ada07e53f38375502
1 # loaded from vm_trace.c
3 # A class that provides the functionality of Kernel#set_trace_func in a
4 # nice Object-Oriented API.
6 # == Example
8 # We can use TracePoint to gather information specifically for exceptions:
10 #           trace = TracePoint.new(:raise) do |tp|
11 #               p [tp.lineno, tp.event, tp.raised_exception]
12 #           end
13 #           #=> #<TracePoint:disabled>
15 #           trace.enable
16 #           #=> false
18 #           0 / 0
19 #           #=> [5, :raise, #<ZeroDivisionError: divided by 0>]
21 # == Events
23 # If you don't specify the type of events you want to listen for,
24 # TracePoint will include all available events.
26 # *Note* do not depend on current event set, as this list is subject to
27 # change. Instead, it is recommended you specify the type of events you
28 # want to use.
30 # To filter what is traced, you can pass any of the following as +events+:
32 # +:line+:: execute an expression or statement on a new line
33 # +:class+:: start a class or module definition
34 # +:end+:: finish a class or module definition
35 # +:call+:: call a Ruby method
36 # +:return+:: return from a Ruby method
37 # +:c_call+:: call a C-language routine
38 # +:c_return+:: return from a C-language routine
39 # +:raise+:: raise an exception
40 # +:rescue+:: rescue an exception
41 # +:b_call+:: event hook at block entry
42 # +:b_return+:: event hook at block ending
43 # +:a_call+:: event hook at all calls (+call+, +b_call+, and +c_call+)
44 # +:a_return+:: event hook at all returns (+return+, +b_return+, and +c_return+)
45 # +:thread_begin+:: event hook at thread beginning
46 # +:thread_end+:: event hook at thread ending
47 # +:fiber_switch+:: event hook at fiber switch
48 # +:script_compiled+:: new Ruby code compiled (with +eval+, +load+ or +require+)
50 class TracePoint
51   # call-seq:
52   #     TracePoint.new(*events) { |obj| block }     -> obj
53   #
54   # Returns a new TracePoint object, not enabled by default.
55   #
56   # Next, in order to activate the trace, you must use TracePoint#enable
57   #
58   #     trace = TracePoint.new(:call) do |tp|
59   #         p [tp.lineno, tp.defined_class, tp.method_id, tp.event]
60   #     end
61   #     #=> #<TracePoint:disabled>
62   #
63   #     trace.enable
64   #     #=> false
65   #
66   #     puts "Hello, TracePoint!"
67   #     # ...
68   #     # [48, IRB::Notifier::AbstractNotifier, :printf, :call]
69   #     # ...
70   #
71   # When you want to deactivate the trace, you must use TracePoint#disable
72   #
73   #     trace.disable
74   #
75   # See TracePoint@Events for possible events and more information.
76   #
77   # A block must be given, otherwise an ArgumentError is raised.
78   #
79   # If the trace method isn't included in the given events filter, a
80   # RuntimeError is raised.
81   #
82   #     TracePoint.trace(:line) do |tp|
83   #         p tp.raised_exception
84   #     end
85   #     #=> RuntimeError: 'raised_exception' not supported by this event
86   #
87   # If the trace method is called outside block, a RuntimeError is raised.
88   #
89   #      TracePoint.trace(:line) do |tp|
90   #        $tp = tp
91   #      end
92   #      $tp.lineno #=> access from outside (RuntimeError)
93   #
94   # Access from other threads is also forbidden.
95   #
96   def self.new(*events)
97     Primitive.attr! :use_block
98     Primitive.tracepoint_new_s(events)
99   end
101   #  call-seq:
102   #    trace.inspect  -> string
103   #
104   #  Return a string containing a human-readable TracePoint
105   #  status.
106   def inspect
107     Primitive.tracepoint_inspect
108   end
110   # call-seq:
111   #     TracePoint.stat -> obj
112   #
113   #  Returns internal information of TracePoint.
114   #
115   #  The contents of the returned value are implementation specific.
116   #  It may be changed in future.
117   #
118   #  This method is only for debugging TracePoint itself.
119   def self.stat
120     Primitive.tracepoint_stat_s
121   end
123   # call-seq:
124   #        TracePoint.trace(*events) { |obj| block }    -> obj
125   #
126   # A convenience method for TracePoint.new, that activates the trace
127   # automatically.
128   #
129   #         trace = TracePoint.trace(:call) { |tp| [tp.lineno, tp.event] }
130   #         #=> #<TracePoint:enabled>
131   #
132   #         trace.enabled? #=> true
133   #
134   def self.trace(*events)
135     Primitive.attr! :use_block
136     Primitive.tracepoint_trace_s(events)
137   end
139   # call-seq:
140   #   TracePoint.allow_reentry { block }
141   #
142   # In general, while a TracePoint callback is running,
143   # other registered callbacks are not called to avoid
144   # confusion by reentrance.
145   # This method allows the reentrance in a given block.
146   # This method should be used carefully, otherwise the callback
147   # can be easily called infinitely.
148   #
149   # If this method is called when the reentrance is already allowed,
150   # it raises a RuntimeError.
151   #
152   # <b>Example:</b>
153   #
154   #   # Without reentry
155   #   # ---------------
156   #
157   #   line_handler = TracePoint.new(:line) do |tp|
158   #     next if tp.path != __FILE__ # only work in this file
159   #     puts "Line handler"
160   #     binding.eval("class C; end")
161   #   end.enable
162   #
163   #   class_handler = TracePoint.new(:class) do |tp|
164   #     puts "Class handler"
165   #   end.enable
166   #
167   #   class B
168   #   end
169   #
170   #   # This script will print "Class handler" only once: when inside :line
171   #   # handler, all other handlers are ignored
172   #
173   #
174   #   # With reentry
175   #   # ------------
176   #
177   #   line_handler = TracePoint.new(:line) do |tp|
178   #     next if tp.path != __FILE__ # only work in this file
179   #     next if (__LINE__..__LINE__+3).cover?(tp.lineno) # don't be invoked from itself
180   #     puts "Line handler"
181   #     TracePoint.allow_reentry { binding.eval("class C; end") }
182   #   end.enable
183   #
184   #   class_handler = TracePoint.new(:class) do |tp|
185   #     puts "Class handler"
186   #   end.enable
187   #
188   #   class B
189   #   end
190   #
191   #   # This wil print "Class handler" twice: inside allow_reentry block in :line
192   #   # handler, other handlers are enabled.
193   #
194   # Note that the example shows the principal effect of the method, but its
195   # practical usage is for debugging libraries that sometimes require other libraries
196   # hooks to not be affected by debugger being inside trace point handling. Precautions
197   # should be taken against infinite recursion in this case (note that we needed to filter
198   # out calls by itself from :line handler, otherwise it will call itself infinitely).
199   #
200   def self.allow_reentry
201     Primitive.attr! :use_block
202     Primitive.tracepoint_allow_reentry
203   end
205   # call-seq:
206   #    trace.enable(target: nil, target_line: nil, target_thread: nil)    -> true or false
207   #    trace.enable(target: nil, target_line: nil, target_thread: :default) { block }  -> obj
208   #
209   # Activates the trace.
210   #
211   # Returns +true+ if trace was enabled.
212   # Returns +false+ if trace was disabled.
213   #
214   #   trace.enabled?  #=> false
215   #   trace.enable    #=> false (previous state)
216   #                   #   trace is enabled
217   #   trace.enabled?  #=> true
218   #   trace.enable    #=> true (previous state)
219   #                   #   trace is still enabled
220   #
221   # If a block is given, the trace will only be enabled during the block call.
222   # If target and target_line are both nil, then target_thread will default
223   # to the current thread if a block is given.
224   #
225   #    trace.enabled?
226   #    #=> false
227   #
228   #    trace.enable do
229   #      trace.enabled?
230   #      # only enabled for this block and thread
231   #    end
232   #
233   #    trace.enabled?
234   #    #=> false
235   #
236   # +target+, +target_line+ and +target_thread+ parameters are used to
237   # limit tracing only to specified code objects. +target+ should be a
238   # code object for which RubyVM::InstructionSequence.of will return
239   # an instruction sequence.
240   #
241   #    t = TracePoint.new(:line) { |tp| p tp }
242   #
243   #    def m1
244   #      p 1
245   #    end
246   #
247   #    def m2
248   #      p 2
249   #    end
250   #
251   #    t.enable(target: method(:m1))
252   #
253   #    m1
254   #    # prints #<TracePoint:line test.rb:4 in `m1'>
255   #    m2
256   #    # prints nothing
257   #
258   # Note: You cannot access event hooks within the +enable+ block.
259   #
260   #    trace.enable { p tp.lineno }
261   #    #=> RuntimeError: access from outside
262   #
263   def enable(target: nil, target_line: nil, target_thread: :default)
264     Primitive.attr! :use_block
265     Primitive.tracepoint_enable_m(target, target_line, target_thread)
266   end
268   # call-seq:
269   #     trace.disable           -> true or false
270   #     trace.disable { block } -> obj
271   #
272   # Deactivates the trace
273   #
274   # Return true if trace was enabled.
275   # Return false if trace was disabled.
276   #
277   #     trace.enabled?  #=> true
278   #     trace.disable   #=> true (previous status)
279   #     trace.enabled?  #=> false
280   #     trace.disable   #=> false
281   #
282   # If a block is given, the trace will only be disable within the scope of the
283   # block.
284   #
285   #     trace.enabled?
286   #     #=> true
287   #
288   #     trace.disable do
289   #         trace.enabled?
290   #         # only disabled for this block
291   #     end
292   #
293   #     trace.enabled?
294   #     #=> true
295   #
296   # Note: You cannot access event hooks within the block.
297   #
298   #     trace.disable { p tp.lineno }
299   #     #=> RuntimeError: access from outside
300   def disable
301     Primitive.attr! :use_block
302     Primitive.tracepoint_disable_m
303   end
305   # call-seq:
306   #     trace.enabled?      -> true or false
307   #
308   # The current status of the trace
309   def enabled?
310     Primitive.tracepoint_enabled_p
311   end
313   # Type of event
314   #
315   # See TracePoint@Events for more information.
316   def event
317     Primitive.tracepoint_attr_event
318   end
320   # Line number of the event
321   def lineno
322     Primitive.tracepoint_attr_lineno
323   end
325   # Path of the file being run
326   def path
327     Primitive.tracepoint_attr_path
328   end
330   # Return the parameters definition of the method or block that the
331   # current hook belongs to. Format is the same as for Method#parameters
332   def parameters
333     Primitive.tracepoint_attr_parameters
334   end
336   # Return the name at the definition of the method being called
337   def method_id
338     Primitive.tracepoint_attr_method_id
339   end
341   # Return the called name of the method being called
342   def callee_id
343     Primitive.tracepoint_attr_callee_id
344   end
346   # Return class or module of the method being called.
347   #
348   #     class C; def foo; end; end
349   #     trace = TracePoint.new(:call) do |tp|
350   #       p tp.defined_class #=> C
351   #     end.enable do
352   #       C.new.foo
353   #     end
354   #
355   # If method is defined by a module, then that module is returned.
356   #
357   #     module M; def foo; end; end
358   #     class C; include M; end;
359   #     trace = TracePoint.new(:call) do |tp|
360   #       p tp.defined_class #=> M
361   #     end.enable do
362   #       C.new.foo
363   #     end
364   #
365   # <b>Note:</b> #defined_class returns singleton class.
366   #
367   # 6th block parameter of Kernel#set_trace_func passes original class
368   # of attached by singleton class.
369   #
370   # <b>This is a difference between Kernel#set_trace_func and TracePoint.</b>
371   #
372   #     class C; def self.foo; end; end
373   #     trace = TracePoint.new(:call) do |tp|
374   #       p tp.defined_class #=> #<Class:C>
375   #     end.enable do
376   #       C.foo
377   #     end
378   def defined_class
379     Primitive.tracepoint_attr_defined_class
380   end
382   # Return the generated binding object from event.
383   #
384   # Note that for +:c_call+ and +:c_return+ events, the method will return
385   # +nil+, since C methods themselves do not have bindings.
386   def binding
387     Primitive.tracepoint_attr_binding
388   end
390   # Return the trace object during event
391   #
392   # Same as the following, except it returns the correct object (the method
393   # receiver) for +:c_call+ and +:c_return+ events:
394   #
395   #   trace.binding.eval('self')
396   def self
397     Primitive.tracepoint_attr_self
398   end
400   #  Return value from +:return+, +:c_return+, and +:b_return+ event
401   def return_value
402     Primitive.tracepoint_attr_return_value
403   end
405   # Value from exception raised on the +:raise+ event, or rescued on the +:rescue+ event.
406   def raised_exception
407     Primitive.tracepoint_attr_raised_exception
408   end
410   # Compiled source code (String) on *eval methods on the +:script_compiled+ event.
411   # If loaded from a file, it will return nil.
412   def eval_script
413     Primitive.tracepoint_attr_eval_script
414   end
416   # Compiled instruction sequence represented by a RubyVM::InstructionSequence instance
417   # on the +:script_compiled+ event.
418   #
419   # Note that this method is MRI specific.
420   def instruction_sequence
421     Primitive.tracepoint_attr_instruction_sequence
422   end