ruby-debug-ide 0.6.1.beta2 → 0.6.1.beta3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c595acd0041d7e04f8a165c1c50538e1f9d30929
4
- data.tar.gz: 1448c05343af9063bdd3b51442e8067849e8cc45
3
+ metadata.gz: 425519e48f44723b8129340ee99f2a2741aaa07c
4
+ data.tar.gz: 99cd5ba804e4884644ac5d38465a8ab1f73cd40f
5
5
  SHA512:
6
- metadata.gz: 61810c4fac4c0f03b155063ccc06e0012ddb34c5c38990e0570a0c91069780f1ea907bf63a2578c8878a30ad29b0fe914d7ab5911094856182555d114005d7dd
7
- data.tar.gz: a40a067d48e1c5444d94559a783f1173bdd5670a23d0d7e2161a1bea450a63f91dba56b47b7af8c2ff30408203200a61e8b4abacfc405d6a5b28dc3671ca5797
6
+ metadata.gz: c2a4de25b4516fc011791b0d6572e57f52d06335b03b1225deb5c771bbd6cf25db7d954424f916e099f4f961719f933855e875be11f04f14a34454cdf8d638c7
7
+ data.tar.gz: 5836a80d9904b1b08b87f33b77f2806a1a3bbdc57b4a2697766bbd6c7f2ffda888fe5d2c2573b49b48cab849208a7aba699f03bdb6e97e6d2807187283ce25d0
data/bin/gdb_wrapper ADDED
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'ostruct'
5
+
6
+ $stdout.sync = true
7
+ $stderr.sync = true
8
+
9
+ options = OpenStruct.new(
10
+ 'pid' => nil,
11
+ 'sdk_path' => nil,
12
+ 'uid' => nil,
13
+ 'gems_to_include' => []
14
+ )
15
+
16
+ module DebugPrinter
17
+
18
+ class << self
19
+ attr_accessor :cli_debug
20
+
21
+ def print_debug(msg)
22
+ if DebugPrinter.cli_debug
23
+ $stderr.puts msg
24
+ end
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ DebugPrinter.cli_debug = ARGV.include? '--debug'
31
+
32
+ opts = OptionParser.new do |opts|
33
+ # TODO need some banner
34
+ opts.banner = <<EOB
35
+ Some useful banner.
36
+ EOB
37
+
38
+ opts.on('--pid PID', 'pid of process you want to attach to for debugging') do |pid|
39
+ options.pid = pid
40
+ end
41
+
42
+ opts.on('--ruby-path RUBY_PATH', 'path to ruby interpreter') do |ruby_path|
43
+ options.ruby_path = ruby_path
44
+ end
45
+
46
+ opts.on('--uid UID', 'uid which this process should set after executing gdb attach') do |uid|
47
+ options.uid = uid
48
+ end
49
+
50
+ opts.on('--include-gem GEM_LIB_PATH', 'lib of gem to include') do |gem_lib_path|
51
+ options.gems_to_include << gem_lib_path
52
+ end
53
+ end
54
+
55
+ opts.parse! ARGV
56
+
57
+ unless options.pid
58
+ $stderr.puts 'You should specify PID of process you want to attach to'
59
+ exit 1
60
+ end
61
+
62
+ unless options.ruby_path
63
+ $stderr.puts 'You should specify path to the ruby interpreter'
64
+ exit 1
65
+ end
66
+
67
+ argv = '["' + ARGV * '", "' + '"]'
68
+ debugger_loader_path = File.expand_path(File.dirname(__FILE__)) + '/../lib/ruby-debug-ide/attach/debugger_loader'
69
+
70
+ options.gems_to_include.each do |gem_path|
71
+ $LOAD_PATH.unshift(gem_path) unless $LOAD_PATH.include?(gem_path)
72
+ end
73
+
74
+ require 'ruby-debug-ide/greeter'
75
+ Debugger::print_greeting_msg($stdout, nil, nil)
76
+
77
+ require 'ruby-debug-ide/attach/util'
78
+ require 'ruby-debug-ide/attach/native_debugger'
79
+ require 'ruby-debug-ide/attach/process_thread'
80
+
81
+ debugger = choose_debugger(options.ruby_path, options.pid, options.gems_to_include, debugger_loader_path, argv)
82
+
83
+ trap('INT') do
84
+ unless debugger.exited?
85
+ $stderr.puts "backtraces for threads:\n\n"
86
+ process_threads = debugger.process_threads
87
+ if process_threads
88
+ process_threads.each do |thread|
89
+ $stderr.puts "#{thread.thread_info}\n#{thread.last_bt}\n\n"
90
+ end
91
+ end
92
+ debugger.exit
93
+ end
94
+ exit!
95
+ end
96
+
97
+ debugger.attach_to_process
98
+ debugger.set_flags
99
+
100
+ if options.uid
101
+ DebugPrinter.print_debug("changing current uid from #{Process.uid} to #{options.uid}")
102
+ Process::Sys.setuid(options.uid.to_i)
103
+ end
104
+
105
+ if debugger.check_already_under_debug
106
+ $stderr.puts "Process #{debugger.pid} is already under debug"
107
+ debugger.exit
108
+ exit!
109
+ end
110
+
111
+ should_check_threads_state = true
112
+
113
+ while should_check_threads_state
114
+ should_check_threads_state = false
115
+ debugger.update_threads.each do |thread|
116
+ thread.switch
117
+ while thread.need_finish_frame
118
+ should_check_threads_state = true
119
+ thread.finish
120
+ end
121
+ end
122
+ end
123
+
124
+ debugger.wait_line_event
125
+ debugger.load_debugger
126
+ debugger.exit
127
+
128
+ sleep
data/bin/rdebug-ide CHANGED
@@ -22,7 +22,9 @@ options = OpenStruct.new(
22
22
  'evaluation_timeout' => 10,
23
23
  'rm_protocol_extensions' => false,
24
24
  'catchpoint_deleted_event' => false,
25
- 'value_as_nested_element' => false
25
+ 'value_as_nested_element' => false,
26
+ 'attach_mode' => false,
27
+ 'cli_debug' => false
26
28
  )
