ruby-debug-ide22 0.7.4

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.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +75 -0
  3. data/ChangeLog.archive +1073 -0
  4. data/ChangeLog.md +594 -0
  5. data/Gemfile +38 -0
  6. data/MIT-LICENSE +24 -0
  7. data/Rakefile +93 -0
  8. data/bin/gdb_wrapper +96 -0
  9. data/bin/rdebug-ide +200 -0
  10. data/ext/mkrf_conf.rb +44 -0
  11. data/lib/ruby-debug-ide/attach/debugger_loader.rb +20 -0
  12. data/lib/ruby-debug-ide/attach/gdb.rb +73 -0
  13. data/lib/ruby-debug-ide/attach/lldb.rb +71 -0
  14. data/lib/ruby-debug-ide/attach/native_debugger.rb +133 -0
  15. data/lib/ruby-debug-ide/attach/process_thread.rb +54 -0
  16. data/lib/ruby-debug-ide/attach/util.rb +115 -0
  17. data/lib/ruby-debug-ide/command.rb +187 -0
  18. data/lib/ruby-debug-ide/commands/breakpoints.rb +128 -0
  19. data/lib/ruby-debug-ide/commands/catchpoint.rb +64 -0
  20. data/lib/ruby-debug-ide/commands/condition.rb +51 -0
  21. data/lib/ruby-debug-ide/commands/control.rb +158 -0
  22. data/lib/ruby-debug-ide/commands/enable.rb +203 -0
  23. data/lib/ruby-debug-ide/commands/eval.rb +64 -0
  24. data/lib/ruby-debug-ide/commands/expression_info.rb +71 -0
  25. data/lib/ruby-debug-ide/commands/file_filtering.rb +107 -0
  26. data/lib/ruby-debug-ide/commands/frame.rb +155 -0
  27. data/lib/ruby-debug-ide/commands/inspect.rb +25 -0
  28. data/lib/ruby-debug-ide/commands/jump.rb +73 -0
  29. data/lib/ruby-debug-ide/commands/load.rb +18 -0
  30. data/lib/ruby-debug-ide/commands/pause.rb +33 -0
  31. data/lib/ruby-debug-ide/commands/set_type.rb +47 -0
  32. data/lib/ruby-debug-ide/commands/stepping.rb +108 -0
  33. data/lib/ruby-debug-ide/commands/threads.rb +178 -0
  34. data/lib/ruby-debug-ide/commands/variables.rb +154 -0
  35. data/lib/ruby-debug-ide/event_processor.rb +71 -0
  36. data/lib/ruby-debug-ide/greeter.rb +42 -0
  37. data/lib/ruby-debug-ide/helper.rb +33 -0
  38. data/lib/ruby-debug-ide/ide_processor.rb +155 -0
  39. data/lib/ruby-debug-ide/interface.rb +45 -0
  40. data/lib/ruby-debug-ide/multiprocess/monkey.rb +47 -0
  41. data/lib/ruby-debug-ide/multiprocess/pre_child.rb +59 -0
  42. data/lib/ruby-debug-ide/multiprocess/starter.rb +11 -0
  43. data/lib/ruby-debug-ide/multiprocess/unmonkey.rb +31 -0
  44. data/lib/ruby-debug-ide/multiprocess.rb +23 -0
  45. data/lib/ruby-debug-ide/thread_alias.rb +27 -0
  46. data/lib/ruby-debug-ide/version.rb +3 -0
  47. data/lib/ruby-debug-ide/xml_printer.rb +571 -0
  48. data/lib/ruby-debug-ide.rb +228 -0
  49. data/ruby-debug-ide.gemspec +47 -0
  50. metadata +110 -0
