ruby-debug-ide 0.6.1.beta4 → 0.6.1.beta6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 90ec6589dc3043b457fe0c148595388e8052df55
4
- data.tar.gz: b60add310e51a12ed117d28b2710a816aab51575
3
+ metadata.gz: 565c9fc5c3cf0ae3477f3b944fbe90f956420302
4
+ data.tar.gz: 8ff67628c2d6b887e8651013f6744157bc65254a
5
5
  SHA512:
6
- metadata.gz: 19c91299d491b609b74cd72e3ea4d909d5f09322bd015fa3c3451aedb019e3d7e0321c3de08cc283019e408d4612ba3cec1326f0b52890f8e1fe0aa6f520e2db
7
- data.tar.gz: b33c0c1e0ac56f69330832dfbc1631dc8dff03c886d33be8127f9352620225c7245cc9af110bfb72997294ae99efb2addac507519f4ddf01bd7810b3b9b93312
6
+ metadata.gz: fbe3852ec8b2cbf4f221912c3e679d2610198af3316b15810ef963e6cab4115d0ef716cebeeb035ed26779d2347c58637ecf55815993fdb5c5bb9d8870bbbe74
7
+ data.tar.gz: 7ebf7eb3bc7e06c95661abf449777f513a25f510de3a3ad2d952edf54b64baa70aaca9b700e984129c58102d4755c5692c46829806c606f4b59d81f452adbb16
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'optparse'
4
+ require 'thread'
4
5
  require 'ostruct'
5
6
 
6
7
  $stdout.sync = true
@@ -65,6 +66,7 @@ unless options.ruby_path
65
66
  end
66
67
 
67
68
  argv = '["' + ARGV * '", "' + '"]'
69
+ child_argv = '["' + ARGV * '", "' + "', '--ignore-port" + '"]'
68
70
  debugger_loader_path = File.expand_path(File.dirname(__FILE__)) + '/../lib/ruby-debug-ide/attach/debugger_loader'
69
71
 
70
72
  options.gems_to_include.each do |gem_path|
@@ -78,51 +80,17 @@ require 'ruby-debug-ide/attach/util'
78
80
  require 'ruby-debug-ide/attach/native_debugger'
79
81
  require 'ruby-debug-ide/attach/process_thread'
80
82
 
81
- debugger = choose_debugger(options.ruby_path, options.pid, options.gems_to_include, debugger_loader_path, argv)
82
83
 
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
84
+ child_pids = get_child_pids(options.pid.to_s)
85
+ attach_threads = Array.new
86
+ attach_threads << attach_and_return_thread(options, options.pid, debugger_loader_path, argv)
96
87
 
97
- debugger.attach_to_process
98
- debugger.set_flags
88
+ attach_threads << child_pids.map {|pid| attach_and_return_thread(options, pid, debugger_loader_path, child_argv)}
99
89
 
90
+
91
+ attach_threads.each {|thread| thread.join}
100
92
  if options.uid
101
93
  DebugPrinter.print_debug("changing current uid from #{Process.uid} to #{options.uid}")
102
94
  Process::Sys.setuid(options.uid.to_i)
103
95
  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
96
  sleep
@@ -36,8 +36,19 @@ Usage: rdebug-ide is supposed to be called from RDT, NetBeans, RubyMine, or
36
36
  EOB
37
37
  opts.separator ""
38
38
  opts.separator "Options:"
39
+
40
+ ENV['DEBUGGER_MEMORY_LIMIT'] = '10'
41
+ opts.on("-m", "--memory-limit LIMIT", Integer, "evaluation memory limit in mb (default: 10)") do |limit|
42
+ ENV['DEBUGGER_MEMORY_LIMIT'] = limit
43
+ end
44
+
45
+ ENV['INSPECT_TIME_LIMIT'] = '100'
46
+ opts.on("-t", "--time-limit LIMIT", Integer, "evaluation time limit in milliseconds (default: 100)") do |limit|
47
+ ENV['INSPECT_TIME_LIMIT'] = limit
48
+ end
49
+
39
50
  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}