27
29
 
28
30
  opts = OptionParser.new do |opts|
@@ -47,6 +49,7 @@ EOB
47
49
  opts.on("-l", "--load-mode", "load mode (experimental)") {options.load_mode = true}
48
50
  opts.on("-d", "--debug", "Debug self - prints information for debugging ruby-debug itself") do
49
51
  Debugger.cli_debug = true
52
+ options.cli_debug = true
50
53
  end
51
54
  opts.on("--xml-debug", "Debug self - sends information <message>s for debugging ruby-debug itself") do
52
55
  Debugger.xml_debug = true
@@ -54,7 +57,9 @@ EOB
54
57
  opts.on("-I", "--include PATH", String, "Add PATH to $LOAD_PATH") do |path|
55
58
  $LOAD_PATH.unshift(path)
56
59
  end
57
-
60
+ opts.on("--attach-mode", "Tells that rdebug-ide is working in attach mode") do
61
+ options.attach_mode = true
62
+ end
58
63
  opts.on("--keep-frame-binding", "Keep frame bindings") {options.frame_bind = true}
59
64
  opts.on("--disable-int-handler", "Disables interrupt signal handler") {options.int_handler = false}
60
65
  opts.on("--rubymine-protocol-extensions", "Enable all RubyMine-specific incompatible protocol extensions") do
@@ -89,29 +94,37 @@ rescue StandardError => e
89
94
  exit(1)
90
95
  end
91
96
 
92
- if ARGV.empty?
97
+ if ARGV.empty? && !options.attach_mode
93
98
  puts opts
94
99
  puts
95
100
  puts "Must specify a script to run"
96
101
  exit(1)
97
- end
102
+ end
98
103
 
99
104
  # save script name
100
- Debugger::PROG_SCRIPT = ARGV.shift
105
+ if !options.attach_mode
106
+ Debugger::PROG_SCRIPT = ARGV.shift
107
+ else
108
+ Debugger::PROG_SCRIPT = $0
109
+ end
101
110
 
102
111
  if options.dispatcher_port != -1
103
112
  ENV['IDE_PROCESS_DISPATCHER'] = options.dispatcher_port.to_s
