rookout 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,6 +3,8 @@ module Rookout
3
3
  module Operations
4
4
  require_relative "operation"
5
5
 
6
+ require_relative "../namespaces/ruby_object_namespace"
7
+
6
8
  require_relative "../rook_error"
7
9
  require_relative "../../logger"
8
10
  require_relative "../../user_warnings"
@@ -29,7 +31,8 @@ module Rookout
29
31
  @paths.each do |dest_path, source_path|
30
32
  begin
31
33
  value = source_path.read_from namespace
32
- if value.is_a?(RubyObjectNamespace) && value.dump_config == Namespaces::OBJECT_DUMP_CONFIG_DEFAULT
34
+ if value.is_a?(Namespaces::RubyObjectNamespace) &&
35
+ value.dump_config == Namespaces::OBJECT_DUMP_CONFIG_DEFAULT
33
36
  value.tailor_limits!
34
37
  end
35
38
 
@@ -71,7 +71,7 @@ module Rookout
71
71
 
72
72
  if result.is_a? Canopy::ToolExceptionMarker
73
73
  raise result.obj if result.obj.is_a? Exceptions::ToolException
74
- raise Exceptions::RookInvalidArithmeticPath, @raw_path, result.obj
74
+ raise Exceptions::RookInvalidArithmeticPath.new(@raw_path, result.obj)
75
75
  end
76
76
 
77
77
  res = result.obj
@@ -4,6 +4,9 @@ module Rookout
4
4
  module Canopy
5
5
  require_relative "consts"
6
6
 
7
+ require_relative "../../../exceptions"
8
+ require_relative "../../namespaces/container_namespace"
9
+
7
10
  class Marker; end
8
11
 
9
12
  class Operation < Marker
@@ -12,7 +15,7 @@ module Rookout
12
15
  end
13
16
 
14
17
  def write _namespace, _value
15
- raise Exception.RookOperationReadOnly, self.class.to_s
18
+ raise Exception::RookOperationReadOnly, self.class.to_s
16
19
  end
17
20
  end
18
21
 
@@ -36,7 +39,7 @@ module Rookout
36
39
  namespace.read_attribute @name
37
40
  rescue Exceptions::RookAttributeNotFound
38
41
  raise unless create
39
- namespace.write_attribute name, ContainerNamespace.new
42
+ namespace.write_attribute @name, Namespaces::ContainerNamespace.new
40
43
  end
41
44
 
42
45
  def write namespace, value
@@ -40,7 +40,7 @@ module Rookout
40
40
  @services_started = false
41
41
  end
42
42
 
43
- def connect token, host, port, proxy, labels, async_start, _fork
43
+ def connect token: nil, host: nil, port: nil, proxy: nil, labels: [], async_start: false, **_
44
44
  raise Exceptions::RookInterfaceException, "Multiple connection attempts not supported!" unless @agent_com.nil?
45
45
 
46
46
  start_trigger_services
@@ -48,6 +48,7 @@ module Rookout
48
48
  Logger.instance.debug "Initiating AgentCom-\t#{host}:#{port}"
49
49
 
50
50
  @agent_com = ComWs::AgentComWs.new @output, host, port, proxy, token, labels
51
+ @output.agent_com = @agent_com
51
52
  @command_handler = ComWs::CommandHandler.new @agent_com, @aug_manager
52
53
 
53
54
  @agent_com.connect
@@ -65,8 +66,8 @@ module Rookout
65
66
  private
66
67
 
67
68
  def check_version_supported
68
- raise Exceptions:: RookVersionNotSupported, "platform", RUBY_ENGINE unless RUBY_ENGINE == "ruby"
69
- raise Exceptions::RookVersionNotSupported, "version", RUBY_VERSION unless
69
+ raise Exceptions:: RookVersionNotSupported.new("platform", RUBY_ENGINE) unless RUBY_ENGINE == "ruby"
70
+ raise Exceptions::RookVersionNotSupported.new("version", RUBY_VERSION) unless
70
71
  RUBY_VERSION.start_with?("2.7") || RUBY_VERSION.start_with?("2.6")
71
72
  end
72
73
  end
@@ -1,5 +1,7 @@
1
1
  module Rookout
2
2
  module Services
3
+ require "zlib"
4
+
3
5
  require_relative "../logger"
4
6
  require_relative "../exceptions"
