readapt 0.8.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +16 -14
- data/.rspec +2 -2
- data/.travis.yml +18 -13
- data/CHANGELOG.md +80 -60
- data/Gemfile +4 -4
- data/LICENSE.txt +21 -21
- data/README.md +37 -29
- data/Rakefile +14 -14
- data/bin/console +14 -14
- data/bin/setup +8 -8
- data/exe/readapt +5 -5
- data/ext/readapt/breakpoints.c +83 -83
- data/ext/readapt/breakpoints.h +11 -11
- data/ext/readapt/extconf.rb +0 -0
- data/ext/readapt/frame.c +137 -137
- data/ext/readapt/frame.h +17 -17
- data/ext/readapt/inspector.c +51 -51
- data/ext/readapt/inspector.h +8 -8
- data/ext/readapt/{hash_table.c → lookup_table.c} +211 -211
- data/ext/readapt/lookup_table.h +30 -0
- data/ext/readapt/monitor.c +42 -5
- data/ext/readapt/monitor.h +0 -0
- data/ext/readapt/normalize.c +59 -59
- data/ext/readapt/normalize.h +7 -7
- data/ext/readapt/readapt.c +18 -18
- data/ext/readapt/stack.c +86 -86
- data/ext/readapt/stack.h +20 -20
- data/ext/readapt/threads.c +15 -11
- data/ext/readapt/threads.h +2 -2
- data/lib/readapt.rb +21 -18
- data/lib/readapt/adapter.rb +98 -138
- data/lib/readapt/breakpoint.rb +21 -20
- data/lib/readapt/data_reader.rb +62 -0
- data/lib/readapt/debugger.rb +220 -224
- data/lib/readapt/error.rb +63 -0
- data/lib/readapt/finder.rb +34 -20
- data/lib/readapt/frame.rb +40 -40
- data/lib/readapt/input.rb +7 -0
- data/lib/readapt/message.rb +62 -62
- data/lib/readapt/message/attach.rb +11 -11
- data/lib/readapt/message/base.rb +32 -32
- data/lib/readapt/message/configuration_done.rb +11 -11
- data/lib/readapt/message/continue.rb +15 -15
- data/lib/readapt/message/disconnect.rb +13 -14
- data/lib/readapt/message/evaluate.rb +18 -18
- data/lib/readapt/message/initialize.rb +13 -13
- data/lib/readapt/message/launch.rb +11 -11
- data/lib/readapt/message/next.rb +12 -12
- data/lib/readapt/message/pause.rb +11 -11
- data/lib/readapt/message/scopes.rb +26 -26
- data/lib/readapt/message/set_breakpoints.rb +25 -25
- data/lib/readapt/message/set_exception_breakpoints.rb +8 -8
- data/lib/readapt/message/stack_trace.rb +38 -38
- data/lib/readapt/message/step_in.rb +11 -11
- data/lib/readapt/message/step_out.rb +11 -11
- data/lib/readapt/message/threads.rb +18 -18
- data/lib/readapt/message/variables.rb +61 -61
- data/lib/readapt/monitor.rb +0 -0
- data/lib/readapt/output.rb +25 -0
- data/lib/readapt/references.rb +27 -0
- data/lib/readapt/server.rb +22 -0
- data/lib/readapt/shell.rb +104 -41
- data/lib/readapt/snapshot.rb +0 -0
- data/lib/readapt/thread.rb +25 -28
- data/lib/readapt/variable.rb +1 -1
- data/lib/readapt/version.rb +3 -3
- data/readapt.gemspec +39 -39
- metadata +15 -9
- data/ext/readapt/hash_table.h +0 -30
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module Readapt
|
4
|
+
module Error
|
5
|
+
class << self
|
6
|
+
attr_accessor :adapter
|
7
|
+
end
|
8
|
+
|
9
|
+
def opening
|
10
|
+
@buffer = ''
|
11
|
+
end
|
12
|
+
|
13
|
+
def receiving data
|
14
|
+
output = ''
|
15
|
+
data.each_char do |char|
|
16
|
+
@buffer += char
|
17
|
+
if open_message.start_with?(@buffer) || @buffer.start_with?(open_message)
|
18
|
+
if @buffer.end_with?(close_message)
|
19
|
+
msg = @buffer[open_message.length..-(close_message.length+1)]
|
20
|
+
exit if msg == '__TERMINATE__'
|
21
|
+
Error.adapter.write msg
|
22
|
+
@buffer.clear
|
23
|
+
end
|
24
|
+
else
|
25
|
+
output += @buffer
|
26
|
+
@buffer.clear
|
27
|
+
end
|
28
|
+
end
|
29
|
+
return if output.empty?
|
30
|
+
send_event('output', {
|
31
|
+
output: output,
|
32
|
+
category: 'stderr'
|
33
|
+
})
|
34
|
+
end
|
35
|
+
|
36
|
+
def send_event event, data
|
37
|
+
obj = {
|
38
|
+
type: 'event',
|
39
|
+
event: event
|
40
|
+
}
|
41
|
+
obj[:body] = data unless data.nil?
|
42
|
+
json = obj.to_json
|
43
|
+
envelope = "Content-Length: #{json.bytesize}\r\n\r\n#{json}"
|
44
|
+
Error.adapter.write envelope
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.procid= pid
|
48
|
+
@@procid = pid
|
49
|
+
end
|
50
|
+
|
51
|
+
def procid
|
52
|
+
@@procid
|
53
|
+
end
|
54
|
+
|
55
|
+
def open_message
|
56
|
+
@@open_message ||= "<readapt-#{procid}>"
|
57
|
+
end
|
58
|
+
|
59
|
+
def close_message
|
60
|
+
@@close_message ||= "</readapt-#{procid}>"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/readapt/finder.rb
CHANGED
@@ -1,20 +1,34 @@
|
|
1
|
-
require 'pathname'
|
2
|
-
|
3
|
-
module Readapt
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module Readapt
|
4
|
+
# Methods to find a program in the current directory or one of the
|
5
|
+
# environment paths.
|
6
|
+
#
|
7
|
+
module Finder
|
8
|
+
module_function
|
9
|
+
|
10
|
+
# Get the program's fully qualified path. Search first in the current
|
11
|
+
# directory, then the environment paths.
|
12
|
+
#
|
13
|
+
# @raise [LoadError] if the program was not found
|
14
|
+
#
|
15
|
+
# @param program [String] The name of the program
|
16
|
+
# @return [String] The fully qualified path
|
17
|
+
def find program
|
18
|
+
return program if File.exist?(program)
|
19
|
+
which(program) || raise(LoadError, "#{program} is not a valid Ruby file or program")
|
20
|
+
end
|
21
|
+
|
22
|
+
# Search the environment paths for the given program.
|
23
|
+
#
|
24
|
+
# @param program [String] The name of the program
|
25
|
+
# @return [String] The fully qualified path, or nil if it was not found
|
26
|
+
def which program
|
27
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
28
|
+
exe = File.join(path, program)
|
29
|
+
return exe if File.file?(exe)
|
30
|
+
end
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/readapt/frame.rb
CHANGED
@@ -1,40 +1,40 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Readapt
|
4
|
-
# @!method file
|
5
|
-
# @return [String]
|
6
|
-
# @!method line
|
7
|
-
# @return [Integer]
|
8
|
-
# @!method binding_id
|
9
|
-
# @return [Integer]
|
10
|
-
# @!method initialize(file, line, binding_id)
|
11
|
-
class Frame
|
12
|
-
def evaluate code
|
13
|
-
frame_binding.eval(code).inspect
|
14
|
-
rescue Exception => e
|
15
|
-
"[#{e.class}] #{e.message}"
|
16
|
-
end
|
17
|
-
|
18
|
-
def local_id
|
19
|
-
frame_binding.object_id
|
20
|
-
end
|
21
|
-
|
22
|
-
def locals
|
23
|
-
return [] if frame_binding.nil?
|
24
|
-
result = []
|
25
|
-
frame_binding.local_variables.each do |sym|
|
26
|
-
var = frame_binding.local_variable_get(sym)
|
27
|
-
result.push Variable.new(sym, var)
|
28
|
-
end
|
29
|
-
result.push Variable.new(:self, frame_binding.receiver)
|
30
|
-
result
|
31
|
-
end
|
32
|
-
|
33
|
-
def local sym
|
34
|
-
return frame_binding.receiver if sym == :self
|
35
|
-
frame_binding.local_variable_get sym
|
36
|
-
end
|
37
|
-
|
38
|
-
NULL_FRAME = Frame.new("", 0, nil)
|
39
|
-
end
|
40
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Readapt
|
4
|
+
# @!method file
|
5
|
+
# @return [String]
|
6
|
+
# @!method line
|
7
|
+
# @return [Integer]
|
8
|
+
# @!method binding_id
|
9
|
+
# @return [Integer]
|
10
|
+
# @!method initialize(file, line, binding_id)
|
11
|
+
class Frame
|
12
|
+
def evaluate code
|
13
|
+
frame_binding.eval(code).inspect
|
14
|
+
rescue Exception => e
|
15
|
+
"[#{e.class}] #{e.message}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def local_id
|
19
|
+
frame_binding.object_id
|
20
|
+
end
|
21
|
+
|
22
|
+
def locals
|
23
|
+
return [] if frame_binding.nil?
|
24
|
+
result = []
|
25
|
+
frame_binding.local_variables.sort.each do |sym|
|
26
|
+
var = frame_binding.local_variable_get(sym)
|
27
|
+
result.push Variable.new(sym, var)
|
28
|
+
end
|
29
|
+
result.push Variable.new(:self, frame_binding.receiver)
|
30
|
+
result
|
31
|
+
end
|
32
|
+
|
33
|
+
def local sym
|
34
|
+
return frame_binding.receiver if sym == :self
|
35
|
+
frame_binding.local_variable_get sym
|
36
|
+
end
|
37
|
+
|
38
|
+
NULL_FRAME = Frame.new("", 0, nil)
|
39
|
+
end
|
40
|
+
end
|
data/lib/readapt/message.rb
CHANGED
@@ -1,62 +1,62 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'readapt/message/base'
|
4
|
-
require 'readapt/message/initialize'
|
5
|
-
require 'readapt/message/launch'
|
6
|
-
require 'readapt/message/set_breakpoints'
|
7
|
-
require 'readapt/message/set_exception_breakpoints'
|
8
|
-
require 'readapt/message/configuration_done'
|
9
|
-
require 'readapt/message/threads'
|
10
|
-
require 'readapt/message/stack_trace'
|
11
|
-
require 'readapt/message/scopes'
|
12
|
-
require 'readapt/message/continue'
|
13
|
-
require 'readapt/message/variables'
|
14
|
-
require 'readapt/message/next'
|
15
|
-
require 'readapt/message/step_in'
|
16
|
-
require 'readapt/message/step_out'
|
17
|
-
require 'readapt/message/disconnect'
|
18
|
-
require 'readapt/message/attach'
|
19
|
-
require 'readapt/message/pause'
|
20
|
-
require 'readapt/message/evaluate'
|
21
|
-
|
22
|
-
module Readapt
|
23
|
-
module Message
|
24
|
-
@@messages = {}
|
25
|
-
@@seq = 0
|
26
|
-
|
27
|
-
def self.register name, klass
|
28
|
-
@@messages[name] = klass
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.process arguments, debugger
|
32
|
-
klass = @@messages[arguments['command']]
|
33
|
-
if klass.nil?
|
34
|
-
STDERR.puts "Debugger received unrecognized command `#{arguments['command']}`"
|
35
|
-
Message::Base.new(arguments, debugger)
|
36
|
-
else
|
37
|
-
message = klass.new(arguments['arguments'], debugger)
|
38
|
-
message.run
|
39
|
-
message
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
register 'initialize', Message::Initialize
|
44
|
-
register 'attach', Message::Attach
|
45
|
-
register 'launch', Message::Launch
|
46
|
-
register 'setBreakpoints', Message::SetBreakpoints
|
47
|
-
register 'setExceptionBreakpoints', Message::SetExceptionBreakpoints
|
48
|
-
register 'configurationDone', Message::ConfigurationDone
|
49
|
-
register 'threads', Message::Threads
|
50
|
-
register 'stackTrace', Message::StackTrace
|
51
|
-
register 'scopes', Message::Scopes
|
52
|
-
register 'continue', Message::Continue
|
53
|
-
register 'variables', Message::Variables
|
54
|
-
register 'next', Message::Next
|
55
|
-
register 'stepIn', Message::StepIn
|
56
|
-
register 'stepOut', Message::StepOut
|
57
|
-
register 'disconnect', Message::Disconnect
|
58
|
-
register 'pause', Message::Pause
|
59
|
-
register 'evaluate', Message::Evaluate
|
60
|
-
# register 'source', Message::Base # @todo Placeholder
|
61
|
-
end
|
62
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'readapt/message/base'
|
4
|
+
require 'readapt/message/initialize'
|
5
|
+
require 'readapt/message/launch'
|
6
|
+
require 'readapt/message/set_breakpoints'
|
7
|
+
require 'readapt/message/set_exception_breakpoints'
|
8
|
+
require 'readapt/message/configuration_done'
|
9
|
+
require 'readapt/message/threads'
|
10
|
+
require 'readapt/message/stack_trace'
|
11
|
+
require 'readapt/message/scopes'
|
12
|
+
require 'readapt/message/continue'
|
13
|
+
require 'readapt/message/variables'
|
14
|
+
require 'readapt/message/next'
|
15
|
+
require 'readapt/message/step_in'
|
16
|
+
require 'readapt/message/step_out'
|
17
|
+
require 'readapt/message/disconnect'
|
18
|
+
require 'readapt/message/attach'
|
19
|
+
require 'readapt/message/pause'
|
20
|
+
require 'readapt/message/evaluate'
|
21
|
+
|
22
|
+
module Readapt
|
23
|
+
module Message
|
24
|
+
@@messages = {}
|
25
|
+
@@seq = 0
|
26
|
+
|
27
|
+
def self.register name, klass
|
28
|
+
@@messages[name] = klass
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.process arguments, debugger
|
32
|
+
klass = @@messages[arguments['command']]
|
33
|
+
if klass.nil?
|
34
|
+
STDERR.puts "Debugger received unrecognized command `#{arguments['command']}`"
|
35
|
+
Message::Base.new(arguments, debugger)
|
36
|
+
else
|
37
|
+
message = klass.new(arguments['arguments'], debugger)
|
38
|
+
message.run
|
39
|
+
message
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
register 'initialize', Message::Initialize
|
44
|
+
register 'attach', Message::Attach
|
45
|
+
register 'launch', Message::Launch
|
46
|
+
register 'setBreakpoints', Message::SetBreakpoints
|
47
|
+
register 'setExceptionBreakpoints', Message::SetExceptionBreakpoints
|
48
|
+
register 'configurationDone', Message::ConfigurationDone
|
49
|
+
register 'threads', Message::Threads
|
50
|
+
register 'stackTrace', Message::StackTrace
|
51
|
+
register 'scopes', Message::Scopes
|
52
|
+
register 'continue', Message::Continue
|
53
|
+
register 'variables', Message::Variables
|
54
|
+
register 'next', Message::Next
|
55
|
+
register 'stepIn', Message::StepIn
|
56
|
+
register 'stepOut', Message::StepOut
|
57
|
+
register 'disconnect', Message::Disconnect
|
58
|
+
register 'pause', Message::Pause
|
59
|
+
register 'evaluate', Message::Evaluate
|
60
|
+
# register 'source', Message::Base # @todo Placeholder
|
61
|
+
end
|
62
|
+
end
|
@@ -1,11 +1,11 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Readapt
|
4
|
-
module Message
|
5
|
-
class Attach < Base
|
6
|
-
def run
|
7
|
-
debugger.config arguments, :attach
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Readapt
|
4
|
+
module Message
|
5
|
+
class Attach < Base
|
6
|
+
def run
|
7
|
+
debugger.config arguments, :attach
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/readapt/message/base.rb
CHANGED
@@ -1,32 +1,32 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Readapt
|
4
|
-
module Message
|
5
|
-
class Base
|
6
|
-
# @return [Hash]
|
7
|
-
attr_reader :arguments
|
8
|
-
|
9
|
-
# @return [Debugger]
|
10
|
-
attr_reader :debugger
|
11
|
-
|
12
|
-
def initialize arguments, debugger
|
13
|
-
@arguments = arguments
|
14
|
-
@debugger = debugger
|
15
|
-
end
|
16
|
-
|
17
|
-
def run; end
|
18
|
-
|
19
|
-
def body
|
20
|
-
@body ||= {}
|
21
|
-
end
|
22
|
-
|
23
|
-
def set_body hash
|
24
|
-
@body = hash
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.run arguments, debugger
|
28
|
-
new(arguments, debugger).run
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Readapt
|
4
|
+
module Message
|
5
|
+
class Base
|
6
|
+
# @return [Hash]
|
7
|
+
attr_reader :arguments
|
8
|
+
|
9
|
+
# @return [Debugger]
|
10
|
+
attr_reader :debugger
|
11
|
+
|
12
|
+
def initialize arguments, debugger
|
13
|
+
@arguments = arguments
|
14
|
+
@debugger = debugger
|
15
|
+
end
|
16
|
+
|
17
|
+
def run; end
|
18
|
+
|
19
|
+
def body
|
20
|
+
@body ||= {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_body hash
|
24
|
+
@body = hash
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.run arguments, debugger
|
28
|
+
new(arguments, debugger).run
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,11 +1,11 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Readapt
|
4
|
-
module Message
|
5
|
-
class ConfigurationDone < Base
|
6
|
-
def run
|
7
|
-
debugger.start
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Readapt
|
4
|
+
module Message
|
5
|
+
class ConfigurationDone < Base
|
6
|
+
def run
|
7
|
+
debugger.start
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|