104
113
  if RUBY_VERSION < "1.9"
105
- $: << File.expand_path(File.dirname(__FILE__) + "/../lib/")
114
+ lib_path = File.expand_path(File.dirname(__FILE__) + "/../lib/")
115
+ $: << lib_path unless $:.include? lib_path
106
116
  require 'ruby-debug-ide/multiprocess'
107
117
  else
108
118
  require_relative '../lib/ruby-debug-ide/multiprocess'
109
119
  end
110
120
 
111
121
  ENV['DEBUGGER_STORED_RUBYLIB'] = ENV['RUBYLIB']
112
- old_opts = ENV['RUBYOPT']
113
- ENV['RUBYOPT'] = "-r#{File.expand_path(File.dirname(__FILE__))}/../lib/ruby-debug-ide/multiprocess/starter"
114
- ENV['RUBYOPT'] += " #{old_opts}" if old_opts
122
+ old_opts = ENV['RUBYOPT'] || ''
123
+ starter = "-r#{File.expand_path(File.dirname(__FILE__))}/../lib/ruby-debug-ide/multiprocess/starter"
124
+ unless old_opts.include? starter
125
+ ENV['RUBYOPT'] = starter
126
+ ENV['RUBYOPT'] += " #{old_opts}" if old_opts != ''
127
+ end
115
128
  ENV['DEBUGGER_CLI_DEBUG'] = Debugger.cli_debug.to_s
116
129
  end
117
130
 
@@ -119,7 +132,7 @@ if options.int_handler
119
132
  # install interruption handler
120
133
  trap('INT') { Debugger.interrupt_last }
121
134
  end
122
-
135
+
123
136
  # set options
124
137
  Debugger.keep_frame_binding = options.frame_bind
125
138
  Debugger.tracing = options.tracing
@@ -127,5 +140,19 @@ Debugger.evaluation_timeout = options.evaluation_timeout
127
140
  Debugger.catchpoint_deleted_event = options.catchpoint_deleted_event || options.rm_protocol_extensions
128
141
  Debugger.value_as_nested_element = options.value_as_nested_element || options.rm_protocol_extensions
129
142
 
130
- Debugger.debug_program(options)
143
+ Debugger.attached = true
131
144
 
145
+ if options.attach_mode
146
+ if Debugger::FRONT_END == "debase"
147
+ Debugger.init_variables
148
+ end
149
+
150
+ Debugger::MultiProcess::pre_child(options)
151
+
152
+ if Debugger::FRONT_END == "debase"
153
+ Debugger.setup_tracepoints
154
+ Debugger.prepare_context
155
+ end
156
+ else
157
+ Debugger.debug_program(options)
158
+ end
@@ -4,11 +4,13 @@ require "socket"
4
4
  require 'thread'
5
5
  if RUBY_VERSION < '2.0' || defined?(JRUBY_VERSION)
6
6
  require 'ruby-debug-base'
7
+ Debugger::FRONT_END = "ruby-debug-base"
7
8
  else
8
9
  require 'debase'
10
+ Debugger::FRONT_END = "debase"
9
11
  end
10
12
 
11
- require 'ruby-debug-ide/version'
13
+ require 'ruby-debug-ide/greeter'
12
14
  require 'ruby-debug-ide/xml_printer'
13
15
  require 'ruby-debug-ide/ide_processor'
14
16
  require 'ruby-debug-ide/event_processor'
@@ -41,6 +43,7 @@ module Debugger
41
43
  cleared
42
44
  end
43
45
 
46
+ attr_accessor :attached
44
47
  attr_accessor :cli_debug, :xml_debug, :evaluation_timeout
45
48
  attr_accessor :control_thread
46
49
  attr_reader :interface
@@ -108,9 +111,8 @@ module Debugger
108
111
  # "localhost" and nil have problems on some systems.
109
112
  host ||= '127.0.0.1'
110
113
  server = TCPServer.new(host, port)
111
- print_greeting_msg(host, port)
114
+ print_greeting_msg($stderr, host, port)
112
115
  notify_dispatcher(port) if notify_dispatcher
113
-
114
116
  while (session = server.accept)