@@ -0,0 +1,154 @@
1
+ module Debugger
2
+ class VarConstantCommand < Command # :nodoc:
3
+ def regexp
4
+ /^\s*v(?:ar)?\s+c(?:onst(?:ant)?)?\s+/
5
+ end
6
+
7
+ def execute
8
+ obj = debug_eval(@match.post_match)
9
+ unless obj.kind_of? Module
10
+ print_msg "Should be Class/Module: %s", @match.post_match
11
+ else
12
+ print_variables(obj.constants, "constant") do |var|
13
+ obj.const_get(var)
14
+ end
15
+ end
16
+ end
17
+
18
+ class << self
19
+ def help_command
20
+ 'var'
21
+ end
22
+
23
+ def help(cmd)
24
+ %{
25
+ v[ar] c[onst] <object>\t\tshow constants of object
26
+ }
27
+ end
28
+ end
29
+ end
30
+
31
+ class VarGlobalCommand < Command # :nodoc:
32
+ def regexp
33
+ /^\s*v(?:ar)?\s+g(?:lobal)?\s*$/
34
+ end
35
+
36
+ def execute
37
+ globals = []
38
+ if RUBY_VERSION < "1.9"
39
+ globals = global_variables - ['$=', '$IGNORECASE']
40
+ else
41
+ globals = global_variables - [:$KCODE, :$-K, :$=, :$IGNORECASE, :$FILENAME]
42
+ end
43
+ print_variables(globals, 'global') do |var|
44
+ debug_eval(var)
45
+ end
46
+ end
47
+
48
+ class << self
49
+ def help_command
50
+ 'var'
51
+ end
52
+
53
+ def help(cmd)
54
+ %{
55
+ v[ar] g[lobal]\t\t\tshow global variables
56
+ }
57
+ end
58
+ end
59
+ end
60
+
61
+ class VarInstanceCommand < Command # :nodoc:
62
+ # TODO: try to find out a way to use Kernel.binding for Rubinius
63
+ # ::Kernel.binding doesn't for for ruby 1.8 (see RUBY-14679)
64
+ BINDING_COMMAND = (defined?(Rubinius) || RUBY_VERSION < '1.9') ? 'binding' : '::Kernel.binding'
65
+
66
+ def regexp
67
+ # id will be read as first match, name as post match
68
+ /^\s*v(?:ar)?\s+i(?:nstance)?\s+((?:[\\+-]0x)[\dabcdef]+)?/
69
+ end
70
+
71
+ def execute
72
+ if (@match[1])
73
+ obj = ObjectSpace._id2ref(@match[1].hex) rescue nil
74
+
75
+ unless obj
76
+ print_element("variables")
77
+ @printer.print_msg("Unknown object id : %s", @match[1])
78
+ end
79
+ else
80
+ obj = debug_eval(@match.post_match)
81
+ end
82
+ return unless obj
83
+ if obj.is_a?(Array)
84
+ print_array(obj)
85
+ elsif obj.is_a?(Hash)
86
+ print_hash(obj)
87
+ elsif obj.is_a?(String)
88
+ print_string(obj)
89
+ else
90
+ print_element("variables") do
91
+ # instance variables
92
+ kind = 'instance'
93
+ inst_vars = obj.instance_variables
94
+ instance_binding = obj.instance_eval(BINDING_COMMAND)
95
+ # print self at top position
96
+ print_variable('self', debug_eval('self', instance_binding), kind) if inst_vars.include?('self')
97
+ inst_vars.sort.each do |var|
98
+ print_variable(var, debug_eval(var, instance_binding), kind) unless var == 'self'
99
+ end
100
+
101
+ # class variables
102
+ class_binding = obj.class.class_eval(BINDING_COMMAND)
103
+ obj.class.class_variables.sort.each do |var|
104
+ print_variable(var, debug_eval(var, class_binding), 'class')
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ class << self
111
+ def help_command
112
+ 'var'
113
+ end
114
+
115
+ def help(cmd)
116
+ %{
117
+ v[ar] i[nstance] <object>\tshow instance variables of object, object can be given by its id or an expression
118
+ }
119
+ end
120
+ end
121
+ end
122
+
123
+ class VarLocalCommand < Command # :nodoc:
124
+ def regexp
125
+ /^\s*v(?:ar)?\s+l(?:ocal)?\s*$/
126
+ end
127
+
128
+ def execute
129
+ locals = @state.context.frame_locals(@state.frame_pos)
130
+ _self = @state.context.frame_self(@state.frame_pos)
131
+ begin
132
+ locals['self'] = _self unless TOPLEVEL_BINDING.eval('self') == _self
133
+ rescue => ex
134
+ locals['self'] = "<Cannot evaluate self>"
135
+ $stderr << "Cannot evaluate self\n#{ex.class.name}: #{ex.message}\n #{ex.backtrace.join("\n ")}"
136
+ end
137
+ print_variables(locals.keys, 'local') do |var|
138
+ locals[var]
139
+ end
140
+ end
141
+
142
+ class << self
143
+ def help_command
144
+ 'var'
145
+ end
146
+
147
+ def help(cmd)
148
+ %{
149
+ v[ar] l[ocal]\t\t\tshow local variables
150
+ }
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,71 @@
1
+ require 'ruby-debug-ide/xml_printer'
2
+
3
+ module Debugger
4
+
5
+ class EventProcessor
6
+
7
+ attr_accessor :line, :file, :context
8
+
9
+ def initialize(interface)
10
+ @printer = XmlPrinter.new(interface)
11
+ @interface = interface
12
+ @line = nil
13
+ @file = nil
14
+ @last_breakpoint = nil
15
+ end
16
+
17
+ def at_breakpoint(context, breakpoint)
18
+ raise "@last_breakpoint supposed to be nil. is #{@last_breakpoint}" if @last_breakpoint
19
+ # at_breakpoint is immediately followed by #at_line event in
20
+ # ruby-debug-base. So postpone breakpoint printing until #at_line.
21
+ @last_breakpoint = breakpoint
22
+ end
23
+
24
+ def at_catchpoint(context, excpt)
25
+ @printer.print_catchpoint(excpt)
26
+ end
27
+
28
+ def at_tracing(context, file, line)
29
+ @printer.print_trace(context, file, line)
30
+ end
31
+
32
+ def at_line(context, file, line)
33
+ @printer.print_at_line(context, file, line) if context.nil? || context.stop_reason == :step
34
+ line_event(context, file, line)
35
+ end
36
+
37
+ def at_return(context, file, line)
38
+ @printer.print_at_line(context, file, line)
39
+ context.stop_frame = -1
40
+ line_event(context, file, line)
41
+ end
42
+
43
+ def line_event(context, file, line)
44
+ @line = line
45
+ @file = file
46
+ @context = context
47
+ if @last_breakpoint
48
+ # followed after #at_breakpoint in the same thread. Print breakpoint
49
+ # now when @line, @file and @context are correctly set to prevent race
50
+ # condition with `control thread'.
51
+ n = Debugger.breakpoints.index(@last_breakpoint) + 1
52
+ @printer.print_breakpoint n, @last_breakpoint
53
+ @last_breakpoint = nil
54
+ end
55
+ raise "DebuggerThread are not supposed to be traced (#{context.thread})" if context.thread.is_a?(Debugger::DebugThread)
56
+ @printer.print_debug("Stopping Thread %s (%s)", context.thread.to_s, Process.pid.to_s)
57
+ @printer.print_debug("Threads equal: %s", Thread.current == context.thread)
58
+ IdeCommandProcessor.new(@interface).process_commands
59
+ InspectCommand.clear_references
60
+ @printer.print_debug("Resumed Thread %s", context.thread.to_s)
61
+ @line = nil
62
+ @file = nil
63
+ @context = nil
64
+ end
65
+
66
+ def at_line?
67
+ @line
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,42 @@
1
+ if RUBY_VERSION < '2.0' || defined?(JRUBY_VERSION)
2
+ require 'ruby-debug-base'
3
+ else
4
+ require 'debase'
5
+ end
6
+
7
+ require 'ruby-debug-ide/version'
8
+ require 'ruby-debug-ide/ide_processor'
9
+
10
+ module Debugger
11
+
12
+ class << self
13
+ def print_greeting_msg(stream, host, port, debugger_name = "Fast", socket_path = nil)
14
+ base_gem_name = if defined?(JRUBY_VERSION) || RUBY_VERSION < '1.9.0'
15
+ 'ruby-debug-base'
16
+ elsif RUBY_VERSION < '2.0.0'
17
+ 'ruby-debug-base19x'
18
+ else
19
+ 'debase'
20
+ end
21
+
22
+ file_filtering_support = if Command.file_filter_supported?
23
+ 'supported'
24
+ else
25
+ 'not supported'
26
+ end
27
+
28
+ if host && port
29
+ listens_on = " listens on #{host}:#{port}\n"
30
+ elsif socket_path
31
+ listens_on = " listens on #{socket_path}\n"
32
+ else
33
+ listens_on = "\n"
34
+ end
35
+
36
+ msg = "#{debugger_name} Debugger (ruby-debug-ide #{IDE_VERSION}, #{base_gem_name} #{VERSION}, file filtering is #{file_filtering_support})" + listens_on
37
+
38
+ stream.printf msg
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,33 @@
1
+ module Debugger
2
+
3
+ module ParseFunctions
4
+ # Parse 'str' of command 'cmd' as an integer between
5
+ # min and max. If either min or max is nil, that
6
+ # value has no bound.
7
+ def get_int(str, cmd, min=nil, max=nil, default=1)
8
+ return default unless str
9
+ begin
10
+ int = Integer(str)
11
+ if min and int < min
12
+ print_error "%s argument '%s' needs to at least %s.\n" % [cmd, str, min]
13
+ return nil
14
+ elsif max and int > max
15
+ print_error "%s argument '%s' needs to at most %s.\n" % [cmd, str, max]
16
+ return nil
17
+ end
18
+ return int
19
+ rescue
20
+ print_error "%s argument '%s' needs to be a number.\n" % [cmd, str]
21
+ return nil
22
+ end
23
+ end
24
+
25
+ # Return true if code is syntactically correct for Ruby.
26
+ def syntax_valid?(code)
27
+ eval("BEGIN {return true}\n#{code}", nil, "", 0)
28
+ rescue Exception
29
+ false
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +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
@@ -0,0 +1,45 @@
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
+ def initialize(socket)
15
+ @socket = socket
16
+ @command_queue = Queue.new
17
+ end
18
+
19
+ def read_command
20
+ result = non_blocking_gets
21
+ raise IOError unless result
22
+ result.chomp
23
+ end
24
+
25
+ def print(*args)
26
+ @socket.printf(*args)
27
+ end
28
+
29
+ def close
30
+ @socket.close
31
+ rescue IOError, SystemCallError
32
+ end
33
+
34
+ # Workaround for JRuby issue http://jira.codehaus.org/browse/JRUBY-2063
35
+ def non_blocking_gets
36
+ loop do
37
+ result, _, _ = IO.select( [@socket], nil, nil, 0.2 )
38
+ next unless result
39
+ return result[0].gets
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +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
47
+ end
@@ -0,0 +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
59
+ end
@@ -0,0 +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
11
+ end
@@ -0,0 +1,31 @@
1
+ module Debugger
2
+ module MultiProcess
3
+ def self.restore_fork
4
+ %Q{
5
+ alias fork pre_debugger_fork
6
+ }
7
+ end
8
+
9
+ def self.restore_exec
10
+ %Q{
11
+ alias exec pre_debugger_exec
12
+ }
13
+ end
14
+ end
15
+ end
16
+
17
+ module Kernel
18
+ class << self
19
+ module_eval Debugger::MultiProcess.restore_fork
20
+ module_eval Debugger::MultiProcess.restore_exec
21
+ end
22
+ module_eval Debugger::MultiProcess.restore_fork
23
+ module_eval Debugger::MultiProcess.restore_exec
24
+ end
25
+
26
+ module Process
27
+ class << self
28
+ module_eval Debugger::MultiProcess.restore_fork
29
+ module_eval Debugger::MultiProcess.restore_exec
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ if RUBY_VERSION < '1.9'
2
+ require 'ruby-debug-ide/multiprocess/pre_child'
3
+ else
4
+ require_relative 'multiprocess/pre_child'
5
+ end
6
+
7
+ module Debugger
8
+ module MultiProcess
9
+ class << self
10
+ def do_monkey
11
+ load File.expand_path(File.dirname(__FILE__) + '/multiprocess/monkey.rb')
12
+ end
13
+
14
+ def undo_monkey
15
+ if ENV['IDE_PROCESS_DISPATCHER']
16
+ load File.expand_path(File.dirname(__FILE__) + '/multiprocess/unmonkey.rb')
17
+ ruby_opts = ENV['RUBYOPT'].split(' ')
18
+ ENV['RUBYOPT'] = ruby_opts.keep_if {|opt| !opt.end_with?('ruby-debug-ide/multiprocess/starter')}.join(' ')
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ module Debugger
2
+ module TimeoutHandler
3
+ class << self
4
+ def do_thread_alias
5
+ if defined? ::OldThread
6
+ Debugger.print_debug 'Tried to re-alias thread for eval'
7
+ return
8
+ end
9
+
10
+ Object.const_set :OldThread, ::Thread
11
+ Object.__send__ :remove_const, :Thread
12
+ Object.const_set :Thread, ::Debugger::DebugThread
13
+ end
14
+
15
+ def undo_thread_alias
16
+ unless defined? ::OldThread
17
+ Debugger.print_debug 'Tried to de-alias thread twice'
18
+ return
19
+ end
20
+
21
+ Object.__send__ :remove_const, :Thread
22
+ Object.const_set :Thread, ::OldThread
23
+ Object.__send__ :remove_const, :OldThread
24
+ end
25
+ end
26
+ end
27
+ end