Spec-Zone.ru › Ruby 3.4

class TracePoint

Родительский класс:
Object

Класс, предоставляющий функциональность Kernel#set_trace_func в хорошо структурированном объектно-ориентированном API.

Пример

Используйте TracePoint, чтобы собирать сведения именно об исключениях:

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>]

События

Если не указать типы событий, за которыми нужно следить, TracePoint будет включать все доступные события.

Примечание: Не полагайтесь на текущий набор событий, поскольку этот список может измениться. Вместо этого рекомендуется указывать типы событий, которые вы хотите использовать.

Чтобы отфильтровать отслеживаемые события, в качестве events можно передать любое из следующих значений:

:line

Выполнить выражение или инструкцию на новой строке.

:class

Начать определение класса или модуля.

:end

Завершить определение класса или модуля.

:call

Вызвать метод Ruby.

:return

Вернуться из метода Ruby.

:c_call

Вызвать подпрограмму на языке C.

:c_return

Вернуться из подпрограммы на языке C.

:raise

Возбудить исключение.

:rescue

Перехватить исключение.

:b_call

Хук события при входе в блок.

:b_return

Хук события при завершении блока.

:a_call

Хук события при всех вызовах (call, b_call и c_call).

:a_return

Хук события при всех возвратах (return, b_return и c_return).

:thread_begin

Хук события при запуске потока.

:thread_end

Хук события при завершении потока.

:fiber_switch

Хук события при переключении fiber.

:script_compiled

Скомпилирован новый код Ruby (с помощью eval, load или require).

Общедоступные методы класса

allow_reentry { block } Показать исходный код
# File trace_point.rb, line 198
def self.allow_reentry
  Primitive.attr! :use_block
  Primitive.tracepoint_allow_reentry
end

Как правило, пока выполняется обратный вызов TracePoint, другие зарегистрированные обратные вызовы не вызываются, чтобы избежать путаницы из-за повторного входа. Этот метод разрешает повторный вход в пределах указанного блока. Используйте его осторожно, чтобы избежать бесконечного вызова обратных вызовов.

Если повторный вход уже разрешён, при вызове этого метода возникает исключение RuntimeError.

Пример:

# 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.

Обратите внимание, что в примере показан основной эффект метода, но на практике он применяется для отладки библиотек, которым иногда требуется, чтобы хуки других библиотек не зависели от того, что отладчик выполняет обработку точки трассировки. В этом случае необходимо предусмотреть защиту от бесконечной рекурсии (обратите внимание, что нам пришлось отфильтровать собственные вызовы в обработчике :line, иначе он вызывал бы сам себя бесконечно).

new(*events) { |tp| block } → tp Показать исходный код
# File trace_point.rb, line 94
def self.new(*events)
  Primitive.attr! :use_block
  Primitive.tracepoint_new_s(events)
end

Возвращает новый объект TracePoint, по умолчанию отключённый.

Чтобы активировать объект TracePoint, используйте 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]
# ...

Чтобы отключить трассировку, используйте TracePoint#disable.

trace.disable

Список возможных событий и дополнительную информацию см. в разделе «События» в TracePoint.

Необходимо передать блок; в противном случае возникает исключение ArgumentError.

Если метод трассировки не входит в заданный фильтр событий, возникает исключение RuntimeError.

TracePoint.trace(:line) do |tp|
  p tp.raised_exception
end
#=> RuntimeError: 'raised_exception' not supported by this event

Если метод трассировки вызывается вне блока, возникает исключение RuntimeError.

TracePoint.trace(:line) do |tp|
  $tp = tp
end
$tp.lineno #=> access from outside (RuntimeError)

Доступ из других потоков также запрещён.

stat → obj Показать исходный код
# File trace_point.rb, line 117
def self.stat
  Primitive.tracepoint_stat_s
end

Возвращает внутреннюю информацию о TracePoint.

Содержимое возвращаемого значения зависит от реализации и может измениться в будущем.

Этот метод предназначен только для отладки самого TracePoint.

trace(*events) { |tp| block } → obj Показать исходный код
# File trace_point.rb, line 132
def self.trace(*events)
  Primitive.attr! :use_block
  Primitive.tracepoint_trace_s(events)
end

Удобный метод для вызова TracePoint.new, который автоматически активирует трассировку.

trace = TracePoint.trace(:call) { |tp| [tp.lineno, tp.event] }
#=> #<TracePoint:enabled>

trace.enabled?  #=> true

Общедоступные методы экземпляра

binding () Показать исходный код
# File trace_point.rb, line 381
def binding
  Primitive.tracepoint_attr_binding
end

Возвращает объект binding, созданный для события.

Обратите внимание: для событий :c_call и :c_return метод возвращает nil, поскольку у самих методов C нет объектов binding.

callee_id () Показать исходный код
# File trace_point.rb, line 337
def callee_id
  Primitive.tracepoint_attr_callee_id
end

Возвращает имя вызываемого метода.

defined_class () Показать исходный код
# File trace_point.rb, line 373
def defined_class
  Primitive.tracepoint_attr_defined_class
end

Возвращает класс или модуль, которому принадлежит вызываемый метод.