115
117
  $stderr.puts "Connected from #{session.peeraddr[2]}" if Debugger.cli_debug
116
118
  dispatcher = ENV['IDE_PROCESS_DISPATCHER']
@@ -136,23 +138,6 @@ module Debugger
136
138
  end
137
139
  end
138
140
 
139
- def print_greeting_msg(host, port)
140
- base_gem_name = if defined?(JRUBY_VERSION) || RUBY_VERSION < '1.9.0'
141
- 'ruby-debug-base'
142
- elsif RUBY_VERSION < '2.0.0'
143
- 'ruby-debug-base19x'
144
- else
145
- 'debase'
146
- end
147
-
148
- file_filtering_support = if Command.file_filter_supported?
149
- 'supported'
150
- else
151
- 'not supported'
152
- end
153
- $stderr.printf "Fast Debugger (ruby-debug-ide #{IDE_VERSION}, #{base_gem_name} #{VERSION}, file filtering is #{file_filtering_support}) listens on #{host}:#{port}\n"
154
- end
155
-
156
141
  private
157
142
 
158
143
 
@@ -160,8 +145,8 @@ module Debugger
160
145
  return unless ENV['IDE_PROCESS_DISPATCHER']
161
146
  acceptor_host, acceptor_port = ENV['IDE_PROCESS_DISPATCHER'].split(":")
162
147
  acceptor_host, acceptor_port = '127.0.0.1', acceptor_host unless acceptor_port
163
-
164
148
  connected = false
149
+
165
150
  3.times do |i|
166
151
  begin
167
152
  s = TCPSocket.open(acceptor_host, acceptor_port)