5
7
 
@@ -16,10 +18,16 @@ module Rookout
16
18
  def initialize tracer
17
19
  @tracer = tracer
18
20
  @augs = {}
21
+ @iseqs = {}
19
22
  @trace_point = TracePoint.new :script_compiled do |tp|
20
23
  begin
21
24
  begin
22
- evaluate_script tp.instruction_sequence
25
+ iseq = tp.instruction_sequence
26
+ # Ignore script without sources
27
+ if iseq.absolute_path
28
+ @iseqs[tp.path] = iseq
29
+ evaluate_script iseq
30
+ end
23
31
  rescue Exception => e
24
32
  Logger.instance.exception "Exception while evaluating script", e
25
33
  end
@@ -30,22 +38,18 @@ module Rookout
30
38
  @trace_point.enable
31
39
  end
32
40
 
33
- def add_aug location, aug
34
- positions = resolve_positions location, aug
35
- if positions.empty?
36
- @augs[aug.id] = [location, aug]
37
- else
38
- @tracer.add_breakpoint_aug positions, aug
39
- end
41
+ def add_aug location
42
+ positions = evaluate_all_scripts_to_location location
43
+ @tracer.add_breakpoint_aug positions, location unless positions.empty?
44
+ @augs[location.id] = location
40
45
  end
41
46
 
42
47
  def remove_aug aug_id
43
- pair = @augs[aug_id]
44
- return if pair.nil?
48
+ location = @augs[aug_id]
49
+ return if location.nil?
45
50
 
46
51
  @augs.delete [aug_id]
47
- aug = pair[1]
48
- aug.notify_removed
52
+ location.notify_removed
49
53
  end
50
54
 
51
55
  def clear_augs
@@ -64,88 +68,47 @@ module Rookout
64
68
  private
65
69
 
66
70
  #########################################################################################
67
- # Dynamic Loading Section
71
+ # ISEQ comparison Section
68
72
  def evaluate_script iseq
69
73
  filename = iseq.absolute_path
70
74
  return if filename.nil?
71
75
 
72
- @augs.each do |pair|
73
- location = pair[0]
76
+ @augs.each_value do |location|
77
+ position = evaluate_script_to_location iseq, filename, location
78
+ next if position.nil?
74
79
 
75
- if exact_match? location, filename
76
- # TODO: CHECK FILE AND LINE HASH COMPARED TO AUG
77
- position = PositionMarker.new iseq.absolute_path, location.lineno, iseq
78
- @tracer.add_breakpoint_aug [position], pair[1]
79
- elsif suggested_match? location, filename
80
- warning = Exceptions::RookSourceFilePathSuggestion.new location.filename, filename
81
- pair[1].notify_warning warning
82
- end
80
+ @tracer.add_breakpoint_aug [position], location
83
81
  end
84
82
  end
85
83
 
86
- #########################################################################################
87
- # Enumerating Section
88
- def resolve_positions location, aug
89
- # TODO: ADD HASHES AND SUGGESTIONS TO THIS FLOW
84
+ def evaluate_all_scripts_to_location location
90
85
  positions = []
86
+ @iseqs.each_value do |iseq|
87
+ position = evaluate_script_to_location iseq, iseq.absolute_path, location
88
+ next if position.nil?
91
89
 
92
- ObjectSpace.each_object Module do |mod|
93
- positions += scan_module_or_class mod, location, aug
94
- end
95
-
96
- ObjectSpace.each_object Class do |klass|
97
- positions += scan_module_or_class klass, location, aug
90
+ positions << position
98
91
  end
99
92
 
100
93
  positions
101
94
  end
102
95
 
103
- def scan_module_or_class mod, location, aug
104
- positions = []
105
-
106
- mod.instance_methods(false).each do |method_name|
107
- method = mod.instance_method method_name
108
- next unless method_match? method, location, aug
109
-
110
- position = PositionMarker.new location.lineno, method
111
- positions.push position
112
- end
113
-
114
- mod.private_instance_methods(false).each do |method_name|
115
- method = mod.instance_method method_name
116
- next unless method_match? method, location, aug
96
+ def evaluate_script_to_location iseq, filename, location
97
+ if exact_match? location.filename, filename
98
+ lineno = find_updated_line filename, location
99
+ return if lineno == -1
117
100
 
