|
1 | | -#!/usr/bin/env ruby |
2 | 1 | # SPDX-License-Identifier: MIT |
3 | | -# Simple utility loading the native tracer extension and executing a program. |
| 2 | +# Library providing a helper method to execute the native tracer. |
4 | 3 |
|
5 | 4 | require 'optparse' |
6 | 5 | require 'fileutils' |
7 | 6 | require 'rbconfig' |
8 | 7 |
|
9 | | -options = {} |
10 | | -parser = OptionParser.new do |opts| |
11 | | - opts.banner = "usage: ruby native_trace.rb [options] <program> [args]" |
12 | | - opts.on('-o DIR', '--out-dir DIR', 'Directory to write trace files') do |dir| |
13 | | - options[:out_dir] = dir |
14 | | - end |
15 | | - opts.on('-h', '--help', 'Print this help') do |
16 | | - puts opts |
17 | | - exit |
18 | | - end |
19 | | -end |
20 | | -parser.order! |
| 8 | +module NativeTrace |
| 9 | + # Execute the native tracer CLI logic with the provided +argv+. |
| 10 | + def self.execute(argv) |
| 11 | + options = {} |
| 12 | + parser = OptionParser.new do |opts| |
| 13 | + opts.banner = 'usage: codetracer-ruby-recorder [options] <program> [args]' |
| 14 | + opts.on('-o DIR', '--out-dir DIR', 'Directory to write trace files') do |dir| |
| 15 | + options[:out_dir] = dir |
| 16 | + end |
| 17 | + opts.on('-h', '--help', 'Print this help') do |
| 18 | + puts opts |
| 19 | + return 0 |
| 20 | + end |
| 21 | + end |
| 22 | + parser.order!(argv) |
21 | 23 |
|
22 | | -if ARGV.empty? |
23 | | - $stderr.puts parser |
24 | | - exit 1 |
25 | | -end |
| 24 | + if argv.empty? |
| 25 | + $stderr.puts parser |
| 26 | + return 1 |
| 27 | + end |
26 | 28 |
|
27 | | -out_dir = options[:out_dir] || ENV['CODETRACER_RUBY_RECORDER_OUT_DIR'] || Dir.pwd |
28 | | -ENV['CODETRACER_RUBY_RECORDER_OUT_DIR'] = out_dir |
| 29 | + out_dir = options[:out_dir] || ENV['CODETRACER_RUBY_RECORDER_OUT_DIR'] || Dir.pwd |
| 30 | + ENV['CODETRACER_RUBY_RECORDER_OUT_DIR'] = out_dir |
29 | 31 |
|
30 | | -# Path to the compiled native extension |
31 | | -ext_dir = File.expand_path('../ext/native_tracer/target/release', __dir__) |
32 | | -dlext = RbConfig::CONFIG['DLEXT'] |
33 | | -target_path = File.join(ext_dir, "codetracer_ruby_recorder.#{dlext}") |
34 | | -unless File.exist?(target_path) |
35 | | - extensions = %w[so bundle dylib dll] |
36 | | - alt_path = extensions |
37 | | - .map { |ext| File.join(ext_dir, "libcodetracer_ruby_recorder.#{ext}") } |
38 | | - .find { |path| File.exist?(path) } |
39 | | - if alt_path |
40 | | - begin |
41 | | - File.symlink(alt_path, target_path) |
42 | | - rescue StandardError |
43 | | - FileUtils.cp(alt_path, target_path) |
| 32 | + ext_dir = File.expand_path('../ext/native_tracer/target/release', __dir__) |
| 33 | + dlext = RbConfig::CONFIG['DLEXT'] |
| 34 | + target_path = File.join(ext_dir, "codetracer_ruby_recorder.#{dlext}") |
| 35 | + unless File.exist?(target_path) |
| 36 | + extensions = %w[so bundle dylib dll] |
| 37 | + alt_path = extensions |
| 38 | + .map { |ext| File.join(ext_dir, "libcodetracer_ruby_recorder.#{ext}") } |
| 39 | + .find { |path| File.exist?(path) } |
| 40 | + if alt_path |
| 41 | + begin |
| 42 | + File.symlink(alt_path, target_path) |
| 43 | + rescue StandardError |
| 44 | + FileUtils.cp(alt_path, target_path) |
| 45 | + end |
| 46 | + end |
44 | 47 | end |
45 | | - end |
46 | | -end |
47 | 48 |
|
48 | | -recorder = nil |
49 | | -begin |
50 | | - require target_path |
51 | | - recorder = RubyRecorder.new |
52 | | - $recorder = recorder |
| 49 | + recorder = nil |
| 50 | + begin |
| 51 | + require target_path |
| 52 | + recorder = RubyRecorder.new |
| 53 | + $recorder = recorder |
53 | 54 |
|
54 | | - module Kernel |
55 | | - alias :old_p :p |
56 | | - alias :old_puts :puts |
57 | | - alias :old_print :print |
| 55 | + Kernel.module_eval do |
| 56 | + alias :old_p :p |
| 57 | + alias :old_puts :puts |
| 58 | + alias :old_print :print |
58 | 59 |
|
59 | | - def p(*args) |
60 | | - if $recorder |
61 | | - loc = caller_locations(1,1).first |
62 | | - $recorder.record_event(loc.path, loc.lineno, args.join("\n")) |
63 | | - end |
64 | | - old_p(*args) |
65 | | - end |
| 60 | + define_method(:p) do |*args| |
| 61 | + if $recorder |
| 62 | + loc = caller_locations(1,1).first |
| 63 | + $recorder.record_event(loc.path, loc.lineno, args.join("\n")) |
| 64 | + end |
| 65 | + old_p(*args) |
| 66 | + end |
66 | 67 |
|
67 | | - def puts(*args) |
68 | | - if $recorder |
69 | | - loc = caller_locations(1,1).first |
70 | | - $recorder.record_event(loc.path, loc.lineno, args.join("\n")) |
| 68 | + define_method(:puts) do |*args| |
| 69 | + if $recorder |
| 70 | + loc = caller_locations(1,1).first |
| 71 | + $recorder.record_event(loc.path, loc.lineno, args.join("\n")) |
| 72 | + end |
| 73 | + old_puts(*args) |
| 74 | + end |
| 75 | + |
| 76 | + define_method(:print) do |*args| |
| 77 | + if $recorder |
| 78 | + loc = caller_locations(1,1).first |
| 79 | + $recorder.record_event(loc.path, loc.lineno, args.join("\n")) |
| 80 | + end |
| 81 | + old_print(*args) |
| 82 | + end |
71 | 83 | end |
72 | | - old_puts(*args) |
| 84 | + rescue Exception => e |
| 85 | + warn "native tracer unavailable: #{e}" |
73 | 86 | end |
74 | 87 |
|
75 | | - def print(*args) |
76 | | - if $recorder |
77 | | - loc = caller_locations(1,1).first |
78 | | - $recorder.record_event(loc.path, loc.lineno, args.join("\n")) |
79 | | - end |
80 | | - old_print(*args) |
| 88 | + program = argv.shift |
| 89 | + recorder.enable_tracing if recorder |
| 90 | + load program |
| 91 | + if recorder |
| 92 | + recorder.disable_tracing |
| 93 | + recorder.flush_trace(out_dir) |
81 | 94 | end |
| 95 | + 0 |
82 | 96 | end |
83 | | - |
84 | | -rescue Exception => e |
85 | | - warn "native tracer unavailable: #{e}" |
86 | 97 | end |
87 | 98 |
|
88 | | -program = ARGV.shift |
89 | | -recorder.enable_tracing if recorder |
90 | | -load program |
91 | | -if recorder |
92 | | - recorder.disable_tracing |
93 | | - recorder.flush_trace(out_dir) |
94 | | -end |
95 | 99 |
|
0 commit comments