@@ -0,0 +1,20 @@
1
+ def load_debugger(gems_to_include, new_argv)
2
+ path_to_rdebug = File.expand_path(File.dirname(__FILE__)) + '/../../../bin/rdebug-ide'
3
+
4
+ old_argv = ARGV.clone
5
+ ARGV.clear
6
+ new_argv.each do |x|
7
+ ARGV << x
8
+ end
9
+
10
+ gems_to_include.each do |gem_path|
11
+ $LOAD_PATH.unshift(gem_path) unless $LOAD_PATH.include?(gem_path)
12
+ end
13
+
14
+ load path_to_rdebug
15
+
16
+ ARGV.clear
17
+ old_argv.each do |x|
18
+ ARGV << x
19
+ end
20
+ end
@@ -0,0 +1,73 @@
1
+ require 'ruby-debug-ide/attach/native_debugger'
2
+
3
+ class GDB < NativeDebugger
4
+
5
+ def initialize(executable, pid, flags, gems_to_include, debugger_loader_path, argv)
6
+ super(executable, pid, flags, gems_to_include, debugger_loader_path, argv)
7
+ end
8
+
9
+ def set_flags
10
+ execute 'set scheduler-locking off' # we will deadlock with it
11
+ execute 'set unwindonsignal on' # in case of some signal we will exit gdb
12
+ end
13
+
14
+ def update_threads
15
+ @process_threads = []
16
+ info_threads = (execute 'info threads').split("\n")
17
+ info_threads.each do |thread_info|
18
+ next unless thread_info =~ /[\s*]*\d+\s+Thread.*/
19
+ $stdout.puts "thread_info: #{thread_info}"
20
+ is_main = thread_info[0] == '*'
21
+ thread_num = thread_info.sub(/[\s*]*/, '').sub(/\s.*$/, '').to_i
22
+ thread = ProcessThread.new(thread_num, is_main, thread_info, self)
23
+ if thread.is_main
24
+ @main_thread = thread
25
+ end
26
+ @process_threads << thread
27
+ end
28
+ @process_threads
29
+ end
30
+
31
+ def check_already_under_debug
32
+ threads = execute 'info threads'
33
+ threads =~ /ruby-debug-ide/
34
+ end
35
+
36
+ def switch_to_thread(thread_num)
37
+ execute "thread #{thread_num}"
38
+ end
39
+
40
+ def set_break(str)
41
+ execute "tbreak #{str}"
42
+ end
43
+
44
+ def call_start_attach
45
+ super()
46
+ execute "call dlopen(\"#{@path_to_attach}\", 2)"
47
+ execute 'call debase_start_attach()'
48
+ set_break(@tbreak)
49
+ end
50
+
51
+ def print_delimiter
52
+ @pipe.puts "print \"#{@delimiter}\""
53
+ end
54
+
55
+ def check_delimiter(line)
56
+ line =~ /\$\d+\s=\s"#{@delimiter}"/
57
+ end
58
+
59
+ def load_debugger
60
+ execute "call #{@eval_string}"
61
+ end
62
+
63
+ def to_s
64
+ GDB.to_s
65
+ end
66
+
67
+ class << self
68
+ def to_s
69
+ 'gdb'
70
+ end
71
+ end
72
+
73
+ end
@@ -0,0 +1,71 @@
1
+ require 'ruby-debug-ide/attach/native_debugger'
2
+
3
+ class LLDB < NativeDebugger
4
+
5
+ def initialize(executable, pid, flags, gems_to_include, debugger_loader_path, argv)
6
+ super(executable, pid, flags, gems_to_include, debugger_loader_path, argv)
7
+ end
8
+
9
+ def set_flags
10
+
11
+ end
12
+
13
+ def update_threads
14
+ @process_threads = []
15
+ info_threads = (execute 'thread list').split("\n")
16
+ info_threads.each do |thread_info|
17
+ next unless thread_info =~ /[\s*]*thread\s#\d+.*/
18
+ is_main = thread_info[0] == '*'
19
+ thread_num = thread_info.sub(/[\s*]*thread\s#/, '').sub(/:\s.*$/, '').to_i
20
+ thread = ProcessThread.new(thread_num, is_main, thread_info, self)
21
+ if thread.is_main
22
+ @main_thread = thread
23
+ end
24
+ @process_threads << thread
25
+ end
26
+ @process_threads
27
+ end
28
+
29
+ def check_already_under_debug
30
+ threads = execute 'thread list'
31
+ threads =~ /ruby-debug-ide/
32
+ end
33
+
34
+ def switch_to_thread(thread_num)
35
+ execute "thread select #{thread_num}"
36
+ end
37
+
38
+ def set_break(str)
39
+ execute "breakpoint set --shlib #{@path_to_attach} --name #{str}"
40
+ end
41
+
42
+ def call_start_attach
43
+ super()
44
+ execute "expr (void *) dlopen(\"#{@path_to_attach}\", 2)"
45
+ execute 'expr (int) debase_start_attach()'
46
+ set_break(@tbreak)
47
+ end
48
+
49
+ def print_delimiter
50
+ @pipe.puts "script print \"#{@delimiter}\""
51
+ end
52
+
53
+ def check_delimiter(line)
54
+ line =~ /#{@delimiter}$/
55
+ end
56
+
57
+ def load_debugger
58
+ execute "expr (void) #{@eval_string}"
59
+ end
60
+
61
+ def to_s
62
+ LLDB.to_s
63
+ end
64
+
65
+ class << self
66
+ def to_s
67
+ 'lldb'
68
+ end
69
+ end
70
+
71
+ end
@@ -0,0 +1,133 @@
1
+ class NativeDebugger
2
+
3
+ attr_reader :pid, :main_thread, :process_threads, :pipe
4
+
5
+ # @param executable -- path to ruby interpreter
6
+ # @param pid -- pid of process you want to debug
7
+ # @param flags -- flags you want to specify to your debugger as a string (e.g. "-nx -nh" for gdb to disable .gdbinit)
8
+ def initialize(executable, pid, flags, gems_to_include, debugger_loader_path, argv)
9
+ @pid = pid
10
+ @delimiter = '__OUTPUT_FINISHED__' # for getting response
11
+ @tbreak = '__func_to_set_breakpoint_at'
12
+ @main_thread = nil
13
+ @process_threads = nil
14
+ debase_path = gems_to_include.select {|gem_path| gem_path =~ /debase/}
15
+ if debase_path.size == 0
16
+ raise 'No debase gem found.'
17
+ end
18
+ @path_to_attach = find_attach_lib(debase_path[0])
19
+
20
+ @gems_to_include = '["' + gems_to_include * '", "' + '"]'
21
+ @debugger_loader_path = debugger_loader_path
22
+ @argv = argv
23
+
24
+ @eval_string = "debase_rb_eval(\"require '#{@debugger_loader_path}'; load_debugger(#{@gems_to_include.gsub("\"", "'")}, #{@argv.gsub("\"", "'")})\")"
25
+
26
+ launch_string = "#{self} #{executable} #{flags}"
27
+ @pipe = IO.popen(launch_string, 'r+')
28
+ $stdout.puts "executed '#{launch_string}'"
29
+ end
30
+
31
+ def find_attach_lib(debase_path)
32
+ attach_lib = debase_path + '/attach'
33
+ known_extensions = %w(.so .bundle .dll .dylib)
34
+ known_extensions.each do |ext|
35
+ if File.file?(attach_lib + ext)
36
+ return attach_lib + ext
37
+ end
38
+ end
39
+
40
+ raise 'Could not find attach library'
41
+ end
42
+
43
+ def attach_to_process
44
+ execute "attach #{@pid}"
45
+ end
46
+
47
+ def execute(command)
48
+ @pipe.puts command
49
+ $stdout.puts "executed `#{command}` command inside #{self}."
50
+ if command == 'q'
51
+ return ''
52
+ end
53
+ get_response
54
+ end
55
+
56
+ def get_response
57
+ # we need this hack to understand that debugger gave us all output from last executed command
58
+ print_delimiter
59
+
60
+ content = ''
61
+ loop do
62
+ line = @pipe.readline
63
+ DebugPrinter.print_debug('respond line: ' + line)
64
+ break if check_delimiter(line)
65
+ next if line =~ /\(lldb\)/ # lldb repeats your input to its output
66
+ content += line
67
+ end
68
+
69
+ content
70
+ end
71
+
72
+ def update_threads
73
+
74
+ end
75
+
76
+ def check_already_under_debug
77
+
78
+ end
79
+
80
+ def print_delimiter
81
+
82
+ end
83
+
84
+ def check_delimiter(line)
85
+
86
+ end
87
+
88
+ def switch_to_thread
89
+
90
+ end
91
+
92
+ def set_break(str)
93
+
94
+ end
95
+
96
+ def continue
97
+ $stdout.puts 'continuing'
98
+ @pipe.puts 'c'
99
+ loop do
100
+ line = @pipe.readline
101
+ DebugPrinter.print_debug('respond line: ' + line)
102
+ break if line =~ /#{Regexp.escape(@tbreak)}/
103
+ end
104
+ get_response
105
+ end
106
+
107
+ def call_start_attach
108
+ raise 'No main thread found. Did you forget to call `update_threads`?' if @main_thread == nil
109
+ @main_thread.switch
110
+ end
111
+
112
+ def wait_line_event
113
+ call_start_attach
114
+ continue
115
+ end
116
+
117
+ def load_debugger
118
+
119
+ end
120
+
121
+ def exited?
122
+ @pipe.closed?
123
+ end
124
+
125
+ def exit
126
+ @pipe.close
127
+ end
128
+
129
+ def to_s
130
+ 'native_debugger'
131
+ end
132
+
133
+ end
@@ -0,0 +1,54 @@
1
+ require 'ruby-debug-ide/attach/native_debugger'
2
+
3
+ class ProcessThread
4
+
5
+ attr_reader :thread_num, :is_main, :thread_info, :last_bt
6
+
7
+ def initialize(thread_num, is_main, thread_info, native_debugger)
8
+ @thread_num = thread_num
9
+ @is_main = is_main
10
+ @native_debugger = native_debugger
11
+ @thread_info = thread_info
12
+ @last_bt = nil
13
+ end
14
+
15
+ def switch
16
+ @native_debugger.switch_to_thread(thread_num)
17
+ end
18
+
19
+ def finish
20
+ @native_debugger.execute 'finish'
21
+ end
22
+
23
+ def get_bt
24
+ @last_bt = @native_debugger.execute 'bt'
25
+ end
26
+
27
+ def any_caller_match(bt, pattern)
28
+ bt =~ /#{pattern}/
29
+ end
30
+
31
+ def is_inside_malloc(bt = get_bt)
32
+ if any_caller_match(bt, '(malloc)')
33
+ $stderr.puts "process #{@native_debugger.pid} is currently inside malloc."
34
+ true
35
+ else
36
+ false
37
+ end
38
+ end
39
+
40
+ def is_inside_gc(bt = get_bt)
41
+ if any_caller_match(bt, '(gc\.c)')
42
+ $stderr.puts "process #{@native_debugger.pid} is currently in garbage collection phase."
43
+ true
44
+ else
45
+ false
46
+ end
47
+ end
48
+
49
+ def need_finish_frame
50
+ bt = get_bt
51
+ is_inside_malloc(bt) || is_inside_gc(bt)
52
+ end
53
+
54
+ end
@@ -0,0 +1,25 @@
1
+ require 'ruby-debug-ide/attach/lldb'
2
+ require 'ruby-debug-ide/attach/gdb'
3
+
4
+ def command_exists(command)
5
+ checking_command = "checking command #{command} for existence\n"
6
+ `command -v #{command} >/dev/null 2>&1 || { exit 1; }`
7
+ if $?.exitstatus != 0
8
+ DebugPrinter.print_debug("#{checking_command}command does not exist.")
9
+ else
10
+ DebugPrinter.print_debug("#{checking_command}command does exist.")
11
+ end
12
+ $?.exitstatus == 0
13
+ end
14
+
15
+ def choose_debugger(ruby_path, pid, gems_to_include, debugger_loader_path, argv)
16
+ if command_exists(LLDB.to_s)
17
+ debugger = LLDB.new(ruby_path, pid, '--no-lldbinit', gems_to_include, debugger_loader_path, argv)
18
+ elsif command_exists(GDB.to_s)
19
+ debugger = GDB.new(ruby_path, pid, '-nh -nx', gems_to_include, debugger_loader_path, argv)
20
+ else
21
+ raise 'Neither gdb nor lldb was found. Aborting.'
22
+ end
23
+
24
+ debugger
25
+ end
@@ -0,0 +1 @@
1
+ sh foo.sh
@@ -126,4 +126,33 @@ module Debugger
126
126
  end