118
- position = PositionMarker.new location.lineno, method
119
- positions.push position
120
- end
121
-
122
- positions
123
- end
124
-
125
- def method_match? method, location, aug
126
- return false unless method.source_location
127
- filename = method.source_location[0]
128
-
129
- if exact_match? location, filename
130
- disasm_header = "== disasm: #<ISeq:#{method.name}@#{location.filename}:"
131
- line_in_disasm = "(#{location.lineno.to_s.rjust 4})"
132
- text = RubyVM::InstructionSequence.disasm method
133
- return false if text.nil?
134
-
135
- text.start_with?(disasm_header) && text.include?(line_in_disasm)
136
- else
137
- if suggested_match? location, filename
138
- warning = Exceptions::RookSourceFilePathSuggestion.new location.filename, filename
139
- aug.notify_warning warning
140
- end
141
- false
101
+ PositionMarker.new location.lineno, iseq
102
+ elsif suggested_match? location, filename
103
+ warning = Exceptions::RookSourceFilePathSuggestion.new location.filename, filename
104
+ location.notify_warning warning
142
105
  end
143
106
  end
144
107
 
145
108
  #########################################################################################
146
109
  # Utils
147
- def exact_match? location, filename
148
- filename.end_with? location.filename
110
+ def exact_match? location_filename, script_filename
111
+ script_filename.end_with? location_filename
149
112
  end
150
113
 
151
114
  def suggested_match? location, filename
@@ -158,6 +121,43 @@ module Rookout
158
121
  content.gsub!(/(?:\r\n|\r|\n)/, "\n")
159
122
  Digest::SHA2.new(256).hexdigest content
160
123
  end
124
+
125
+ def find_updated_line filename, location
126
+ return location.lineno if location.line_crc.nil?
127
+
128
+ lines = File.readlines filename, chomp: true
129
+ line_crc32 = lines.length >= location.lineno ? crc_line(lines[location.lineno - 1]) : nil
130
+ return location.lineno if location.line_crc == line_crc32
131
+
132
+ if location.line_unique
133
+ first_line = nil
134
+ second_found = false
135
+
136
+ lines.each_with_index do |line, index|
137
+ if crc_line(line) == location.line_crc
138
+ if first_line.nil?
139
+ first_line = index
140
+ else
141
+ second_found = true
142
+ break
143
+ end
144
+ end
145
+ end
146
+
147
+ if first_line && !second_found
148
+ updated_line = first_line + 1
149
+ location.notify_warning Exceptions::RookLineMoved.new(filename, location.lineno, updated_line)
150
+ return updated_line
151
+ end
152
+ end
153
+
154
+ location.notify_error Exceptions::RookCrcMismatchException.new(filename, location.line_crc, line_crc32)
155
+ -1
156
+ end
157
+
158
+ def crc_line line
159
+ (Zlib.crc32(line) & 0xffffffff).to_s 16
160
+ end
161
161
  end
162
162
  end
163
163
  end
@@ -1,9 +1,11 @@
1
1
  module Rookout
2
2
  module Services
3
- require "binding_of_caller"
4
- include BindingOfCaller::BindingExtensions
3
+ require_relative "../logger"
5
4
 
6
5
  class Tracer
6
+ require "binding_of_caller"
7
+ include BindingOfCaller::BindingExtensions
8
+
7
9
  def initialize
8
10
  @trace_points = {}
9
11
  @augs = {}
@@ -19,7 +21,7 @@ module Rookout
19
21
  begin
20
22
  trace_point.enable target: position.method, target_line: position.lineno
21
23
  rescue ArgumentError => e
22
- raise Exceptions::RookSetTracepointFailed, position.lineno, e
24
+ raise Exceptions::RookSetTracepointFailed.new(position.lineno, e)
23
25
  end
24
26
 
25
27
  # We add and remove a dummy trace point to re-align the tracing mechanism as a result of some bug in adding
@@ -69,9 +71,10 @@ module Rookout
69
71
  TracePoint.new :line do
70
72
  begin
71
73
  begin
72
- aug.execute BindingOfCaller::BindingExtensions.callers, nil
74
+ # TODO: consider delaying callers (get bindings) until we actually need them in Aug.rb
75
+ aug.execute callers, nil
73
76
  rescue Exception => e
74
- Logger.instance.exception "Exception while evaluating script", e
77
+ Logger.instance.exception "Exception calling aug", e
75
78
  end