51
+ opts.on("-p", "--port PORT", Integer, "Port used for remote debugging") {|port| options.port = port}
41
52
  opts.on("--dispatcher-port PORT", Integer, "Port used for multi-process debugging dispatcher") do |dp|
42
53
  options.dispatcher_port = dp
43
54
  end
@@ -60,6 +71,9 @@ EOB
60
71
  opts.on("--attach-mode", "Tells that rdebug-ide is working in attach mode") do
61
72
  options.attach_mode = true
62
73
  end
74
+ opts.on("--ignore-port", "Generate another port") do
75
+ options.ignore_port = true
76
+ end
63
77
  opts.on("--keep-frame-binding", "Keep frame bindings") {options.frame_bind = true}
64
78
  opts.on("--disable-int-handler", "Disables interrupt signal handler") {options.int_handler = false}
65
79
  opts.on("--rubymine-protocol-extensions", "Enable all RubyMine-specific incompatible protocol extensions") do
@@ -1,5 +1,76 @@
1
1
  require 'ruby-debug-ide/attach/lldb'
2
2
  require 'ruby-debug-ide/attach/gdb'
3
+ require 'socket'
4
+
5
+ def attach_and_return_thread(options, pid, debugger_loader_path, argv)
6
+ Thread.new(argv) do |argv|
7
+
8
+ debugger = choose_debugger(options.ruby_path, pid, options.gems_to_include, debugger_loader_path, argv)
9
+
10
+ trap('INT') do
11
+ unless debugger.exited?
12
+ $stderr.puts "backtraces for threads:\n\n"
13
+ process_threads = debugger.process_threads
14
+ if process_threads
15
+ process_threads.each do |thread|
16
+ $stderr.puts "#{thread.thread_info}\n#{thread.last_bt}\n\n"
17
+ end
18
+ end
19
+ debugger.exit
20
+ end
21
+ exit!
22
+ end
23
+
24
+ debugger.attach_to_process
25
+ debugger.set_flags
26
+
27
+ if debugger.check_already_under_debug
28
+ $stderr.puts "Process #{debugger.pid} is already under debug"
29
+ debugger.exit
30
+ exit!
31
+ end
32
+
33
+ should_check_threads_state = true
34
+
35
+ while should_check_threads_state
36
+ should_check_threads_state = false
37
+ debugger.update_threads.each do |thread|
38
+ thread.switch
39
+ while thread.need_finish_frame
40
+ should_check_threads_state = true
41
+ thread.finish
42
+ end
43
+ end
44
+ end
45
+
46
+ debugger.wait_line_event
47
+ debugger.load_debugger
48
+ debugger.exit
49
+ end
50
+ end
51
+
52
+ def get_child_pids(pid)
53
+ return [] unless command_exists 'pgrep'
54
+
55
+ pids = Array.new
56
+
57
+ q = Queue.new
58
+ q.push(pid)
59
+
60
+ while (!q.empty?) do
61
+ pid = q.pop
62
+
63
+ pipe = IO.popen("pgrep -P #{pid}")
64
+
65
+ pipe.readlines.each do |child|
66
+ child_pid = child.strip.to_i
67
+ q.push(child_pid)
68
+ pids << child_pid
69
+ end
70
+ end
71
+
72
+ pids
73
+ end
3
74
 
4
75
  def command_exists(command)
5
76
  checking_command = "checking command #{command} for existence\n"
@@ -118,6 +118,7 @@ module Debugger
118
118
  def debug_eval(str, b = get_binding)
119
119
  begin
120
120
  str = str.to_s
121
+ str.force_encoding('UTF-8') if(RUBY_VERSION > '2.0')
121
122
  to_inspect = Command.unescape_incoming(str)
122
123
  max_time = Debugger.evaluation_timeout
123
124
  @printer.print_debug("Evaluating %s with timeout after %i sec", str, max_time)
@@ -129,7 +129,7 @@ module Debugger
129
129
  locals = @state.context.frame_locals(@state.frame_pos)
130
130
  _self = @state.context.frame_self(@state.frame_pos)
131
131
  begin
132
- locals['self'] = _self unless "main" == _self.to_s
132
+ locals['self'] = _self unless TOPLEVEL_BINDING.eval('self') == _self
133
133
  rescue => ex
