зеркало из https://github.com/github/ruby.git
Removed tracer from ruby repo
This commit is contained in:
Родитель
274d0aa768
Коммит
ab3266ea5c
|
@ -277,10 +277,6 @@ Yukihiro Matsumoto (matz)
|
|||
_unmaintained_
|
||||
https://github.com/ruby/tmpdir
|
||||
https://rubygems.org/gems/tmpdir
|
||||
[lib/tracer.rb]
|
||||
Keiju ISHITSUKA (keiju)
|
||||
https://github.com/ruby/tracer
|
||||
https://rubygems.org/gems/tracer
|
||||
[lib/tsort.rb]
|
||||
Tanaka Akira (akr)
|
||||
https://github.com/ruby/tsort
|
||||
|
|
|
@ -72,7 +72,6 @@ Tempfile:: A utility class for managing temporary files
|
|||
Time:: Extends the Time class with methods for parsing and conversion
|
||||
Timeout:: Auto-terminate potentially long-running operations in Ruby
|
||||
tmpdir.rb:: Extends the Dir class to manage the OS temporary file path
|
||||
Tracer:: Outputs a source level execution trace of a Ruby program
|
||||
TSort:: Topological sorting using Tarjan's algorithm
|
||||
un.rb:: Utilities to replace common UNIX commands
|
||||
URI:: A Ruby module providing support for Uniform Resource Identifiers
|
||||
|
|
292
lib/tracer.rb
292
lib/tracer.rb
|
@ -1,292 +0,0 @@
|
|||
# frozen_string_literal: false
|
||||
#--
|
||||
# $Release Version: 0.3$
|
||||
# $Revision: 1.12 $
|
||||
|
||||
##
|
||||
# Outputs a source level execution trace of a Ruby program.
|
||||
#
|
||||
# It does this by registering an event handler with Kernel#set_trace_func for
|
||||
# processing incoming events. It also provides methods for filtering unwanted
|
||||
# trace output (see Tracer.add_filter, Tracer.on, and Tracer.off).
|
||||
#
|
||||
# == Example
|
||||
#
|
||||
# Consider the following Ruby script
|
||||
#
|
||||
# class A
|
||||
# def square(a)
|
||||
# return a*a
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# a = A.new
|
||||
# a.square(5)
|
||||
#
|
||||
# Running the above script using <code>ruby -r tracer example.rb</code> will
|
||||
# output the following trace to STDOUT (Note you can also explicitly
|
||||
# <code>require 'tracer'</code>)
|
||||
#
|
||||
# #0:<internal:lib/rubygems/custom_require>:38:Kernel:<: -
|
||||
# #0:example.rb:3::-: class A
|
||||
# #0:example.rb:3::C: class A
|
||||
# #0:example.rb:4::-: def square(a)
|
||||
# #0:example.rb:7::E: end
|
||||
# #0:example.rb:9::-: a = A.new
|
||||
# #0:example.rb:10::-: a.square(5)
|
||||
# #0:example.rb:4:A:>: def square(a)
|
||||
# #0:example.rb:5:A:-: return a*a
|
||||
# #0:example.rb:6:A:<: end
|
||||
# | | | | |
|
||||
# | | | | ---------------------+ event
|
||||
# | | | ------------------------+ class
|
||||
# | | --------------------------+ line
|
||||
# | ------------------------------------+ filename
|
||||
# ---------------------------------------+ thread
|
||||
#
|
||||
# Symbol table used for displaying incoming events:
|
||||
#
|
||||
# +}+:: call a C-language routine
|
||||
# +{+:: return from a C-language routine
|
||||
# +>+:: call a Ruby method
|
||||
# +C+:: start a class or module definition
|
||||
# +E+:: finish a class or module definition
|
||||
# +-+:: execute code on a new line
|
||||
# +^+:: raise an exception
|
||||
# +<+:: return from a Ruby method
|
||||
#
|
||||
# == Copyright
|
||||
#
|
||||
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
||||
#
|
||||
class Tracer
|
||||
VERSION = "0.1.1"
|
||||
|
||||
class << self
|
||||
# display additional debug information (defaults to false)
|
||||
attr_accessor :verbose
|
||||
alias verbose? verbose
|
||||
|
||||
# output stream used to output trace (defaults to STDOUT)
|
||||
attr_accessor :stdout
|
||||
|
||||
# mutex lock used by tracer for displaying trace output
|
||||
attr_reader :stdout_mutex
|
||||
|
||||
# display process id in trace output (defaults to false)
|
||||
attr_accessor :display_process_id
|
||||
alias display_process_id? display_process_id
|
||||
|
||||
# display thread id in trace output (defaults to true)
|
||||
attr_accessor :display_thread_id
|
||||
alias display_thread_id? display_thread_id
|
||||
|
||||
# display C-routine calls in trace output (defaults to false)
|
||||
attr_accessor :display_c_call
|
||||
alias display_c_call? display_c_call
|
||||
end
|
||||
|
||||
Tracer::stdout = STDOUT
|
||||
Tracer::verbose = false
|
||||
Tracer::display_process_id = false
|
||||
Tracer::display_thread_id = true
|
||||
Tracer::display_c_call = false
|
||||
|
||||
@stdout_mutex = Thread::Mutex.new
|
||||
|
||||
# Symbol table used for displaying trace information
|
||||
EVENT_SYMBOL = {
|
||||
"line" => "-",
|
||||
"call" => ">",
|
||||
"return" => "<",
|
||||
"class" => "C",
|
||||
"end" => "E",
|
||||
"raise" => "^",
|
||||
"c-call" => "}",
|
||||
"c-return" => "{",
|
||||
"unknown" => "?"
|
||||
}
|
||||
|
||||
def initialize # :nodoc:
|
||||
@threads = Hash.new
|
||||
if defined? Thread.main
|
||||
@threads[Thread.main.object_id] = 0
|
||||
else
|
||||
@threads[Thread.current.object_id] = 0
|
||||
end
|
||||
|
||||
@get_line_procs = {}
|
||||
|
||||
@filters = []
|
||||
end
|
||||
|
||||
def stdout # :nodoc:
|
||||
Tracer.stdout
|
||||
end
|
||||
|
||||
def on # :nodoc:
|
||||
if block_given?
|
||||
on
|
||||
begin
|
||||
yield
|
||||
ensure
|
||||
off
|
||||
end
|
||||
else
|
||||
set_trace_func method(:trace_func).to_proc
|
||||
stdout.print "Trace on\n" if Tracer.verbose?
|
||||
end
|
||||
end
|
||||
|
||||
def off # :nodoc:
|
||||
set_trace_func nil
|
||||
stdout.print "Trace off\n" if Tracer.verbose?
|
||||
end
|
||||
|
||||
def add_filter(p = nil, &b) # :nodoc:
|
||||
p ||= b
|
||||
@filters.push p
|
||||
end
|
||||
|
||||
def set_get_line_procs(file, p = nil, &b) # :nodoc:
|
||||
p ||= b
|
||||
@get_line_procs[file] = p
|
||||
end
|
||||
|
||||
def get_line(file, line) # :nodoc:
|
||||
if p = @get_line_procs[file]
|
||||
return p.call(line)
|
||||
end
|
||||
|
||||
unless list = SCRIPT_LINES__[file]
|
||||
list = File.readlines(file) rescue []
|
||||
SCRIPT_LINES__[file] = list
|
||||
end
|
||||
|
||||
if l = list[line - 1]
|
||||
l
|
||||
else
|
||||
"-\n"
|
||||
end
|
||||
end
|
||||
|
||||
def get_thread_no # :nodoc:
|
||||
if no = @threads[Thread.current.object_id]
|
||||
no
|
||||
else
|
||||
@threads[Thread.current.object_id] = @threads.size
|
||||
end
|
||||
end
|
||||
|
||||
def trace_func(event, file, line, id, binding, klass, *) # :nodoc:
|
||||
return if file == __FILE__
|
||||
|
||||
for p in @filters
|
||||
return unless p.call event, file, line, id, binding, klass
|
||||
end
|
||||
|
||||
return unless Tracer::display_c_call? or
|
||||
event != "c-call" && event != "c-return"
|
||||
|
||||
Tracer::stdout_mutex.synchronize do
|
||||
if EVENT_SYMBOL[event]
|
||||
stdout.printf("<%d>", $$) if Tracer::display_process_id?
|
||||
stdout.printf("#%d:", get_thread_no) if Tracer::display_thread_id?
|
||||
if line == 0
|
||||
source = "?\n"
|
||||
else
|
||||
source = get_line(file, line)
|
||||
end
|
||||
stdout.printf("%s:%d:%s:%s: %s",
|
||||
file,
|
||||
line,
|
||||
klass || '',
|
||||
EVENT_SYMBOL[event],
|
||||
source)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Reference to singleton instance of Tracer
|
||||
Single = new
|
||||
|
||||
##
|
||||
# Start tracing
|
||||
#
|
||||
# === Example
|
||||
#
|
||||
# Tracer.on
|
||||
# # code to trace here
|
||||
# Tracer.off
|
||||
#
|
||||
# You can also pass a block:
|
||||
#
|
||||
# Tracer.on {
|
||||
# # trace everything in this block
|
||||
# }
|
||||
|
||||
def Tracer.on
|
||||
if block_given?
|
||||
Single.on{yield}
|
||||
else
|
||||
Single.on
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Disable tracing
|
||||
|
||||
def Tracer.off
|
||||
Single.off
|
||||
end
|
||||
|
||||
##
|
||||
# Register an event handler <code>p</code> which is called every time a line
|
||||
# in +file_name+ is executed.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# Tracer.set_get_line_procs("example.rb", lambda { |line|
|
||||
# puts "line number executed is #{line}"
|
||||
# })
|
||||
|
||||
def Tracer.set_get_line_procs(file_name, p = nil, &b)
|
||||
p ||= b
|
||||
Single.set_get_line_procs(file_name, p)
|
||||
end
|
||||
|
||||
##
|
||||
# Used to filter unwanted trace output
|
||||
#
|
||||
# Example which only outputs lines of code executed within the Kernel class:
|
||||
#
|
||||
# Tracer.add_filter do |event, file, line, id, binding, klass, *rest|
|
||||
# "Kernel" == klass.to_s
|
||||
# end
|
||||
|
||||
def Tracer.add_filter(p = nil, &b)
|
||||
p ||= b
|
||||
Single.add_filter(p)
|
||||
end
|
||||
end
|
||||
|
||||
# :stopdoc:
|
||||
SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
|
||||
|
||||
if $0 == __FILE__
|
||||
# direct call
|
||||
|
||||
$0 = ARGV[0]
|
||||
ARGV.shift
|
||||
Tracer.on
|
||||
require $0
|
||||
else
|
||||
# call Tracer.on only if required by -r command-line option
|
||||
count = caller.count {|bt| %r%/rubygems/core_ext/kernel_require\.rb:% !~ bt}
|
||||
if (defined?(Gem) and count == 0) or
|
||||
(!defined?(Gem) and count <= 1)
|
||||
Tracer.on
|
||||
end
|
||||
end
|
||||
# :startdoc:
|
|
@ -1,25 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
name = File.basename(__FILE__, ".gemspec")
|
||||
version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
|
||||
break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
|
||||
/^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
|
||||
end rescue nil
|
||||
end
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = name
|
||||
spec.version = version
|
||||
spec.authors = ["Keiju ISHITSUKA"]
|
||||
spec.email = ["keiju@ruby-lang.org"]
|
||||
|
||||
spec.summary = %q{Outputs a source level execution trace of a Ruby program.}
|
||||
spec.description = %q{Outputs a source level execution trace of a Ruby program.}
|
||||
spec.homepage = "https://github.com/ruby/tracer"
|
||||
spec.licenses = ["Ruby", "BSD-2-Clause"]
|
||||
|
||||
spec.files = ["Gemfile", "LICENSE.txt", "README.md", "Rakefile", "lib/tracer.rb", "tracer.gemspec"]
|
||||
spec.bindir = "exe"
|
||||
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
||||
spec.require_paths = ["lib"]
|
||||
end
|
|
@ -1,234 +0,0 @@
|
|||
# frozen_string_literal: false
|
||||
require 'test/unit'
|
||||
require 'tmpdir'
|
||||
|
||||
class TestTracer < Test::Unit::TestCase
|
||||
include EnvUtil
|
||||
|
||||
def test_tracer_with_option_r
|
||||
assert_in_out_err(%w[-rtracer -e 1]) do |(*lines),|
|
||||
case lines.size
|
||||
when 1
|
||||
# do nothing
|
||||
else
|
||||
assert_match(%r{rubygems/core_ext/kernel_require\.rb:\d+:Kernel:<:}, lines[0])
|
||||
end
|
||||
assert_equal "#0:-e:1::-: 1", lines.last
|
||||
end
|
||||
end
|
||||
|
||||
def test_tracer_with_option_r_without_gems
|
||||
assert_in_out_err(%w[--disable-gems -rtracer -e 1]) do |(*lines),|
|
||||
assert_equal 1, lines.size, "unexpected output from `ruby --disable-gems -rtracer -e 1`"
|
||||
assert_equal "#0:-e:1::-: 1", lines.last
|
||||
end
|
||||
end
|
||||
|
||||
def test_tracer_with_require
|
||||
Dir.mktmpdir("test_ruby_tracer") do |dir|
|
||||
script = File.join(dir, "require_tracer.rb")
|
||||
open(script, "w") do |f|
|
||||
f.print <<-EOF
|
||||
require 'tracer'
|
||||
1
|
||||
EOF
|
||||
end
|
||||
assert_in_out_err([script]) do |(*lines),|
|
||||
assert_empty(lines)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_tracer_with_require_without_gems
|
||||
Dir.mktmpdir("test_ruby_tracer") do |dir|
|
||||
script = File.join(dir, "require_tracer.rb")
|
||||
open(script, "w") do |f|
|
||||
f.print <<-EOF
|
||||
require 'tracer'
|
||||
1
|
||||
EOF
|
||||
end
|
||||
assert_in_out_err(["--disable-gems", script]) do |(*lines),|
|
||||
assert_empty(lines)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_tracer_by_add_filter_with_block
|
||||
Dir.mktmpdir("test_ruby_tracer") do |dir|
|
||||
script = File.join(dir, "require_tracer.rb")
|
||||
open(script, "w") do |f|
|
||||
f.print <<-'EOF'
|
||||
require 'tracer'
|
||||
|
||||
class Hoge
|
||||
def Hoge.fuga(i)
|
||||
"fuga #{i}"
|
||||
end
|
||||
end
|
||||
|
||||
Tracer.add_filter {|event, file, line, id, binding, klass|
|
||||
event =~ /line/ and klass.to_s =~ /hoge/i
|
||||
}
|
||||
Tracer.on
|
||||
for i in 0..3
|
||||
puts Hoge.fuga(i) if i % 3 == 0
|
||||
end
|
||||
Tracer.off
|
||||
EOF
|
||||
end
|
||||
assert_in_out_err([script]) do |(*lines), err|
|
||||
expected = [
|
||||
"#0:#{script}:5:Hoge:-: \"fuga \#{i}\"",
|
||||
"fuga 0",
|
||||
"#0:#{script}:5:Hoge:-: \"fuga \#{i}\"",
|
||||
"fuga 3"
|
||||
]
|
||||
assert_equal(expected, lines)
|
||||
assert_empty(err)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_tracer_by_add_filter_with_proc
|
||||
Dir.mktmpdir("test_ruby_tracer") do |dir|
|
||||
script = File.join(dir, "require_tracer.rb")
|
||||
open(script, "w") do |f|
|
||||
f.print <<-'EOF'
|
||||
require 'tracer'
|
||||
|
||||
class Hoge
|
||||
def Hoge.fuga(i)
|
||||
"fuga #{i}"
|
||||
end
|
||||
end
|
||||
|
||||
a_proc_to_add_filter = proc {|event, file, line, id, binding, klass|
|
||||
event =~ /line/ and klass.to_s =~ /hoge/i
|
||||
}
|
||||
Tracer.add_filter(a_proc_to_add_filter)
|
||||
Tracer.on
|
||||
for i in 0..3
|
||||
puts Hoge.fuga(i) if i % 3 == 0
|
||||
end
|
||||
Tracer.off
|
||||
EOF
|
||||
end
|
||||
assert_in_out_err([script]) do |(*lines), err|
|
||||
expected = [
|
||||
"#0:#{script}:5:Hoge:-: \"fuga \#{i}\"",
|
||||
"fuga 0",
|
||||
"#0:#{script}:5:Hoge:-: \"fuga \#{i}\"",
|
||||
"fuga 3"
|
||||
]
|
||||
assert_equal(expected, lines)
|
||||
assert_empty(err)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_tracer_by_set_get_line_procs_with_block
|
||||
Dir.mktmpdir("test_ruby_tracer") do |dir|
|
||||
dummy_script = File.join(dir, "dummy.rb")
|
||||
open(dummy_script, "w") do |f|
|
||||
f.print <<-'EOF'
|
||||
class Dummy
|
||||
def initialize
|
||||
@number = 135
|
||||
end
|
||||
attr :number
|
||||
end
|
||||
EOF
|
||||
end
|
||||
dummy_script = File.realpath dummy_script
|
||||
script = File.join(dir, "require_tracer.rb")
|
||||
open(script, "w") do |f|
|
||||
f.print <<-EOF
|
||||
require 'tracer'
|
||||
|
||||
Tracer.set_get_line_procs('#{dummy_script}') { |line|
|
||||
str = %{\\n}
|
||||
str = %{!!\\n} if line >= 3 and line <= 6
|
||||
str
|
||||
}
|
||||
Tracer.on
|
||||
require_relative 'dummy'
|
||||
|
||||
dm = Dummy.new
|
||||
puts dm.number
|
||||
EOF
|
||||
end
|
||||
assert_in_out_err([script]) do |(*lines), err|
|
||||
expected = [
|
||||
"#0:#{script}:9::-: require_relative 'dummy'",
|
||||
"#0:#{dummy_script}:1::-: ",
|
||||
"#0:#{dummy_script}:1::C: ",
|
||||
"#0:#{dummy_script}:2::-: ",
|
||||
"#0:#{dummy_script}:5::-: !!",
|
||||
"#0:#{dummy_script}:6::E: !!",
|
||||
"#0:#{script}:11::-: dm = Dummy.new",
|
||||
"#0:#{dummy_script}:2:Dummy:>: ",
|
||||
"#0:#{dummy_script}:3:Dummy:-: !!",
|
||||
"#0:#{dummy_script}:4:Dummy:<: !!",
|
||||
"#0:#{script}:12::-: puts dm.number",
|
||||
"135"
|
||||
]
|
||||
assert_equal(expected, lines)
|
||||
assert_empty(err)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_tracer_by_set_get_line_procs_with_proc
|
||||
Dir.mktmpdir("test_ruby_tracer") do |dir|
|
||||
dummy_script = File.join(dir, "dummy.rb")
|
||||
open(dummy_script, "w") do |f|
|
||||
f.print <<-'EOF'
|
||||
class Dummy
|
||||
def initialize
|
||||
@number = 135
|
||||
end
|
||||
attr :number
|
||||
end
|
||||
EOF
|
||||
end
|
||||
dummy_script = File.realpath dummy_script
|
||||
script = File.join(dir, "require_tracer.rb")
|
||||
open(script, "w") do |f|
|
||||
f.print <<-EOF
|
||||
require 'tracer'
|
||||
|
||||
a_proc_to_set_get_line_procs = proc { |line|
|
||||
str = %{\\n}
|
||||
str = %{!!\\n} if line >= 3 and line <= 6
|
||||
str
|
||||
}
|
||||
Tracer.set_get_line_procs('#{dummy_script}', a_proc_to_set_get_line_procs)
|
||||
Tracer.on
|
||||
require_relative 'dummy'
|
||||
|
||||
dm = Dummy.new
|
||||
puts dm.number
|
||||
EOF
|
||||
end
|
||||
assert_in_out_err([script]) do |(*lines), err|
|
||||
expected = [
|
||||
"#0:#{script}:10::-: require_relative 'dummy'",
|
||||
"#0:#{dummy_script}:1::-: ",
|
||||
"#0:#{dummy_script}:1::C: ",
|
||||
"#0:#{dummy_script}:2::-: ",
|
||||
"#0:#{dummy_script}:5::-: !!",
|
||||
"#0:#{dummy_script}:6::E: !!",
|
||||
"#0:#{script}:12::-: dm = Dummy.new",
|
||||
"#0:#{dummy_script}:2:Dummy:>: ",
|
||||
"#0:#{dummy_script}:3:Dummy:-: !!",
|
||||
"#0:#{dummy_script}:4:Dummy:<: !!",
|
||||
"#0:#{script}:13::-: puts dm.number",
|
||||
"135"
|
||||
]
|
||||
assert_equal(expected, lines)
|
||||
assert_empty(err)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -29,7 +29,6 @@ REPOSITORIES = {
|
|||
matrix: 'ruby/matrix',
|
||||
ostruct: 'ruby/ostruct',
|
||||
irb: 'ruby/irb',
|
||||
tracer: 'ruby/tracer',
|
||||
forwardable: "ruby/forwardable",
|
||||
mutex_m: "ruby/mutex_m",
|
||||
racc: "ruby/racc",
|
||||
|
|
Загрузка…
Ссылка в новой задаче