ruby-debug-ide22 0.7.4 → 0.7.5
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/CHANGES +75 -75
- data/ChangeLog.archive +1073 -1073
- data/ChangeLog.md +594 -594
- data/Gemfile +38 -38
- data/MIT-LICENSE +24 -24
- data/Rakefile +92 -92
- data/bin/gdb_wrapper +96 -96
- data/bin/rdebug-ide +200 -200
- data/ext/mkrf_conf.rb +44 -44
- data/lib/ruby-debug-ide/attach/debugger_loader.rb +20 -20
- data/lib/ruby-debug-ide/attach/gdb.rb +73 -73
- data/lib/ruby-debug-ide/attach/lldb.rb +71 -71
- data/lib/ruby-debug-ide/attach/native_debugger.rb +133 -133
- data/lib/ruby-debug-ide/attach/process_thread.rb +54 -54
- data/lib/ruby-debug-ide/attach/util.rb +114 -114
- data/lib/ruby-debug-ide/command.rb +187 -187
- data/lib/ruby-debug-ide/commands/breakpoints.rb +128 -128
- data/lib/ruby-debug-ide/commands/catchpoint.rb +64 -64
- data/lib/ruby-debug-ide/commands/condition.rb +51 -51
- data/lib/ruby-debug-ide/commands/control.rb +164 -158
- data/lib/ruby-debug-ide/commands/enable.rb +203 -203
- data/lib/ruby-debug-ide/commands/eval.rb +64 -64
- data/lib/ruby-debug-ide/commands/expression_info.rb +71 -71
- data/lib/ruby-debug-ide/commands/file_filtering.rb +106 -106
- data/lib/ruby-debug-ide/commands/frame.rb +155 -155
- data/lib/ruby-debug-ide/commands/inspect.rb +25 -25
- data/lib/ruby-debug-ide/commands/load.rb +17 -17
- data/lib/ruby-debug-ide/commands/stepping.rb +108 -108
- data/lib/ruby-debug-ide/commands/threads.rb +178 -178
- data/lib/ruby-debug-ide/commands/variables.rb +154 -154
- data/lib/ruby-debug-ide/event_processor.rb +71 -71
- data/lib/ruby-debug-ide/greeter.rb +42 -42
- data/lib/ruby-debug-ide/helper.rb +33 -33
- data/lib/ruby-debug-ide/ide_processor.rb +155 -155
- data/lib/ruby-debug-ide/interface.rb +47 -45
- data/lib/ruby-debug-ide/multiprocess/monkey.rb +46 -46
- data/lib/ruby-debug-ide/multiprocess/pre_child.rb +58 -58
- data/lib/ruby-debug-ide/multiprocess/starter.rb +10 -10
- data/lib/ruby-debug-ide/multiprocess/unmonkey.rb +30 -30
- data/lib/ruby-debug-ide/multiprocess.rb +22 -22
- data/lib/ruby-debug-ide/thread_alias.rb +26 -26
- data/lib/ruby-debug-ide/version.rb +3 -3
- data/lib/ruby-debug-ide/xml_printer.rb +570 -570
- data/lib/ruby-debug-ide.rb +230 -228
- data/ruby-debug-ide.gemspec +47 -47
- metadata +4 -4
@@ -1,155 +1,155 @@
|
|
1
|
-
require 'ruby-debug-ide/interface'
|
2
|
-
require 'ruby-debug-ide/command'
|
3
|
-
|
4
|
-
module Debugger
|
5
|
-
class IdeCommandProcessor
|
6
|
-
def initialize(interface = nil)
|
7
|
-
@interface = interface
|
8
|
-
@printer = XmlPrinter.new(@interface)
|
9
|
-
end
|
10
|
-
|
11
|
-
def print(*args)
|
12
|
-
@interface.print(*args)
|
13
|
-
end
|
14
|
-
|
15
|
-
def process_commands
|
16
|
-
unless Debugger.handler.at_line?
|
17
|
-
@printer.print_error "There is no thread suspended at the time and therefore no context to execute '#{input.gsub('%', '%%')}'"
|
18
|
-
return
|
19
|
-
end
|
20
|
-
context = Debugger.handler.context
|
21
|
-
file = Debugger.handler.file
|
22
|
-
line = Debugger.handler.line
|
23
|
-
state = State.new do |s|
|
24
|
-
s.context = context
|
25
|
-
s.file = file
|
26
|
-
s.line = line
|
27
|
-
s.binding = context.frame_binding(0)
|
28
|
-
s.interface = @interface
|
29
|
-
end
|
30
|
-
event_cmds = Command.commands.map{|cmd| cmd.new(state, @printer) }
|
31
|
-
until state.proceed? do
|
32
|
-
input = @interface.command_queue.pop
|
33
|
-
catch(:debug_error) do
|
34
|
-
splitter[input].each do |input|
|
35
|
-
# escape % since print_debug might use printf
|
36
|
-
@printer.print_debug "Processing in context: #{input.gsub('%', '%%')}"
|
37
|
-
if (cmd = event_cmds.find { |c| c.match(input) })
|
38
|
-
if context.dead? && cmd.class.need_context
|
39
|
-
@printer.print_msg "Command is unavailable\n"
|
40
|
-
else
|
41
|
-
cmd.execute
|
42
|
-
end
|
43
|
-
else
|
44
|
-
@printer.print_msg "Unknown command: #{input}"
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
state.restore_context
|
49
|
-
end
|
50
|
-
rescue ::Exception
|
51
|
-
@printer.print_error "INTERNAL ERROR!!! #{$!}\n" rescue nil
|
52
|
-
@printer.print_error $!.backtrace.map{|l| "\t#{l}"}.join("\n") rescue nil
|
53
|
-
end
|
54
|
-
|
55
|
-
def splitter
|
56
|
-
lambda do |str|
|
57
|
-
str.split(/;/).inject([]) do |m, v|
|
58
|
-
if m.empty?
|
59
|
-
m << v
|
60
|
-
else
|
61
|
-
if m.last[-1] == ?\\
|
62
|
-
m.last[-1,1] = ''
|
63
|
-
m.last << ';' << v
|
64
|
-
else
|
65
|
-
m << v
|
66
|
-
end
|
67
|
-
end
|
68
|
-
m
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
class IdeControlCommandProcessor < IdeCommandProcessor# :nodoc:
|
75
|
-
def process_commands
|
76
|
-
@printer.print_debug("Starting control thread")
|
77
|
-
ctrl_cmd_classes = Command.commands.select{|cmd| cmd.control}
|
78
|
-
state = ControlState.new(@interface)
|
79
|
-
ctrl_cmds = ctrl_cmd_classes.map{|cmd| cmd.new(state, @printer)}
|
80
|
-
while input = @interface.read_command
|
81
|
-
# escape % since print_debug might use printf
|
82
|
-
# sleep 0.3
|
83
|
-
catch(:debug_error) do
|
84
|
-
if cmd = ctrl_cmds.find{|c| c.match(input) }
|
85
|
-
@printer.print_debug "Processing in control: #{input.gsub('%', '%%')}"
|
86
|
-
cmd.execute
|
87
|
-
else
|
88
|
-
@interface.command_queue << input
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
rescue ::Exception
|
93
|
-
@printer.print_debug "INTERNAL ERROR!!! #{$!}\n" rescue nil
|
94
|
-
@printer.print_error "INTERNAL ERROR!!! #{$!}\n" rescue nil
|
95
|
-
@printer.print_error $!.backtrace.map{|l| "\t#{l}"}.join("\n") rescue nil
|
96
|
-
ensure
|
97
|
-
@interface.close
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
class State # :nodoc:
|
102
|
-
|
103
|
-
attr_accessor :context, :original_context
|
104
|
-
attr_accessor :file, :line, :binding
|
105
|
-
attr_accessor :frame_pos, :previous_line
|
106
|
-
attr_accessor :interface
|
107
|
-
|
108
|
-
def initialize
|
109
|
-
@frame_pos = 0
|
110
|
-
@previous_line = nil
|
111
|
-
@proceed = false
|
112
|
-
yield self
|
113
|
-
@original_context = context
|
114
|
-
end
|
115
|
-
|
116
|
-
def print(*args)
|
117
|
-
@interface.print(*args)
|
118
|
-
end
|
119
|
-
|
120
|
-
def proceed?
|
121
|
-
@proceed
|
122
|
-
end
|
123
|
-
|
124
|
-
def proceed
|
125
|
-
@proceed = true
|
126
|
-
end
|
127
|
-
|
128
|
-
def restore_context
|
129
|
-
@context = @original_context
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
class ControlState # :nodoc:
|
134
|
-
|
135
|
-
def initialize(interface)
|
136
|
-
@interface = interface
|
137
|
-
end
|
138
|
-
|
139
|
-
def proceed
|
140
|
-
end
|
141
|
-
|
142
|
-
def print(*args)
|
143
|
-
@interface.print(*args)
|
144
|
-
end
|
145
|
-
|
146
|
-
def context
|
147
|
-
nil
|
148
|
-
end
|
149
|
-
|
150
|
-
def file
|
151
|
-
print "ERROR: No filename given.\n"
|
152
|
-
throw :debug_error
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
1
|
+
require 'ruby-debug-ide/interface'
|
2
|
+
require 'ruby-debug-ide/command'
|
3
|
+
|
4
|
+
module Debugger
|
5
|
+
class IdeCommandProcessor
|
6
|
+
def initialize(interface = nil)
|
7
|
+
@interface = interface
|
8
|
+
@printer = XmlPrinter.new(@interface)
|
9
|
+
end
|
10
|
+
|
11
|
+
def print(*args)
|
12
|
+
@interface.print(*args)
|
13
|
+
end
|
14
|
+
|
15
|
+
def process_commands
|
16
|
+
unless Debugger.handler.at_line?
|
17
|
+
@printer.print_error "There is no thread suspended at the time and therefore no context to execute '#{input.gsub('%', '%%')}'"
|
18
|
+
return
|
19
|
+
end
|
20
|
+
context = Debugger.handler.context
|
21
|
+
file = Debugger.handler.file
|
22
|
+
line = Debugger.handler.line
|
23
|
+
state = State.new do |s|
|
24
|
+
s.context = context
|
25
|
+
s.file = file
|
26
|
+
s.line = line
|
27
|
+
s.binding = context.frame_binding(0)
|
28
|
+
s.interface = @interface
|
29
|
+
end
|
30
|
+
event_cmds = Command.commands.map{|cmd| cmd.new(state, @printer) }
|
31
|
+
until state.proceed? do
|
32
|
+
input = @interface.command_queue.pop
|
33
|
+
catch(:debug_error) do
|
34
|
+
splitter[input].each do |input|
|
35
|
+
# escape % since print_debug might use printf
|
36
|
+
@printer.print_debug "Processing in context: #{input.gsub('%', '%%')}"
|
37
|
+
if (cmd = event_cmds.find { |c| c.match(input) })
|
38
|
+
if context.dead? && cmd.class.need_context
|
39
|
+
@printer.print_msg "Command is unavailable\n"
|
40
|
+
else
|
41
|
+
cmd.execute
|
42
|
+
end
|
43
|
+
else
|
44
|
+
@printer.print_msg "Unknown command: #{input}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
state.restore_context
|
49
|
+
end
|
50
|
+
rescue ::Exception
|
51
|
+
@printer.print_error "INTERNAL ERROR!!! #{$!}\n" rescue nil
|
52
|
+
@printer.print_error $!.backtrace.map{|l| "\t#{l}"}.join("\n") rescue nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def splitter
|
56
|
+
lambda do |str|
|
57
|
+
str.split(/;/).inject([]) do |m, v|
|
58
|
+
if m.empty?
|
59
|
+
m << v
|
60
|
+
else
|
61
|
+
if m.last[-1] == ?\\
|
62
|
+
m.last[-1,1] = ''
|
63
|
+
m.last << ';' << v
|
64
|
+
else
|
65
|
+
m << v
|
66
|
+
end
|
67
|
+
end
|
68
|
+
m
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class IdeControlCommandProcessor < IdeCommandProcessor# :nodoc:
|
75
|
+
def process_commands
|
76
|
+
@printer.print_debug("Starting control thread")
|
77
|
+
ctrl_cmd_classes = Command.commands.select{|cmd| cmd.control}
|
78
|
+
state = ControlState.new(@interface)
|
79
|
+
ctrl_cmds = ctrl_cmd_classes.map{|cmd| cmd.new(state, @printer)}
|
80
|
+
while input = @interface.read_command
|
81
|
+
# escape % since print_debug might use printf
|
82
|
+
# sleep 0.3
|
83
|
+
catch(:debug_error) do
|
84
|
+
if cmd = ctrl_cmds.find{|c| c.match(input) }
|
85
|
+
@printer.print_debug "Processing in control: #{input.gsub('%', '%%')}"
|
86
|
+
cmd.execute
|
87
|
+
else
|
88
|
+
@interface.command_queue << input
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
rescue ::Exception
|
93
|
+
@printer.print_debug "INTERNAL ERROR!!! #{$!}\n" rescue nil
|
94
|
+
@printer.print_error "INTERNAL ERROR!!! #{$!}\n" rescue nil
|
95
|
+
@printer.print_error $!.backtrace.map{|l| "\t#{l}"}.join("\n") rescue nil
|
96
|
+
ensure
|
97
|
+
@interface.close
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
class State # :nodoc:
|
102
|
+
|
103
|
+
attr_accessor :context, :original_context
|
104
|
+
attr_accessor :file, :line, :binding
|
105
|
+
attr_accessor :frame_pos, :previous_line
|
106
|
+
attr_accessor :interface
|
107
|
+
|
108
|
+
def initialize
|
109
|
+
@frame_pos = 0
|
110
|
+
@previous_line = nil
|
111
|
+
@proceed = false
|
112
|
+
yield self
|
113
|
+
@original_context = context
|
114
|
+
end
|
115
|
+
|
116
|
+
def print(*args)
|
117
|
+
@interface.print(*args)
|
118
|
+
end
|
119
|
+
|
120
|
+
def proceed?
|
121
|
+
@proceed
|
122
|
+
end
|
123
|
+
|
124
|
+
def proceed
|
125
|
+
@proceed = true
|
126
|
+
end
|
127
|
+
|
128
|
+
def restore_context
|
129
|
+
@context = @original_context
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class ControlState # :nodoc:
|
134
|
+
|
135
|
+
def initialize(interface)
|
136
|
+
@interface = interface
|
137
|
+
end
|
138
|
+
|
139
|
+
def proceed
|
140
|
+
end
|
141
|
+
|
142
|
+
def print(*args)
|
143
|
+
@interface.print(*args)
|
144
|
+
end
|
145
|
+
|
146
|
+
def context
|
147
|
+
nil
|
148
|
+
end
|
149
|
+
|
150
|
+
def file
|
151
|
+
print "ERROR: No filename given.\n"
|
152
|
+
throw :debug_error
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -1,45 +1,47 @@
|
|
1
|
-
require 'thread'
|
2
|
-
|
3
|
-
module Debugger
|
4
|
-
class Interface
|
5
|
-
end
|
6
|
-
|
7
|
-
class LocalInterface < Interface
|
8
|
-
end
|
9
|
-
|
10
|
-
|
11
|
-
class RemoteInterface < Interface # :nodoc:
|
12
|
-
attr_accessor :command_queue
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
result
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Debugger
|
4
|
+
class Interface
|
5
|
+
end
|
6
|
+
|
7
|
+
class LocalInterface < Interface
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
class RemoteInterface < Interface # :nodoc:
|
12
|
+
attr_accessor :command_queue
|
13
|
+
attr_accessor :closing
|
14
|
+
|
15
|
+
def initialize(socket)
|
16
|
+
@socket = socket
|
17
|
+
@command_queue = Queue.new
|
18
|
+
@closing = false
|
19
|
+
end
|
20
|
+
|
21
|
+
def read_command
|
22
|
+
result = non_blocking_gets
|
23
|
+
raise IOError unless result
|
24
|
+
result.chomp
|
25
|
+
end
|
26
|
+
|
27
|
+
def print(*args)
|
28
|
+
@socket.printf(*args) unless (@closing && ENV['DEBUGGER_KEEP_PROCESS_ALIVE'])
|
29
|
+
end
|
30
|
+
|
31
|
+
def close
|
32
|
+
@socket.close
|
33
|
+
rescue IOError, SystemCallError
|
34
|
+
end
|
35
|
+
|
36
|
+
# Workaround for JRuby issue http://jira.codehaus.org/browse/JRUBY-2063
|
37
|
+
def non_blocking_gets
|
38
|
+
loop do
|
39
|
+
result, _, _ = IO.select( [@socket], nil, nil, 0.2 )
|
40
|
+
next unless result
|
41
|
+
return result[0].gets
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -1,47 +1,47 @@
|
|
1
|
-
module Debugger
|
2
|
-
module MultiProcess
|
3
|
-
def self.create_mp_fork(private=false)
|
4
|
-
%Q{
|
5
|
-
alias pre_debugger_fork fork
|
6
|
-
|
7
|
-
#{private ? "private" : ""}
|
8
|
-
def fork(*args)
|
9
|
-
if block_given?
|
10
|
-
return pre_debugger_fork{Debugger::MultiProcess::pre_child; yield}
|
11
|
-
end
|
12
|
-
result = pre_debugger_fork
|
13
|
-
Debugger::MultiProcess::pre_child unless result
|
14
|
-
result
|
15
|
-
end
|
16
|
-
}
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.create_mp_exec(private=false)
|
20
|
-
%Q{
|
21
|
-
alias pre_debugger_exec exec
|
22
|
-
|
23
|
-
#{private ? "private" : ""}
|
24
|
-
def exec(*args)
|
25
|
-
Debugger.interface.close
|
26
|
-
pre_debugger_exec(*args)
|
27
|
-
end
|
28
|
-
}
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
module Kernel
|
34
|
-
class << self
|
35
|
-
module_eval Debugger::MultiProcess.create_mp_fork
|
36
|
-
module_eval Debugger::MultiProcess.create_mp_exec
|
37
|
-
end
|
38
|
-
module_eval Debugger::MultiProcess.create_mp_fork(true)
|
39
|
-
module_eval Debugger::MultiProcess.create_mp_exec(true)
|
40
|
-
end
|
41
|
-
|
42
|
-
module Process
|
43
|
-
class << self
|
44
|
-
module_eval Debugger::MultiProcess.create_mp_fork
|
45
|
-
module_eval Debugger::MultiProcess.create_mp_exec
|
46
|
-
end
|
1
|
+
module Debugger
|
2
|
+
module MultiProcess
|
3
|
+
def self.create_mp_fork(private=false)
|
4
|
+
%Q{
|
5
|
+
alias pre_debugger_fork fork
|
6
|
+
|
7
|
+
#{private ? "private" : ""}
|
8
|
+
def fork(*args)
|
9
|
+
if block_given?
|
10
|
+
return pre_debugger_fork{Debugger::MultiProcess::pre_child; yield}
|
11
|
+
end
|
12
|
+
result = pre_debugger_fork
|
13
|
+
Debugger::MultiProcess::pre_child unless result
|
14
|
+
result
|
15
|
+
end
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.create_mp_exec(private=false)
|
20
|
+
%Q{
|
21
|
+
alias pre_debugger_exec exec
|
22
|
+
|
23
|
+
#{private ? "private" : ""}
|
24
|
+
def exec(*args)
|
25
|
+
Debugger.interface.close
|
26
|
+
pre_debugger_exec(*args)
|
27
|
+
end
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module Kernel
|
34
|
+
class << self
|
35
|
+
module_eval Debugger::MultiProcess.create_mp_fork
|
36
|
+
module_eval Debugger::MultiProcess.create_mp_exec
|
37
|
+
end
|
38
|
+
module_eval Debugger::MultiProcess.create_mp_fork(true)
|
39
|
+
module_eval Debugger::MultiProcess.create_mp_exec(true)
|
40
|
+
end
|
41
|
+
|
42
|
+
module Process
|
43
|
+
class << self
|
44
|
+
module_eval Debugger::MultiProcess.create_mp_fork
|
45
|
+
module_eval Debugger::MultiProcess.create_mp_exec
|
46
|
+
end
|
47
47
|
end
|
@@ -1,59 +1,59 @@
|
|
1
|
-
module Debugger
|
2
|
-
module MultiProcess
|
3
|
-
class << self
|
4
|
-
def pre_child(options = nil)
|
5
|
-
require 'socket'
|
6
|
-
require 'ostruct'
|
7
|
-
|
8
|
-
host = ENV['DEBUGGER_HOST']
|
9
|
-
|
10
|
-
options ||= OpenStruct.new(
|
11
|
-
'frame_bind' => false,
|
12
|
-
'host' => host,
|
13
|
-
'load_mode' => false,
|
14
|
-
'port' => Debugger.find_free_port(host),
|
15
|
-
'stop' => false,
|
16
|
-
'tracing' => false,
|
17
|
-
'int_handler' => true,
|
18
|
-
'cli_debug' => (ENV['DEBUGGER_CLI_DEBUG'] == 'true'),
|
19
|
-
'notify_dispatcher' => true,
|
20
|
-
'evaluation_timeout' => 10,
|
21
|
-
'trace_to_s' => false,
|
22
|
-
'debugger_memory_limit' => 10,
|
23
|
-
'inspect_time_limit' => 100
|
24
|
-
)
|
25
|
-
|
26
|
-
if(options.ignore_port)
|
27
|
-
options.port = Debugger.find_free_port(options.host)
|
28
|
-
options.notify_dispatcher = true
|
29
|
-
end
|
30
|
-
|
31
|
-
start_debugger(options)
|
32
|
-
end
|
33
|
-
|
34
|
-
def start_debugger(options)
|
35
|
-
if Debugger.started?
|
36
|
-
# we're in forked child, only need to restart control thread
|
37
|
-
Debugger.breakpoints.clear
|
38
|
-
Debugger.control_thread = nil
|
39
|
-
Debugger.start_control(options.host, options.port, options.notify_dispatcher)
|
40
|
-
end
|
41
|
-
|
42
|
-
if options.int_handler
|
43
|
-
# install interruption handler
|
44
|
-
trap('INT') { Debugger.interrupt_last }
|
45
|
-
end
|
46
|
-
|
47
|
-
# set options
|
48
|
-
Debugger.keep_frame_binding = options.frame_bind
|
49
|
-
Debugger.tracing = options.tracing
|
50
|
-
Debugger.evaluation_timeout = options.evaluation_timeout
|
51
|
-
Debugger.trace_to_s = options.trace_to_s
|
52
|
-
Debugger.debugger_memory_limit = options.debugger_memory_limit
|
53
|
-
Debugger.inspect_time_limit = options.inspect_time_limit
|
54
|
-
Debugger.cli_debug = options.cli_debug
|
55
|
-
Debugger.prepare_debugger(options)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
1
|
+
module Debugger
|
2
|
+
module MultiProcess
|
3
|
+
class << self
|
4
|
+
def pre_child(options = nil)
|
5
|
+
require 'socket'
|
6
|
+
require 'ostruct'
|
7
|
+
|
8
|
+
host = ENV['DEBUGGER_HOST']
|
9
|
+
|
10
|
+
options ||= OpenStruct.new(
|
11
|
+
'frame_bind' => false,
|
12
|
+
'host' => host,
|
13
|
+
'load_mode' => false,
|
14
|
+
'port' => Debugger.find_free_port(host),
|
15
|
+
'stop' => false,
|
16
|
+
'tracing' => false,
|
17
|
+
'int_handler' => true,
|
18
|
+
'cli_debug' => (ENV['DEBUGGER_CLI_DEBUG'] == 'true'),
|
19
|
+
'notify_dispatcher' => true,
|
20
|
+
'evaluation_timeout' => 10,
|
21
|
+
'trace_to_s' => false,
|
22
|
+
'debugger_memory_limit' => 10,
|
23
|
+
'inspect_time_limit' => 100
|
24
|
+
)
|
25
|
+
|
26
|
+
if(options.ignore_port)
|
27
|
+
options.port = Debugger.find_free_port(options.host)
|
28
|
+
options.notify_dispatcher = true
|
29
|
+
end
|
30
|
+
|
31
|
+
start_debugger(options)
|
32
|
+
end
|
33
|
+
|
34
|
+
def start_debugger(options)
|
35
|
+
if Debugger.started?
|
36
|
+
# we're in forked child, only need to restart control thread
|
37
|
+
Debugger.breakpoints.clear
|
38
|
+
Debugger.control_thread = nil
|
39
|
+
Debugger.start_control(options.host, options.port, options.notify_dispatcher)
|
40
|
+
end
|
41
|
+
|
42
|
+
if options.int_handler
|
43
|
+
# install interruption handler
|
44
|
+
trap('INT') { Debugger.interrupt_last }
|
45
|
+
end
|
46
|
+
|
47
|
+
# set options
|
48
|
+
Debugger.keep_frame_binding = options.frame_bind
|
49
|
+
Debugger.tracing = options.tracing
|
50
|
+
Debugger.evaluation_timeout = options.evaluation_timeout
|
51
|
+
Debugger.trace_to_s = options.trace_to_s
|
52
|
+
Debugger.debugger_memory_limit = options.debugger_memory_limit
|
53
|
+
Debugger.inspect_time_limit = options.inspect_time_limit
|
54
|
+
Debugger.cli_debug = options.cli_debug
|
55
|
+
Debugger.prepare_debugger(options)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
59
|
end
|
@@ -1,11 +1,11 @@
|
|
1
|
-
if ENV['IDE_PROCESS_DISPATCHER']
|
2
|
-
require 'rubygems'
|
3
|
-
ENV['DEBUGGER_STORED_RUBYLIB'].split(File::PATH_SEPARATOR).each do |path|
|
4
|
-
next unless path =~ /ruby-debug-ide|ruby-debug-base|linecache|debase/
|
5
|
-
$LOAD_PATH << path
|
6
|
-
end
|
7
|
-
require 'ruby-debug-ide'
|
8
|
-
require 'ruby-debug-ide/multiprocess'
|
9
|
-
Debugger::MultiProcess::do_monkey
|
10
|
-
Debugger::MultiProcess::pre_child
|
1
|
+
if ENV['IDE_PROCESS_DISPATCHER']
|
2
|
+
require 'rubygems'
|
3
|
+
ENV['DEBUGGER_STORED_RUBYLIB'].split(File::PATH_SEPARATOR).each do |path|
|
4
|
+
next unless path =~ /ruby-debug-ide|ruby-debug-base|linecache|debase/
|
5
|
+
$LOAD_PATH << path
|
6
|
+
end
|
7
|
+
require 'ruby-debug-ide'
|
8
|
+
require 'ruby-debug-ide/multiprocess'
|
9
|
+
Debugger::MultiProcess::do_monkey
|
10
|
+
Debugger::MultiProcess::pre_child
|
11
11
|
end
|