134
134
  locals['self'] = "<Cannot evaluate self>"
135
135
  $stderr << "Cannot evaluate self\n#{ex.class.name}: #{ex.message}\n #{ex.backtrace.join("\n ")}"
@@ -19,6 +19,11 @@ module Debugger
19
19
  'notify_dispatcher' => true
20
20
  )
21
21
 
22
+ if(options.ignore_port)
23
+ options.port = find_free_port(options.host)
24
+ options.notify_dispatcher = true
25
+ end
26
+
22
27
  start_debugger(options)
23
28
  end
24
29
 
@@ -39,7 +44,6 @@ module Debugger
39
44
  Debugger.keep_frame_binding = options.frame_bind
40
45
  Debugger.tracing = options.tracing
41
46
  Debugger.cli_debug = options.cli_debug
42
-
43
47
  Debugger.prepare_debugger(options)
44
48
  end
45
49
 
@@ -6,5 +6,6 @@ if ENV['IDE_PROCESS_DISPATCHER']
6
6
  end
7
7
  require 'ruby-debug-ide'
8
8
  require 'ruby-debug-ide/multiprocess'
9
+ Debugger::MultiProcess::do_monkey
9
10
  Debugger::MultiProcess::pre_child
10
11
  end
@@ -1,3 +1,3 @@
1
1
  module Debugger
2
- IDE_VERSION='0.6.1.beta4'
2
+ IDE_VERSION='0.6.1.beta6'
3
3
  end
@@ -1,12 +1,39 @@
1
1
  require 'stringio'
2
2
  require 'cgi'
3
3
  require 'monitor'
4
+ require 'objspace'
4
5
 
5
6
  module Debugger
6
7
 
8
+ module OverflowMessageType
9
+ NIL_MESSAGE = lambda {|e| nil}
10
+ EXCEPTION_MESSAGE = lambda {|e| e.message}
11
+ SPECIAL_SYMBOL_MESSAGE = lambda {|e| '<?>'}
12
+ end
13
+
14
+ class MemoryLimitError < StandardError
15
+ attr_reader :message
16
+ attr_reader :backtrace
17
+
18
+ def initialize(message, backtrace = '')
19
+ @message = message
20
+ @backtrace = backtrace
21
+ end
22
+ end
23
+
24
+ class TimeLimitError < StandardError
25
+ attr_reader :message
26
+ attr_reader :backtrace
27
+
28
+ def initialize(message, backtrace = '')
29
+ @message = message
30
+ @backtrace = backtrace
31
+ end
32
+ end
33
+
7
34
  class XmlPrinter # :nodoc:
8
35
  class ExceptionProxy
9
- instance_methods.each { |m| undef_method m unless m =~ /(^__|^send$|^object_id$|^instance_variables$|^instance_eval$)/ }
36
+ instance_methods.each {|m| undef_method m unless m =~ /(^__|^send$|^object_id$|^instance_variables$|^instance_eval$)/}
10
37
 
11
38
  def initialize(exception)
12
39
  @exception = exception
@@ -14,9 +41,9 @@ module Debugger
14
41
  @backtrace = Debugger.cleanup_backtrace(exception.backtrace)
15
42
  end
16
43
 
17
- private
18
- def method_missing(called, *args, &block)
19
- @exception.__send__(called, *args, &block)
44
+ private
45
+ def method_missing(called, *args, &block)
46
+ @exception.__send__(called, *args, &block)
20
47
  end
21
48
  end
22
49
 
@@ -31,15 +58,15 @@ module Debugger
31
58
  end
32
59
  end
33
60
  }
34
- end
61
+ end
35
62
 
36
63
  @@monitor = Monitor.new
37
64
  attr_accessor :interface
38
-
65
+
39
66
  def initialize(interface)
40
67
  @interface = interface
41
68
  end
42
-
69
+
43
70
  def print_msg(*args)
44
71
  msg, *args = args
45
72
  xml_message = CGI.escapeHTML(msg % args)
@@ -62,7 +89,7 @@ module Debugger
62
89
  print CGI.escapeHTML(msg % args)
63
90
  end
64
91
  end
65
-
92
+
66
93
  def print_frames(context, current_frame_id)
