ruby-debug-ide 0.4.17.beta9 → 0.4.17.beta12
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.
- data/Gemfile +1 -1
- data/bin/rdebug-ide +27 -5
- data/lib/ruby-debug-ide.rb +16 -5
- data/lib/ruby-debug-ide/event_processor.rb +1 -1
- data/lib/ruby-debug-ide/interface.rb +1 -0
- data/lib/ruby-debug-ide/multiprocess.rb +7 -0
- data/lib/ruby-debug-ide/multiprocess/monkey.rb +45 -0
- data/lib/ruby-debug-ide/multiprocess/pre_child.rb +72 -0
- data/lib/ruby-debug-ide/multiprocess/starter.rb +10 -0
- data/lib/ruby-debug-ide/version.rb +1 -1
- data/lib/ruby-debug-ide/xml_printer.rb +1 -1
- metadata +59 -28
data/Gemfile
CHANGED
data/bin/rdebug-ide
CHANGED
@@ -25,7 +25,9 @@ options = OpenStruct.new(
|
|
25
25
|
'load_mode' => false,
|
26
26
|
'port' => 1234,
|
27
27
|
'stop' => false,
|
28
|
-
'tracing' => false
|
28
|
+
'tracing' => false,
|
29
|
+
'int_handler' => true,
|
30
|
+
'dispatcher_port' => -1
|
29
31
|
)
|
30
32
|
|
31
33
|
opts = OptionParser.new do |opts|
|
@@ -37,7 +39,10 @@ EOB
|
|
37
39
|
opts.separator ""
|
38
40
|
opts.separator "Options:"
|
39
41
|
opts.on("-h", "--host HOST", "Host name used for remote debugging") {|host| options.host = host}
|
40
|
-
opts.on("-p", "--port PORT", Integer, "Port used for remote debugging") {|port| options.port = port}
|
42
|
+
opts.on("-p", "--port PORT", Integer, "Port used for remote debugging") {|port| options.port = port}
|
43
|
+
opts.on("--dispatcher-port PORT", Integer, "Port used for multi-process debugging dispatcher") do |dp|
|
44
|
+
options.dispatcher_port = dp
|
45
|
+
end
|
41
46
|
opts.on('--stop', 'stop when the script is loaded') {options.stop = true}
|
42
47
|
opts.on("-x", "--trace", "turn on line tracing") {options.tracing = true}
|
43
48
|
opts.on("-l", "--load-mode", "load mode (experimental)") {options.load_mode = true}
|
@@ -52,6 +57,7 @@ EOB
|
|
52
57
|
end
|
53
58
|
|
54
59
|
opts.on("--keep-frame-binding", "Keep frame bindings") {options.frame_bind = true}
|
60
|
+
opts.on("--disable-int-handler", "Disables interrupt signal handler") {options.int_handler = false}
|
55
61
|
opts.separator ""
|
56
62
|
opts.separator "Common options:"
|
57
63
|
opts.on_tail("-v", "--version", "Show version") do
|
@@ -84,9 +90,25 @@ end
|
|
84
90
|
|
85
91
|
# save script name
|
86
92
|
Debugger::PROG_SCRIPT = ARGV.shift
|
87
|
-
|
88
|
-
|
89
|
-
|
93
|
+
|
94
|
+
if (options.dispatcher_port != -1)
|
95
|
+
ENV['IDE_PROCESS_DISPATCHER'] = options.dispatcher_port.to_s
|
96
|
+
if RUBY_VERSION < "1.9"
|
97
|
+
require 'ruby-debug-ide/multiprocess'
|
98
|
+
else
|
99
|
+
require_relative '../lib/ruby-debug-ide/multiprocess'
|
100
|
+
end
|
101
|
+
|
102
|
+
ENV['DEBUGGER_STORED_RUBYLIB'] = ENV['RUBYLIB']
|
103
|
+
old_opts = ENV['RUBYOPT']
|
104
|
+
ENV['RUBYOPT'] = "-r#{File.expand_path(File.dirname(__FILE__))}/../lib/ruby-debug-ide/multiprocess/starter"
|
105
|
+
ENV['RUBYOPT'] += " #{old_opts}" if old_opts
|
106
|
+
end
|
107
|
+
|
108
|
+
if options.int_handler
|
109
|
+
# install interruption handler
|
110
|
+
trap('INT') { Debugger.interrupt_last }
|
111
|
+
end
|
90
112
|
|
91
113
|
# set options
|
92
114
|
Debugger.keep_frame_binding = options.frame_bind
|
data/lib/ruby-debug-ide.rb
CHANGED
@@ -15,6 +15,7 @@ module Debugger
|
|
15
15
|
# Prints to the stderr using printf(*args) if debug logging flag (-d) is on.
|
16
16
|
def print_debug(*args)
|
17
17
|
if Debugger.cli_debug
|
18
|
+
$stderr.printf("#{Process.pid}: ")
|
18
19
|
$stderr.printf(*args)
|
19
20
|
$stderr.printf("\n")
|
20
21
|
$stderr.flush
|
@@ -76,7 +77,8 @@ module Debugger
|
|
76
77
|
class << self
|
77
78
|
|
78
79
|
attr_accessor :event_processor, :cli_debug, :xml_debug
|
79
|
-
|
80
|
+
attr_accessor :control_thread
|
81
|
+
attr_reader :interface
|
80
82
|
|
81
83
|
#
|
82
84
|
# Interrupts the current thread
|
@@ -104,7 +106,7 @@ module Debugger
|
|
104
106
|
start_control(host, port)
|
105
107
|
end
|
106
108
|
|
107
|
-
def
|
109
|
+
def prepare_debugger(options)
|
108
110
|
start_server(options.host, options.port)
|
109
111
|
|
110
112
|
raise "Control thread did not start (#{@control_thread}}" unless @control_thread && @control_thread.alive?
|
@@ -116,7 +118,11 @@ module Debugger
|
|
116
118
|
@mutex.synchronize do
|
117
119
|
@proceed.wait(@mutex)
|
118
120
|
end
|
119
|
-
|
121
|
+
end
|
122
|
+
|
123
|
+
def debug_program(options)
|
124
|
+
prepare_debugger(options)
|
125
|
+
|
120
126
|
abs_prog_script = File.expand_path(Debugger::PROG_SCRIPT)
|
121
127
|
bt = debug_load(abs_prog_script, options.stop, options.load_mode)
|
122
128
|
if bt && !bt.is_a?(SystemExit)
|
@@ -143,13 +149,18 @@ module Debugger
|
|
143
149
|
$stderr.printf "Fast Debugger (ruby-debug-ide #{IDE_VERSION}, ruby-debug-base #{VERSION}) listens on #{host}:#{port}\n"
|
144
150
|
server = TCPServer.new(host, port)
|
145
151
|
while (session = server.accept)
|
152
|
+
$stderr.puts "Connected from #{session.addr[2]}" if Debugger.cli_debug
|
153
|
+
dispatcher = ENV['IDE_PROCESS_DISPATCHER']
|
154
|
+
if (dispatcher)
|
155
|
+
ENV['IDE_PROCESS_DISPATCHER'] = "#{session.addr[2]}:#{dispatcher}" unless dispatcher.include?(":")
|
156
|
+
end
|
146
157
|
begin
|
147
|
-
interface = RemoteInterface.new(session)
|
158
|
+
@interface = RemoteInterface.new(session)
|
148
159
|
@event_processor = EventProcessor.new(interface)
|
149
160
|
IdeControlCommandProcessor.new(interface).process_commands
|
150
161
|
rescue StandardError, ScriptError => ex
|
151
162
|
bt = ex.backtrace
|
152
|
-
$stderr.printf "Exception in DebugThread loop: #{ex.message}\nBacktrace:\n#{bt ? bt.join("\n from: ") : "<none>"}\n"
|
163
|
+
$stderr.printf "#{Process.pid}: Exception in DebugThread loop: #{ex.message}\nBacktrace:\n#{bt ? bt.join("\n from: ") : "<none>"}\n"
|
153
164
|
exit 1
|
154
165
|
end
|
155
166
|
end
|
@@ -53,7 +53,7 @@ require 'ruby-debug-ide/xml_printer'
|
|
53
53
|
@last_breakpoint = nil
|
54
54
|
end
|
55
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", context.thread.to_s)
|
56
|
+
@printer.print_debug("Stopping Thread %s (%s)", context.thread.to_s, Process.pid.to_s)
|
57
57
|
@printer.print_debug("Threads equal: %s", Thread.current == context.thread)
|
58
58
|
IdeCommandProcessor.new(@interface).process_commands
|
59
59
|
InspectCommand.clear_references
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Debugger
|
2
|
+
module MultiProcess
|
3
|
+
def self.create_mp_fork
|
4
|
+
%Q{
|
5
|
+
alias pre_debugger_fork fork
|
6
|
+
|
7
|
+
def fork(*args)
|
8
|
+
if block_given?
|
9
|
+
return pre_debugger_fork{Debugger::MultiProcess::pre_child; yield}
|
10
|
+
end
|
11
|
+
result = pre_debugger_fork
|
12
|
+
Debugger::MultiProcess::pre_child unless result
|
13
|
+
result
|
14
|
+
end
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.create_mp_exec
|
19
|
+
%Q{
|
20
|
+
alias pre_debugger_exec exec
|
21
|
+
|
22
|
+
def exec(*args)
|
23
|
+
Debugger.interface.close
|
24
|
+
pre_debugger_exec(*args)
|
25
|
+
end
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module Kernel
|
32
|
+
class << self
|
33
|
+
module_eval Debugger::MultiProcess.create_mp_fork
|
34
|
+
module_eval Debugger::MultiProcess.create_mp_exec
|
35
|
+
end
|
36
|
+
module_eval Debugger::MultiProcess.create_mp_fork
|
37
|
+
module_eval Debugger::MultiProcess.create_mp_exec
|
38
|
+
end
|
39
|
+
|
40
|
+
module Process
|
41
|
+
class << self
|
42
|
+
module_eval Debugger::MultiProcess.create_mp_fork
|
43
|
+
module_eval Debugger::MultiProcess.create_mp_exec
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Debugger
|
2
|
+
module MultiProcess
|
3
|
+
class << self
|
4
|
+
def pre_child
|
5
|
+
|
6
|
+
require "socket"
|
7
|
+
require "ostruct"
|
8
|
+
|
9
|
+
host = '127.0.0.1'
|
10
|
+
port = find_free_port(host)
|
11
|
+
|
12
|
+
options = OpenStruct.new(
|
13
|
+
'frame_bind' => false,
|
14
|
+
'host' => host,
|
15
|
+
'load_mode' => false,
|
16
|
+
'port' => port,
|
17
|
+
'stop' => false,
|
18
|
+
'tracing' => false,
|
19
|
+
'int_handler' => true
|
20
|
+
)
|
21
|
+
|
22
|
+
acceptor_host, acceptor_port = ENV['IDE_PROCESS_DISPATCHER'].split(":")
|
23
|
+
acceptor_host, acceptor_port = '127.0.0.1', acceptor_host unless acceptor_port
|
24
|
+
|
25
|
+
connected = false
|
26
|
+
3.times do |i|
|
27
|
+
begin
|
28
|
+
s = TCPSocket.open(acceptor_host, acceptor_port)
|
29
|
+
s.print(port)
|
30
|
+
s.close
|
31
|
+
connected = true
|
32
|
+
start_debugger(options)
|
33
|
+
return
|
34
|
+
rescue => bt
|
35
|
+
$stderr.puts "#{Process.pid}: connection failed(#{i+1})"
|
36
|
+
$stderr.puts "Exception: #{bt}"
|
37
|
+
$stderr.puts bt.backtrace.map { |l| "\t#{l}" }.join("\n")
|
38
|
+
sleep 0.3
|
39
|
+
end unless connected
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def start_debugger(options)
|
44
|
+
if Debugger.started?
|
45
|
+
#we're in forked child, only need to restart control thread
|
46
|
+
Debugger.breakpoints.clear
|
47
|
+
Debugger.control_thread = nil
|
48
|
+
Debugger.start_control(options.host, options.port)
|
49
|
+
end
|
50
|
+
|
51
|
+
if options.int_handler
|
52
|
+
# install interruption handler
|
53
|
+
trap('INT') { Debugger.interrupt_last }
|
54
|
+
end
|
55
|
+
|
56
|
+
# set options
|
57
|
+
Debugger.keep_frame_binding = options.frame_bind
|
58
|
+
Debugger.tracing = options.tracing
|
59
|
+
|
60
|
+
Debugger.prepare_debugger(options)
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
def find_free_port(host)
|
65
|
+
server = TCPServer.open(host, 0)
|
66
|
+
port = server.addr[1]
|
67
|
+
server.close
|
68
|
+
port
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,10 @@
|
|
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/
|
5
|
+
$LOAD_PATH << path
|
6
|
+
end
|
7
|
+
require 'ruby-debug-ide'
|
8
|
+
require 'ruby-debug-ide/multiprocess'
|
9
|
+
Debugger::MultiProcess::pre_child
|
10
|
+
end
|
@@ -92,7 +92,7 @@ module Debugger
|
|
92
92
|
|
93
93
|
def print_context(context)
|
94
94
|
current = 'current="yes"' if context.thread == Thread.current
|
95
|
-
print "<thread id=\"%s\" status=\"%s\" #{current}/>", context.thnum, context.thread.status
|
95
|
+
print "<thread id=\"%s\" status=\"%s\" pid=\"%s\" #{current}/>", context.thnum, context.thread.status, Process.pid
|
96
96
|
end
|
97
97
|
|
98
98
|
def print_variables(vars, kind)
|
metadata
CHANGED
@@ -1,38 +1,51 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-debug-ide
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 62196339
|
5
5
|
prerelease: 7
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 4
|
9
|
+
- 17
|
10
|
+
- beta
|
11
|
+
- 12
|
12
|
+
version: 0.4.17.beta12
|
6
13
|
platform: ruby
|
7
|
-
authors:
|
14
|
+
authors:
|
8
15
|
- Markus Barchfeld, Martin Krauskopf, Mark Moseley, JetBrains RubyMine Team
|
9
16
|
autorequire:
|
10
17
|
bindir: bin
|
11
18
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
19
|
+
|
20
|
+
date: 2012-06-07 00:00:00 Z
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
15
23
|
name: rake
|
16
|
-
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
17
26
|
none: false
|
18
|
-
requirements:
|
19
|
-
- -
|
20
|
-
- !ruby/object:Gem::Version
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 61
|
31
|
+
segments:
|
32
|
+
- 0
|
33
|
+
- 8
|
34
|
+
- 1
|
21
35
|
version: 0.8.1
|
22
36
|
type: :runtime
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
and RubyMine.
|
37
|
+
version_requirements: *id001
|
38
|
+
description: |
|
39
|
+
An interface which glues ruby-debug to IDEs like Eclipse (RDT), NetBeans and RubyMine.
|
27
40
|
|
28
|
-
'
|
29
41
|
email: rubymine-feedback@jetbrains.com
|
30
|
-
executables:
|
42
|
+
executables:
|
31
43
|
- rdebug-ide
|
32
|
-
extensions:
|
44
|
+
extensions:
|
33
45
|
- ext/mkrf_conf.rb
|
34
46
|
extra_rdoc_files: []
|
35
|
-
|
47
|
+
|
48
|
+
files:
|
36
49
|
- CHANGES
|
37
50
|
- ChangeLog
|
38
51
|
- ChangeLog.archive
|
@@ -62,31 +75,49 @@ files:
|
|
62
75
|
- lib/ruby-debug-ide/helper.rb
|
63
76
|
- lib/ruby-debug-ide/ide_processor.rb
|
64
77
|
- lib/ruby-debug-ide/interface.rb
|
78
|
+
- lib/ruby-debug-ide/multiprocess/monkey.rb
|
79
|
+
- lib/ruby-debug-ide/multiprocess/pre_child.rb
|
80
|
+
- lib/ruby-debug-ide/multiprocess/starter.rb
|
81
|
+
- lib/ruby-debug-ide/multiprocess.rb
|
65
82
|
- lib/ruby-debug-ide/version.rb
|
66
83
|
- lib/ruby-debug-ide/xml_printer.rb
|
67
84
|
- lib/ruby-debug-ide.rb
|
68
85
|
homepage: https://github.com/JetBrains/ruby-debug-ide
|
69
86
|
licenses: []
|
87
|
+
|
70
88
|
post_install_message:
|
71
89
|
rdoc_options: []
|
72
|
-
|
90
|
+
|
91
|
+
require_paths:
|
73
92
|
- lib
|
74
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
94
|
none: false
|
76
|
-
requirements:
|
77
|
-
- -
|
78
|
-
- !ruby/object:Gem::Version
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
hash: 51
|
99
|
+
segments:
|
100
|
+
- 1
|
101
|
+
- 8
|
102
|
+
- 2
|
79
103
|
version: 1.8.2
|
80
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
105
|
none: false
|
82
|
-
requirements:
|
83
|
-
- -
|
84
|
-
- !ruby/object:Gem::Version
|
106
|
+
requirements:
|
107
|
+
- - ">"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
hash: 25
|
110
|
+
segments:
|
111
|
+
- 1
|
112
|
+
- 3
|
113
|
+
- 1
|
85
114
|
version: 1.3.1
|
86
115
|
requirements: []
|
116
|
+
|
87
117
|
rubyforge_project: debug-commons
|
88
118
|
rubygems_version: 1.8.6
|
89
119
|
signing_key:
|
90
120
|
specification_version: 3
|
91
121
|
summary: IDE interface for ruby-debug.
|
92
122
|
test_files: []
|
123
|
+
|