127
127
  end
128
128
  end
129
+
130
+
131
+ class DetachCommand < Command # :nodoc:
132
+ self.control = true
133
+
134
+ def regexp
135
+ /^\s*detach\s*$/
136
+ end
137
+
138
+ def execute
139
+ Debugger.attached = false
140
+ Debugger.stop
141
+ Debugger.interface.close
142
+ Debugger.control_thread = nil
143
+ Thread.current.exit #@control_thread is a current thread
144
+ end
145
+
146
+ class << self
147
+ def help_command
148
+ 'detach'
149
+ end
150
+
151
+ def help(cmd)
152
+ %{
153
+ detach\ndetach debugger\nnote: this option is only for remote debugging (or local attach)
154
+ }
155
+ end
156
+ end
157
+ end
129
158
  end
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ echo a;
3
+ echo a;
4
+ echo a
@@ -0,0 +1,40 @@
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)
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
+ else
31
+ listens_on = "\n"
32
+ end
33
+
34
+ msg = "Fast Debugger (ruby-debug-ide #{IDE_VERSION}, #{base_gem_name} #{VERSION}, file filtering is #{file_filtering_support})" + listens_on
35
+
36
+ stream.printf msg
37
+ end
38
+ end
39
+
40
+ end
@@ -77,7 +77,6 @@ module Debugger
77
77
  ctrl_cmd_classes = Command.commands.select{|cmd| cmd.control}