67
94
  print_element("frames") do
68
95
  (0...context.stack_size).each do |id|
@@ -70,18 +97,18 @@ module Debugger
70
97
  end
71
98
  end
72
99
  end
73
-
100
+
74
101
  def print_current_frame(frame_pos)
75
102
  print_debug "Selected frame no #{frame_pos}"
76
103
  end
77
-
104
+
78
105
  def print_frame(context, frame_id, current_frame_id)
79
106
  # idx + 1: one-based numbering as classic-debugger
80
107
  file = context.frame_file(frame_id)
81
108
  print "<frame no=\"%s\" file=\"%s\" line=\"%s\" #{"current='true' " if frame_id == current_frame_id}/>",
82
- frame_id + 1, CGI.escapeHTML(File.expand_path(file)), context.frame_line(frame_id)
109
+ frame_id + 1, CGI.escapeHTML(File.expand_path(file)), context.frame_line(frame_id)
83
110
  end
84
-
111
+
85
112
  def print_contexts(contexts)
86
113
  print_element("threads") do
87
114
  contexts.each do |c|
@@ -89,11 +116,11 @@ module Debugger
89
116
  end
90
117
  end
91
118
  end
92
-
119
+
93
120
  def print_context(context)
94
121
  print "<thread id=\"%s\" status=\"%s\" pid=\"%s\" #{current_thread_attr(context)}/>", context.thnum, context.thread.status, Process.pid
95
122
  end
96
-
123
+
97
124
  def print_variables(vars, kind)
98
125
  print_element("variables") do
99
126
  # print self at top position
@@ -103,26 +130,26 @@ module Debugger
103
130
  end
104
131
  end
105
132
  end
106
-
133
+
107
134
  def print_array(array)
108
135
  print_element("variables") do