class C; def foo; end; end
trace = TracePoint.new(:call) do |tp|
  p tp.defined_class #=> C
end.enable do
  C.new.foo
end

Если метод определён в модуле, возвращается этот модуль.

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

Примечание: defined_class возвращает singleton-класс.

Шестой параметр блока в Kernel#set_trace_func передаёт исходный класс, связанный с singleton-классом.

Это различие между Kernel#set_trace_func и 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
disable → true or false Показать исходный код
disable { block } → obj
# File trace_point.rb, line 295
def disable
  Primitive.attr! :use_block
  Primitive.tracepoint_disable_m
end

Отключает трассировку.

Возвращает true, если трассировка была включена. Возвращает false, если трассировка была отключена.

trace.enabled?  #=> true
trace.disable   #=> true (previous status)
trace.enabled?  #=> false
trace.disable   #=> false

Если передан блок, трассировка будет отключена только на время выполнения блока.

trace.enabled?  #=> true

trace.disable do
  trace.enabled?
  # Only disabled for this block
end

trace.enabled?  #=> true

Примечание: внутри блока нельзя обращаться к хукам событий.

trace.disable { p tp.lineno }
#=> RuntimeError: access from outside
enable(target: nil, target_line: nil, target_thread: nil) → true or false Показать исходный код
enable(target: nil, target_line: nil, target_thread: :default) { block } → obj
# File trace_point.rb, line 259
def enable(target: nil, target_line: nil, target_thread: :default)
  Primitive.attr! :use_block
  Primitive.tracepoint_enable_m(target, target_line, target_thread)
end

Активирует трассировку.

Возвращает true, если трассировка была включена. Возвращает false, если трассировка была отключена.

trace.enabled?  #=> false
trace.enable    #=> false (previous state)
                #   trace is enabled
trace.enabled?  #=> true
trace.enable    #=> true (previous state)
                #   trace is still enabled

Если передан блок, трассировка будет включена только на время его выполнения. Если и target, и target_line равны nil, то при переданном блоке значением target_thread по умолчанию будет текущий поток.

trace.enabled?  #=> false

trace.enable do
  trace.enabled?
  # Only enabled for this block and thread
end

trace.enabled?  #=> false

Параметры target, target_line и target_thread используются, чтобы ограничить трассировку указанными объектами кода. target должен быть объектом кода, для которого RubyVM::InstructionSequence.of возвращает последовательность инструкций.

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

Примечание: внутри блока enable нельзя обращаться к хукам событий.

trace.enable { p tp.lineno }
#=> RuntimeError: access from outside
enabled? → true or false Показать исходный код
# File trace_point.rb, line 304
def enabled?
  Primitive.tracepoint_enabled_p
end

Возвращает текущее состояние трассировки.

eval_script () Показать исходный код
# File trace_point.rb, line 407
def eval_script
  Primitive.tracepoint_attr_eval_script
end

Возвращает скомпилированный исходный код (String) методов eval для события :script_compiled. Если код загружен из файла, возвращается nil.

event () Показать исходный код
# File trace_point.rb, line 311
def event
  Primitive.tracepoint_attr_event
end

Возвращает тип события.

Дополнительную информацию см. в разделе «События» в TracePoint.

inspect → string Показать исходный код
# File trace_point.rb, line 104
def inspect
  Primitive.tracepoint_inspect
end

Возвращает строку с понятным человеку описанием состояния TracePoint.

instruction_sequence () Показать исходный код
# File trace_point.rb, line 415
def instruction_sequence
  Primitive.tracepoint_attr_instruction_sequence
end

Возвращает скомпилированную последовательность инструкций, представленную экземпляром RubyVM::InstructionSequence, для события :script_compiled.

Обратите внимание, что этот метод специфичен для CRuby.

lineno () Показать исходный код
# File trace_point.rb, line 316
def lineno
  Primitive.tracepoint_attr_lineno
end

Возвращает номер строки события.

method_id () Показать исходный код
# File trace_point.rb, line 332
def method_id
  Primitive.tracepoint_attr_method_id
end

Возвращает имя метода в месте его определения.

parameters () Показать исходный код
# File trace_point.rb, line 327
def parameters
  Primitive.tracepoint_attr_parameters
end

Возвращает определения параметров метода или блока, к которому относится текущий хук. Формат совпадает с форматом Method#parameters.

path () Показать исходный код
# File trace_point.rb, line 321
def path
  Primitive.tracepoint_attr_path
end

Возвращает путь к выполняемому файлу.

raised_exception () Показать исходный код
# File trace_point.rb, line 401
def raised_exception
  Primitive.tracepoint_attr_raised_exception
end

Возвращает исключение, возбужденное при событии :raise или перехваченное при событии :rescue.

return_value () Показать исходный код
# File trace_point.rb, line 396
def return_value
  Primitive.tracepoint_attr_return_value
end

Возвращает значение, полученное при событиях :return, :c_return и :b_return.

self () Показать исходный код
# File trace_point.rb, line 391
def self
  Primitive.tracepoint_attr_self
end

Возвращает объект трассировки во время события.

Аналогично следующему коду, но для событий :c_call и :c_return возвращает правильный объект (получатель метода):

trace.binding.eval('self')

Ruby Core © 1993–2025 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API