76
79
  rescue
77
80
  # Don't leak any exception from here
@@ -17,8 +17,8 @@ module Rookout
17
17
  @services.each_value { |service| service.remove_aug aug_id }
18
18
  end
19
19
 
20
- def clear_augs aug_id
21
- @services.each_value { |service| service.clear_augs aug_id }
20
+ def clear_augs
21
+ @services.each_value(&:clear_augs)
22
22
  end
23
23
 
24
24
  def start
@@ -21,5 +21,7 @@ module Rookout
21
21
  aug = Thread.current[TLS_KEY]
22
22
  aug.notify_error error unless aug.nil?
23
23
  end
24
+
25
+ module_function :with, :notify_warning, :notify_error
24
26
  end
25
27
  end
@@ -0,0 +1,9 @@
1
+ module Utils
2
+ require "securerandom"
3
+
4
+ module_function
5
+
6
+ def uuid
7
+ SecureRandom.uuid.gsub(/-/, "")
8
+ end
9
+ end
@@ -1,4 +1,3 @@
1
1
  module Rookout
2
- VERSION = "0.1.0".freeze
3
- COMMIT = "CommitGoesHere".freeze
2
+ VERSION = "0.1.1".freeze
4
3
  end
metadata CHANGED
@@ -1,181 +1,181 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rookout
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Liran Haimovitch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-10 00:00:00.000000000 Z
11
+ date: 2020-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: binding_of_caller
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.7'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.7'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: concurrent-ruby
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.1'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.1'
41
41
  - !ruby/object:Gem::Dependency
42
- name: kontena-websocket-client
42
+ name: websocket-driver
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 0.1.1
47
+ version: 0.5.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 0.1.1
54
+ version: 0.5.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: google-protobuf
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 3.13.0
61
+ version: 3.0.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 3.13.0
68
+ version: 3.0.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: event_emitter
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: 0.2.6
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.2.6
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: google-style
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: 1.24.0
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: 1.24.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: minitest
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '5.14'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '5.14'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: minitest-autotest
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - "~>"
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
117
  version: '1.0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - "~>"
122
+ - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '1.0'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: minitest-focus
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - "~>"
129
+ - - ">="
130
130
  - !ruby/object:Gem::Version
131
131
  version: '1.1'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - "~>"
136
+ - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '1.1'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: minitest-rg
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - "~>"
143
+ - - ">="
144
144
  - !ruby/object:Gem::Version
145
145
  version: '5.2'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - "~>"
150
+ - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '5.2'
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: autotest-suffix
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
- - - "~>"
157
+ - - ">="
158
158
  - !ruby/object:Gem::Version
159
159
  version: '1.1'
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
- - - "~>"
164
+ - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '1.1'
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: rake-compiler
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
- - - "~>"
171
+ - - ">="
172
172
  - !ruby/object:Gem::Version
173
173
  version: '1.0'
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
- - - "~>"
178
+ - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: '1.0'
181
181
  description: rookout is the Ruby SDK for the Rookout Debugging Platform
@@ -204,7 +204,9 @@ files:
204
204
  - lib/rookout/com_ws/git.rb
205
205
  - lib/rookout/com_ws/information.rb
206
206
  - lib/rookout/com_ws/output.rb
207
+ - lib/rookout/com_ws/pinger.rb
207
208
  - lib/rookout/com_ws/token_bucket.rb
209
+ - lib/rookout/com_ws/websocket_client.rb
208
210
  - lib/rookout/config.rb
209
211
  - lib/rookout/exceptions.rb
210
212
  - lib/rookout/interface.rb
@@ -241,6 +243,7 @@ files:
241
243
  - lib/rookout/services/tracer.rb
242
244
  - lib/rookout/trigger_services.rb
243
245
  - lib/rookout/user_warnings.rb
246
+ - lib/rookout/utils.rb
244
247
  - lib/rookout/version.rb
245
248
  homepage: https://rookout.com
246
249
  licenses:
@@ -262,7 +265,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
262
265
  - !ruby/object:Gem::Version
263
266
  version: '0'
264
267
  requirements: []
265
- rubygems_version: 3.1.4
268
+ rubygems_version: 3.0.3
266
269
  signing_key:
267
270
  specification_version: 4
268
271
  summary: rookout is the Ruby SDK for the Rookout Debugging Platform