109
- index = 0
110
- array.each { |e|
111
- print_variable('[' + index.to_s + ']', e, 'instance')
112
- index += 1
136
+ index = 0
137
+ array.each {|e|
138
+ print_variable('[' + index.to_s + ']', e, 'instance')
139
+ index += 1
113
140
  }
114
141
  end
115
142
  end
116
-
143
+
117
144
  def print_hash(hash)
118
145
  print_element("variables") do
119
- hash.keys.each { | k |
146
+ hash.keys.each {|k|
120
147
  if k.class.name == "String"
121
148
  name = '\'' + k + '\''
122
149
  else
123
- name = k.to_s
150
+ name = exec_with_allocation_control(k, ENV['DEBUGGER_MEMORY_LIMIT'].to_i, ENV['INSPECT_TIME_LIMIT'].to_i, :to_s, OverflowMessageType::EXCEPTION_MESSAGE)
124
151
  end
125
- print_variable(name, hash[k], 'instance')
152
+ print_variable(name, hash[k], 'instance')
126
153
  }
127
154
  end
128
155
  end
@@ -134,10 +161,55 @@ module Debugger
134
161
  InspectCommand.reference_result(bytes)
135
162
  print_variable('bytes', bytes, 'instance')
136
163
  end
137
- print_variable('encoding', string.encoding, 'instance') if string.respond_to?('encoding')
164
+ print_variable('encoding', string.encoding, 'instance') if string.respond_to?('encoding')
138
165
  end
139
166
  end
140
-
167
+
168
+ def exec_with_allocation_control(value, memory_limit, time_limit, exec_method, overflow_message_type)
169
+ check_memory_limit = true
170
+ if (defined?(JRUBY_VERSION) || ENV['DEBUGGER_MEMORY_LIMIT'].to_i <= 0)
171
+ check_memory_limit = false
172
+ end
173
+ curr_thread = Thread.current
174
+ result = nil
175
+ inspect_thread = DebugThread.start {
176
+
177
+ start_alloc_size = ObjectSpace.memsize_of_all if (check_memory_limit)
178
+ start_time = Time.now.to_f
179
+
180
+ trace = TracePoint.new(:c_call, :call) do |tp|
181
+
182
+ if (rand > 0.75)
183
+ curr_time = Time.now.to_f
184
+
185
+ if ((curr_time - start_time) * 1e3 > time_limit)
186
+ curr_thread.raise TimeLimitError.new("Timeout: evaluation of #{exec_method} took longer than #{time_limit}ms.", "#{caller.map {|l| "\t#{l}"}.join("\n")}")
187
+ inspect_thread.kill
188
+ end
189
+
190
+ if (check_memory_limit)
191
+ curr_alloc_size = ObjectSpace.memsize_of_all
192
+ start_alloc_size = curr_alloc_size if (curr_alloc_size < start_alloc_size)
193
+
194
+ if (curr_alloc_size - start_alloc_size > 1e6 * memory_limit)
195
+ curr_thread.raise MemoryLimitError.new("Out of memory: evaluation of #{exec_method} took more than #{memory_limit}mb.", "#{caller.map {|l| "\t#{l}"}.join("\n")}")
196
+ inspect_thread.kill
197
+ end
198
+ end
199
+ end
200
+ end.enable {
201
+ result = value.send exec_method
202
+ }
203
+ }
204
+ inspect_thread.join
205
+ inspect_thread.kill
206
+ return result
207
+ rescue MemoryLimitError, TimeLimitError => e
208
+ print_debug(e.message + "\n" + e.backtrace)
209
+
210
+ return overflow_message_type.call(e)
211
+ end
212
+
141
213
  def print_variable(name, value, kind)
142
214
  name = name.to_s
143
215
  if value.nil?
@@ -147,7 +219,7 @@ module Debugger
147
219
  if value.is_a?(Array) || value.is_a?(Hash)
148
220
  has_children = !value.empty?
149
221
  if has_children
150
- size = value.size
222
+ size = value.size
151
223
  value_str = "#{value.class} (#{value.size} element#{size > 1 ? "s" : "" })"
152
224
  else
153
225
  value_str = "Empty #{value.class}"
@@ -155,27 +227,29 @@ module Debugger
155
227
  elsif value.is_a?(String)
156
228
  has_children = value.respond_to?('bytes') || value.respond_to?('encoding')
157
229
  value_str = value
158
- else
230
+ else
159
231
  has_children = !value.instance_variables.empty? || !value.class.class_variables.empty?
160
- value_str = value.to_s || 'nil' rescue "<#to_s method raised exception: #{$!}>"
232
+
233
+ value_str = exec_with_allocation_control(value, ENV['DEBUGGER_MEMORY_LIMIT'].to_i, ENV['INSPECT_TIME_LIMIT'].to_i, :to_s, OverflowMessageType::EXCEPTION_MESSAGE) || 'nil' rescue "<#to_s method raised exception: #{$!}>"
234
+
161
235
  unless value_str.is_a?(String)
162
- value_str = "ERROR: #{value.class}.to_s method returns #{value_str.class}. Should return String."
236
+ value_str = "ERROR: #{value.class}.to_s method returns #{value_str.class}. Should return String."
163
237
  end
164
238
  end
165
239
 
166
240
  if value_str.respond_to?('encode')
167
241
  # noinspection RubyEmptyRescueBlockInspection
168
242
  begin
169
- value_str = value_str.encode("UTF-8")
243
+ value_str = value_str.encode("UTF-8")
170
244
  rescue
171
245
  end
172
246
  end
173
247
  value_str = handle_binary_data(value_str)
174
248
  escaped_value_str = CGI.escapeHTML(value_str)
175
249
  print("<variable name=\"%s\" %s kind=\"%s\" %s type=\"%s\" hasChildren=\"%s\" objectId=\"%#+x\">",
176
- CGI.escapeHTML(name), build_compact_value_attr(value, value_str), kind,
177
- build_value_attr(escaped_value_str), value.class,
178
- has_children, value.respond_to?(:object_id) ? value.object_id : value.id)
250
+ CGI.escapeHTML(name), build_compact_value_attr(value, value_str), kind,
251
+ build_value_attr(escaped_value_str), value.class,
252
+ has_children, value.respond_to?(:object_id) ? value.object_id : value.id)
179
253
  print("<value><![CDATA[%s]]></value>", escaped_value_str) if Debugger.value_as_nested_element
180
254
  print('</variable>')
181
255
  rescue StandardError => e
@@ -198,28 +272,28 @@ module Debugger
198
272
 
199
273
  def print_breakpoints(breakpoints)
200
274
  print_element 'breakpoints' do
201
- breakpoints.sort_by{|b| b.id }.each do |b|
275
+ breakpoints.sort_by {|b| b.id}.each do |b|
202
276
  print "<breakpoint n=\"%d\" file=\"%s\" line=\"%s\" />", b.id, CGI.escapeHTML(b.source), b.pos.to_s
203
277
  end
204
278
  end
205
279
  end
206
-
280
+
207
281
  def print_breakpoint_added(b)
208
282
  print "<breakpointAdded no=\"%s\" location=\"%s:%s\"/>", b.id, CGI.escapeHTML(b.source), b.pos
209
283
  end
210
-
284
+
211
285
  def print_breakpoint_deleted(b)
212
286
  print "<breakpointDeleted no=\"%s\"/>", b.id
213
287
  end
214
-
288
+
215
289
  def print_breakpoint_enabled(b)
216
290
  print "<breakpointEnabled bp_id=\"%s\"/>", b.id
217
291
  end
218
-
292
+
219
293
  def print_breakpoint_disabled(b)
220
294
  print "<breakpointDisabled bp_id=\"%s\"/>", b.id
221
295
  end
222
-
296
+
223
297
  def print_contdition_set(bp_id)
224
298
  print "<conditionSet bp_id=\"%d\"/>", bp_id
225
299
  end
@@ -239,37 +313,37 @@ module Debugger
239
313
  def print_expressions(exps)
240
314
  print_element "expressions" do
241
315
  exps.each_with_index do |(exp, value), idx|
242
- print_expression(exp, value, idx+1)
316
+ print_expression(exp, value, idx + 1)
243
317
  end
244
318
  end unless exps.empty?
245
319
  end
246
-
320
+
247
321
  def print_expression(exp, value, idx)
248
322
  print "<dispay name=\"%s\" value=\"%s\" no=\"%d\" />", exp, value, idx
249
323
  end
250
324
 
251
325
  def print_expression_info(incomplete, prompt, indent)
252
326
  print "<expressionInfo incomplete=\"%s\" prompt=\"%s\" indent=\"%s\"></expressionInfo>",
253
- incomplete, CGI.escapeHTML(prompt), indent
327
+ incomplete, CGI.escapeHTML(prompt), indent
254
328
  end
255
-
329
+
256
330
  def print_eval(exp, value)
257
- print "<eval expression=\"%s\" value=\"%s\" />", CGI.escapeHTML(exp), value
331
+ print "<eval expression=\"%s\" value=\"%s\" />", CGI.escapeHTML(exp), value
258
332
  end
259
-
333
+
260
334
  def print_pp(value)
261
335
  print value
262
336
  end
263
-
337
+
264
338
  def print_list(b, e, file, line)
265
339
  print "[%d, %d] in %s\n", b, e, file
266
340
  if (lines = Debugger.source_for(file))
267
341
  b.upto(e) do |n|
268
- if n > 0 && lines[n-1]
342
+ if n > 0 && lines[n - 1]
269
343
  if n == line
270
- print "=> %d %s\n", n, lines[n-1].chomp
344
+ print "=> %d %s\n", n, lines[n - 1].chomp
271
345
  else
272
- print " %d %s\n", n, lines[n-1].chomp
346
+ print " %d %s\n", n, lines[n - 1].chomp
273
347
  end
274
348
  end
275
349
  end
@@ -277,7 +351,7 @@ module Debugger
277
351
  print "No source-file available for %s\n", file
278
352
  end
279
353
  end
280
-
354
+
281
355
  def print_methods(methods)
282
356
  print_element "methods" do
283
357
  methods.each do |method|
@@ -285,31 +359,31 @@ module Debugger
285
359
  end
286
360
  end
287
361
  end
288
-
362
+
289
363
  # Events
290
-
364
+
291
365
  def print_breakpoint(_, breakpoint)
292
366
  print("<breakpoint file=\"%s\" line=\"%s\" threadId=\"%d\"/>",
293
- CGI.escapeHTML(breakpoint.source), breakpoint.pos, Debugger.current_context.thnum)
367
+ CGI.escapeHTML(breakpoint.source), breakpoint.pos, Debugger.current_context.thnum)
294
368
  end
295
-
369
+
296
370
  def print_catchpoint(exception)
297
371
  context = Debugger.current_context
298
- print("<exception file=\"%s\" line=\"%s\" type=\"%s\" message=\"%s\" threadId=\"%d\"/>",
299
- CGI.escapeHTML(context.frame_file(0)), context.frame_line(0), exception.class, CGI.escapeHTML(exception.to_s), context.thnum)
372
+ print("<exception file=\"%s\" line=\"%s\" type=\"%s\" message=\"%s\" threadId=\"%d\"/>",
373
+ CGI.escapeHTML(context.frame_file(0)), context.frame_line(0), exception.class, CGI.escapeHTML(exception.to_s), context.thnum)
300
374
  end
301
-
375
+
302
376
  def print_trace(context, file, line)
303
377
  Debugger::print_debug "trace: location=\"%s:%s\", threadId=%d", file, line, context.thnum
304
378
  # TBD: do we want to clog fronend with the <trace> elements? There are tons of them.
305
379
  # print "<trace file=\"%s\" line=\"%s\" threadId=\"%d\" />", file, line, context.thnum
306
380
  end
307
-
381
+
308
382
  def print_at_line(context, file, line)
309
383
  print "<suspended file=\"%s\" line=\"%s\" threadId=\"%d\" frames=\"%d\"/>",
310
384
  CGI.escapeHTML(File.expand_path(file)), line, context.thnum, context.stack_size
311
385
  end
312
-
386
+
313
387
  def print_exception(exception, _)
314
388
  print_element("variables") do
315
389
  proxy = ExceptionProxy.new(exception)
@@ -317,21 +391,21 @@ module Debugger
317
391
  print_variable('error', proxy, 'exception')
318
392
  end
319
393
  rescue Exception
320
- print "<processingException type=\"%s\" message=\"%s\"/>",
321
- exception.class, CGI.escapeHTML(exception.to_s)
394
+ print "<processingException type=\"%s\" message=\"%s\"/>",
395
+ exception.class, CGI.escapeHTML(exception.to_s)
322
396
  end
323
-
397
+
324
398
  def print_inspect(eval_result)
325
- print_element("variables") do
399
+ print_element("variables") do
326
400
  print_variable("eval_result", eval_result, 'local')
327
401
  end
328
402
  end
329
-
330
- def print_load_result(file, exception=nil)
403
+
404
+ def print_load_result(file, exception = nil)
331
405
  if exception
332
- print("<loadResult file=\"%s\" exceptionType=\"%s\" exceptionMessage=\"%s\"/>", file, exception.class, CGI.escapeHTML(exception.to_s))
406
+ print("<loadResult file=\"%s\" exceptionType=\"%s\" exceptionMessage=\"%s\"/>", file, exception.class, CGI.escapeHTML(exception.to_s))
333
407
  else
334
- print("<loadResult file=\"%s\" status=\"OK\"/>", file)
408
+ print("<loadResult file=\"%s\" status=\"OK\"/>", file)
335
409
  end
336
410
  end
337
411
 
@@ -345,7 +419,7 @@ module Debugger
345
419
  end
346
420
 
347
421
  private
348
-
422
+
349
423
  def print(*params)
350
424
  Debugger::print_debug(*params)
351
425
  @interface.print(*params)
@@ -381,22 +455,35 @@ module Debugger
381
455
  end
382
456
 
383
457
  def compact_array_str(value)
384
- slice = value[0..10]
385
- compact = slice.inspect
386
- if value.size != slice.size
387
- compact[0..compact.size-2] + ", ...]"
458
+ slice = value[0..10]
459
+
460
+ compact = exec_with_allocation_control(slice, ENV['DEBUGGER_MEMORY_LIMIT'].to_i, ENV['INSPECT_TIME_LIMIT'].to_i, :inspect, OverflowMessageType::NIL_MESSAGE)
461
+
462
+ if compact && value.size != slice.size
463
+ compact[0..compact.size - 2] + ", ...]"
388
464
  end
389
465
  compact
390
466
  end
391
467
 
392
468
  def compact_hash_str(value)
393
- slice = value.sort_by { |k, _| k.to_s }[0..5]
394
- compact = slice.map { |kv| "#{kv[0]}: #{handle_binary_data(kv[1])}" }.join(", ")
469
+ keys_strings = Hash.new
470
+
471
+ slice = value.sort_by do |k, _|
472
+ keys_string = exec_with_allocation_control(k, ENV['DEBUGGER_MEMORY_LIMIT'].to_i, ENV['INSPECT_TIME_LIMIT'].to_i, :to_s, OverflowMessageType::SPECIAL_SYMBOL_MESSAGE)
473
+ keys_strings[k] = keys_string
474
+ keys_string
475
+ end[0..5]
476
+
477
+ compact = slice.map do |kv|
478
+ key_string = keys_strings[kv[0]]
479
+ value_string = exec_with_allocation_control(kv[1], ENV['DEBUGGER_MEMORY_LIMIT'].to_i, ENV['INSPECT_TIME_LIMIT'].to_i, :to_s, OverflowMessageType::SPECIAL_SYMBOL_MESSAGE)
480
+ "#{key_string}: #{handle_binary_data(value_string)}"
481
+ end.join(", ")
395
482
  "{" + compact + (slice.size != value.size ? ", ..." : "") + "}"
396
483
  end
397
484
 
398
485
  def build_compact_value_attr(value, value_str)
399
- compact_value_str = build_compact_name(value, value_str)
486
+ compact_value_str = build_compact_name(value, value_str)
400
487
  compact_value_str.nil? ? '' : "compactValue=\"#{CGI.escapeHTML(compact_value_str)}\""
401
488
  end
402
489
 
@@ -422,7 +509,7 @@ module Debugger
422
509
  protect m
423
510
  end
424
511
  end
425
-
512
+
426
513
  end
427
514
 
428
515
  end
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.beta4
4
+ version: 0.6.1.beta6
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-12-22 00:00:00.000000000 Z
11
+ date: 2017-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -24,8 +24,10 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.8.1
27
- description: |
28
- An interface which glues ruby-debug to IDEs like Eclipse (RDT), NetBeans and RubyMine.
27
+ description: 'An interface which glues ruby-debug to IDEs like Eclipse (RDT), NetBeans
28
+ and RubyMine.
29
+
30
+ '
29
31
  email: rubymine-feedback@jetbrains.com
30
32
  executables:
31
33
  - rdebug-ide
@@ -50,7 +52,6 @@ files:
50
52
  - lib/ruby-debug-ide/attach/native_debugger.rb
51
53
  - lib/ruby-debug-ide/attach/process_thread.rb
52
54
  - lib/ruby-debug-ide/attach/util.rb
53
- - lib/ruby-debug-ide/boo.sh
54
55
  - lib/ruby-debug-ide/command.rb
55
56
  - lib/ruby-debug-ide/commands/breakpoints.rb
56
57
  - lib/ruby-debug-ide/commands/catchpoint.rb
@@ -70,7 +71,6 @@ files:
70
71
  - lib/ruby-debug-ide/commands/threads.rb
71
72
  - lib/ruby-debug-ide/commands/variables.rb
72
73
  - lib/ruby-debug-ide/event_processor.rb
73
- - lib/ruby-debug-ide/foo.sh
74
74
  - lib/ruby-debug-ide/greeter.rb
75
75
  - lib/ruby-debug-ide/helper.rb
76
76
  - lib/ruby-debug-ide/ide_processor.rb
@@ -103,9 +103,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
103
  version: 1.3.1
104
104
  requirements: []
105
105
  rubyforge_project: debug-commons
106
- rubygems_version: 2.4.8
106
+ rubygems_version: 2.6.11
107
107
  signing_key:
108
108
  specification_version: 4
109
109
  summary: IDE interface for ruby-debug.
110
110
  test_files: []
111
- has_rdoc: false
@@ -1 +0,0 @@
1
- sh foo.sh
@@ -1,4 +0,0 @@
1
- #!/bin/sh
2
- echo a;
3
- echo a;
4
- echo a