class TracePoint
Eine Klasse, die die Funktionalität von Kernel#set_trace_func in einer gut strukturierten objektorientierten API bereitstellt.
Beispiel
Verwenden Sie TracePoint, um Informationen speziell für Ausnahmen zu sammeln
trace = TracePoint.new(:raise) do |tp| p [tp.lineno, tp.event, tp.raised_exception] end #=> #<TracePoint:disabled> trace.enable #=> false 0 / 0 #=> [5, :raise, #<ZeroDivisionError: divided by 0>]
Ereignisse
Wenn Sie die Arten von Ereignissen, auf die Sie hören möchten, nicht angeben, enthält TracePoint alle verfügbaren Ereignisse.
Hinweis: Verlassen Sie sich nicht auf den aktuellen Ereignissatz, da diese Liste Änderungen unterliegt. Stattdessen wird empfohlen, die Arten von Ereignissen anzugeben, die Sie verwenden möchten.
Um zu filtern, was verfolgt wird, können Sie eine beliebige Anzahl der folgenden als events übergeben
:line-
Eine Anweisung oder ein Ausdruck in einer neuen Zeile ausführen.
:class-
Starten Sie die Definition einer Klasse oder eines Moduls.
:end-
Beenden Sie die Definition einer Klasse oder eines Moduls.
:call-
Rufen Sie eine Ruby-Methode auf.
:return-
Kehren Sie aus einer Ruby-Methode zurück.
:c_call-
Rufen Sie eine C-Routine auf.
:c_return-
Kehren Sie aus einer C-Routine zurück.
:raise-
Lösen Sie eine Ausnahme aus.
:rescue-
Fangen Sie eine Ausnahme ab.
:b_call-
Ereignis-Hook beim Eintritt in einen Block.
:b_return-
Ereignis-Hook beim Ende eines Blocks.
:a_call-
Ereignis-Hook bei allen Aufrufen (
call,b_callundc_call). :a_return-
Ereignis-Hook bei allen Rückgaben (
return,b_returnundc_return). :thread_begin-
Ereignis-Hook beim Beginn eines Threads.
:thread_end-
Ereignis-Hook beim Ende eines Threads.
:fiber_switch-
Ereignis-Hook beim Wechsel von Fibers.
:script_compiled-
Neuer Ruby-Code kompiliert (mit
eval,loadoderrequire).
Öffentliche Klassenmethoden
Source
# File trace_point.rb, line 200 def self.allow_reentry Primitive.attr! :use_block Primitive.tracepoint_allow_reentry end
Im Allgemeinen werden andere registrierte Callbacks nicht aufgerufen, während ein TracePoint-Callback ausgeführt wird, um Verwirrung durch Wiedereintritt zu vermeiden. Diese Methode erlaubt den Wiedereintritt innerhalb eines gegebenen Blocks. Verwenden Sie diese Methode vorsichtig, um eine unendliche Callback-Aufrufung zu vermeiden.
Wenn sie aufgerufen wird, wenn der Wiedereintritt bereits erlaubt ist, löst sie eine RuntimeError aus.
Beispiel
# Without reentry # --------------- line_handler = TracePoint.new(:line) do |tp| next if tp.path != __FILE__ # Only works in this file puts "Line handler" binding.eval("class C; end") end.enable class_handler = TracePoint.new(:class) do |tp| puts "Class handler" end.enable class B end # This script will print "Class handler" only once: when inside the :line # handler, all other handlers are ignored. # With reentry # ------------ line_handler = TracePoint.new(:line) do |tp| next if tp.path != __FILE__ # Only works in this file next if (__LINE__..__LINE__+3).cover?(tp.lineno) # Prevent infinite calls puts "Line handler" TracePoint.allow_reentry { binding.eval("class C; end") } end.enable class_handler = TracePoint.new(:class) do |tp| puts "Class handler" end.enable class B end # This will print "Class handler" twice: inside the allow_reentry block in the :line # handler, other handlers are enabled.
Beachten Sie, dass das Beispiel den Haupteffekt der Methode zeigt, aber ihre praktische Anwendung besteht darin, Bibliotheken zu debuggen, die manchmal erfordern, dass andere Bibliotheken-Hooks nicht von der Tatsache beeinflusst werden, dass der Debugger sich innerhalb der Trace-Point-Verarbeitung befindet. In diesem Fall sind Vorsichtsmaßnahmen gegen unendliche Rekursion zu treffen (beachten Sie, dass wir Aufrufe von sich selbst aus dem :line-Handler herausfiltern mussten, da er sich sonst unendlich selbst aufrufen würde).
Source
# File trace_point.rb, line 96 def self.new(*events) Primitive.attr! :use_block Primitive.tracepoint_new_s(events) end
Gibt ein neues, standardmäßig nicht aktiv geschaltetes TracePoint-Objekt zurück.
Um das TracePoint-Objekt zu aktivieren, verwenden Sie TracePoint#enable
trace = TracePoint.new(:call) do |tp| p [tp.lineno, tp.defined_class, tp.method_id, tp.event] end #=> #<TracePoint:disabled> trace.enable #=> false puts "Hello, TracePoint!" # ... # [48, IRB::Notifier::AbstractNotifier, :printf, :call] # ...
Um die Verfolgung zu deaktivieren, verwenden Sie TracePoint#disable.
trace.disable
Siehe Events at TracePoint für mögliche Ereignisse und weitere Informationen.
Es muss ein Block angegeben werden, andernfalls wird eine ArgumentError ausgelöst.
Wenn die Trace-Methode für den angegebenen Ereignis-Filter nicht unterstützt wird, wird eine RuntimeError ausgelöst.
TracePoint.trace(:line) do |tp| p tp.raised_exception end #=> RuntimeError: 'raised_exception' not supported by this event
Wenn die Trace-Methode außerhalb eines Blocks aufgerufen wird, wird eine RuntimeError ausgelöst.
TracePoint.trace(:line) do |tp| $tp = tp end $tp.lineno #=> access from outside (RuntimeError)
Der Zugriff von anderen Raktoren, Threads oder Fasern ist verboten. TracePoints sind pro Raktor aktiv, daher werden andere Raktoren nicht beeinflusst, wenn Sie einen TracePoint in einem Raktor aktivieren.
Source
# File trace_point.rb, line 119 def self.stat Primitive.tracepoint_stat_s end
Gibt interne Informationen von TracePoint zurück.
Der Inhalt des zurückgegebenen Werts ist implementierungsspezifisch und kann sich in Zukunft ändern.
Diese Methode dient nur dem Debugging von TracePoint selbst.
Source
# File trace_point.rb, line 134 def self.trace(*events) Primitive.attr! :use_block Primitive.tracepoint_trace_s(events) end
Eine Komfortmethode für TracePoint.new, die die Spur automatisch aktiviert.
trace = TracePoint.trace(:call) { |tp| [tp.lineno, tp.event] } #=> #<TracePoint:enabled> trace.enabled? #=> true
Öffentliche Instanzmethoden
Source
# File trace_point.rb, line 383 def binding Primitive.tracepoint_attr_binding end
Gibt das generierte Binding-Objekt aus dem Ereignis zurück.
Beachten Sie, dass für :c_call- und :c_return-Ereignisse die Methode nil zurückgibt, da C-Methoden selbst keine Bindungen haben.
Source
# File trace_point.rb, line 339 def callee_id Primitive.tracepoint_attr_callee_id end
Gibt den aufgerufenen Namen der aufgerufenen Methode zurück.
Source
# File trace_point.rb, line 375 def defined_class Primitive.tracepoint_attr_defined_class end
Gibt die Klasse oder das Modul der aufgerufenen Methode zurück.
class C; def foo; end; end trace = TracePoint.new(:call) do |tp| p tp.defined_class #=> C end.enable do C.new.foo end
Wenn die Methode von einem Modul definiert wurde, wird dieses Modul zurückgegeben.
module M; def foo; end; end class C; include M; end trace = TracePoint.new(:call) do |tp| p tp.defined_class #=> M end.enable do C.new.foo end
Hinweis: defined_class gibt die Singleton-Klasse zurück.
Der 6. Blockparameter von Kernel#set_trace_func übergibt die ursprüngliche Klasse, die von der Singleton-Klasse angehängt wurde.
Dies ist ein Unterschied zwischen Kernel#set_trace_func und TracePoint.
class C; def self.foo; end; end trace = TracePoint.new(:call) do |tp| p tp.defined_class #=> #<Class:C> end.enable do C.foo end
Source
# File trace_point.rb, line 297 def disable Primitive.attr! :use_block Primitive.tracepoint_disable_m end
Deaktiviert die Verfolgung.
Gibt true zurück, wenn die Verfolgung aktiviert war. Gibt false zurück, wenn die Verfolgung deaktiviert war.
trace.enabled? #=> true trace.disable #=> true (previous status) trace.enabled? #=> false trace.disable #=> false
Wenn ein Block angegeben wird, wird die Verfolgung nur innerhalb des Geltungsbereichs des Blocks deaktiviert.
trace.enabled? #=> true trace.disable do trace.enabled? # Only disabled for this block end trace.enabled? #=> true
Hinweis: Sie können innerhalb des Blocks nicht auf Ereignis-Hooks zugreifen.
trace.disable { p tp.lineno } #=> RuntimeError: access from outside
Source
# File trace_point.rb, line 261 def enable(target: nil, target_line: nil, target_thread: :default) Primitive.attr! :use_block Primitive.tracepoint_enable_m(target, target_line, target_thread) end
Aktiviert die Verfolgung.
Gibt true zurück, wenn die Verfolgung aktiviert war. Gibt false zurück, wenn die Verfolgung deaktiviert war.
trace.enabled? #=> false trace.enable #=> false (previous state) # trace is enabled trace.enabled? #=> true trace.enable #=> true (previous state) # trace is still enabled
Wenn ein Block angegeben wird, ist die Verfolgung nur während der Ausführung des Blocks aktiviert. Wenn target und target_line beide nil sind, ist target_thread standardmäßig der aktuelle Thread, wenn ein Block angegeben wird.
trace.enabled? #=> false trace.enable do trace.enabled? # Only enabled for this block and thread end trace.enabled? #=> false
Die Parameter target, target_line und target_thread werden verwendet, um die Verfolgung auf bestimmte Code-Objekte zu beschränken. target sollte ein Code-Objekt sein, für das RubyVM::InstructionSequence.of eine Instruktionssequenz zurückgibt.
t = TracePoint.new(:line) { |tp| p tp } def m1 p 1 end def m2 p 2 end t.enable(target: method(:m1)) m1 # Prints #<TracePoint:line test.rb:4 in `m1'> m2 # Prints nothing
Hinweis: Sie können innerhalb des enable-Blocks nicht auf Ereignis-Hooks zugreifen.
trace.enable { p tp.lineno } #=> RuntimeError: access from outside
Source
# File trace_point.rb, line 306 def enabled? Primitive.tracepoint_enabled_p end
Gibt den aktuellen Status der Verfolgung zurück.
Source
# File trace_point.rb, line 409 def eval_script Primitive.tracepoint_attr_eval_script end
Gibt den kompilierten Quellcode (String) von eval-Methoden beim :script_compiled-Ereignis zurück. Wenn aus einer Datei geladen, gibt sie nil zurück.
Source
# File trace_point.rb, line 313 def event Primitive.tracepoint_attr_event end
Gibt den Typ des Ereignisses zurück.
Siehe Events at TracePoint für weitere Informationen.
Source
# File trace_point.rb, line 106 def inspect Primitive.tracepoint_inspect end
Gibt einen String zurück, der einen menschenlesbaren TracePoint-Status enthält.
Source
# File trace_point.rb, line 417 def instruction_sequence Primitive.tracepoint_attr_instruction_sequence end
Gibt die kompilierte Instruktionssequenz, repräsentiert durch eine RubyVM::InstructionSequence-Instanz, beim :script_compiled-Ereignis zurück.
Beachten Sie, dass diese Methode CRuby-spezifisch ist.
Source
# File trace_point.rb, line 318 def lineno Primitive.tracepoint_attr_lineno end
Gibt die Zeilennummer des Ereignisses zurück.
Source
# File trace_point.rb, line 334 def method_id Primitive.tracepoint_attr_method_id end
Gibt den Namen bei der Definition der aufgerufenen Methode zurück.
Source
# File trace_point.rb, line 329 def parameters Primitive.tracepoint_attr_parameters end
Gibt die Parameterdefinitionen der Methode oder des Blocks zurück, zu dem der aktuelle Hook gehört. Das Format ist dasselbe wie bei Method#parameters.
Source
# File trace_point.rb, line 323 def path Primitive.tracepoint_attr_path end
Gibt den Pfad der ausgeführten Datei zurück.
Source
# File trace_point.rb, line 403 def raised_exception Primitive.tracepoint_attr_raised_exception end
Gibt die Ausnahme zurück, die beim :raise-Ereignis ausgelöst oder beim :rescue-Ereignis abgefangen wurde.
Source
# File trace_point.rb, line 398 def return_value Primitive.tracepoint_attr_return_value end
Gibt den Rückgabewert von :return-, :c_return- und :b_return-Ereignissen zurück.
Source
# File trace_point.rb, line 393 def self Primitive.tracepoint_attr_self end
Gibt das Trace-Objekt während des Ereignisses zurück.
Ähnlich wie unten, aber es gibt das korrekte Objekt (den Methodenempfänger) für :c_call- und :c_return-Ereignisse zurück
trace.binding.eval('self')