78
78
  state = ControlState.new(@interface)
79
79
  ctrl_cmds = ctrl_cmd_classes.map{|cmd| cmd.new(state, @printer)}
80
-
81
80
  while input = @interface.read_command
82
81
  # escape % since print_debug might use printf
83
82
  # sleep 0.3
@@ -1,19 +1,19 @@
1
1
  module Debugger
2
2
  module MultiProcess
3
3
  class << self
4
- def pre_child
4
+ def pre_child(options = nil)
5
+ return unless Debugger.attached
5
6
 
6
7
  require 'socket'
7
8
  require 'ostruct'
8
9
 
9
10
  host = ENV['DEBUGGER_HOST']
10
- port = find_free_port(host)
11
11
 
12
- options = OpenStruct.new(
12
+ options ||= OpenStruct.new(
13
13
  'frame_bind' => false,
14
14
  'host' => host,
15
15
  'load_mode' => false,
16
- 'port' => port,
16
+ 'port' => find_free_port(host),
17
17
  'stop' => false,
18
18
  'tracing' => false,
19
19
  'int_handler' => true,
@@ -1,3 +1,3 @@
1
1
  module Debugger
2
- IDE_VERSION='0.6.1.beta2'
2
+ IDE_VERSION='0.6.1.beta3'
3
3
  end
@@ -36,7 +36,7 @@ EOF
36
36
  spec.platform = Gem::Platform::RUBY
37
37
  spec.require_path = "lib"
38
38
  spec.bindir = "bin"
39
- spec.executables = ["rdebug-ide"]
39
+ spec.executables = ["rdebug-ide", "gdb_wrapper"]
40
40
  spec.files = FILES
41
41
 
42
42
  spec.extensions << "ext/mkrf_conf.rb" unless ENV['NO_EXT']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-debug-ide
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1.beta2
4
+ version: 0.6.1.beta3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Barchfeld, Martin Krauskopf, Mark Moseley, JetBrains RubyMine Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-21 00:00:00.000000000 Z
11
+ date: 2016-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -24,13 +24,12 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.8.1
27
- description: 'An interface which glues ruby-debug to IDEs like Eclipse (RDT), NetBeans
28
- and RubyMine.
29
-
30
- '
27
+ description: |
28
+ An interface which glues ruby-debug to IDEs like Eclipse (RDT), NetBeans and RubyMine.
31
29
  email: rubymine-feedback@jetbrains.com
32
30
  executables:
33
31
  - rdebug-ide
32
+ - gdb_wrapper
34
33
  extensions:
35
34
  - ext/mkrf_conf.rb
36
35
  extra_rdoc_files: []
@@ -41,9 +40,17 @@ files:
41
40
  - Gemfile
42
41
  - MIT-LICENSE
43
42
  - Rakefile
43
+ - bin/gdb_wrapper
44
44
  - bin/rdebug-ide
45
45
  - ext/mkrf_conf.rb
46
46
  - lib/ruby-debug-ide.rb
47
+ - lib/ruby-debug-ide/attach/debugger_loader.rb
48
+ - lib/ruby-debug-ide/attach/gdb.rb
49
+ - lib/ruby-debug-ide/attach/lldb.rb
50
+ - lib/ruby-debug-ide/attach/native_debugger.rb
51
+ - lib/ruby-debug-ide/attach/process_thread.rb
52
+ - lib/ruby-debug-ide/attach/util.rb
53
+ - lib/ruby-debug-ide/boo.sh
47
54
  - lib/ruby-debug-ide/command.rb
48
55
  - lib/ruby-debug-ide/commands/breakpoints.rb
49
56
  - lib/ruby-debug-ide/commands/catchpoint.rb
@@ -63,6 +70,8 @@ files:
63
70
  - lib/ruby-debug-ide/commands/threads.rb
64
71
  - lib/ruby-debug-ide/commands/variables.rb
65
72
  - lib/ruby-debug-ide/event_processor.rb
73
+ - lib/ruby-debug-ide/foo.sh
74
+ - lib/ruby-debug-ide/greeter.rb
66
75
  - lib/ruby-debug-ide/helper.rb
67
76
  - lib/ruby-debug-ide/ide_processor.rb
68
77
  - lib/ruby-debug-ide/interface.rb
@@ -93,8 +102,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
102
  version: 1.3.1
94
103
  requirements: []
95
104
  rubyforge_project: debug-commons
96
- rubygems_version: 2.5.1
105
+ rubygems_version: 2.4.8
97
106
  signing_key:
98
107
  specification_version: 4
99
108
  summary: IDE interface for ruby-debug.
100
109
  test_files: []
110
+ has_rdoc: false