debug 1.6.3 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -18,7 +18,7 @@ module DEBUGGER__
18
18
  end
19
19
 
20
20
  at_exit do
21
- CONFIG.skip_all
21
+ DEBUGGER__.skip_all
22
22
  FileUtils.rm_rf dir if tempdir
23
23
  end
24
24
 
@@ -128,7 +128,8 @@ module DEBUGGER__
128
128
 
129
129
  case self
130
130
  when UI_UnixDomainServer
131
- UI_DAP.local_fs_map_set true
131
+ # If the user specified a mapping, respect it, otherwise, make sure that no mapping is used
132
+ UI_DAP.local_fs_map_set CONFIG[:local_fs_map] || true
132
133
  when UI_TcpServer
133
134
  # TODO: loopback address can be used to connect other FS env, like Docker containers
134
135
  # UI_DAP.local_fs_set if @local_addr.ipv4_loopback? || @local_addr.ipv6_loopback?
@@ -198,6 +199,13 @@ module DEBUGGER__
198
199
  # supportsInstructionBreakpoints:
199
200
  )
200
201
  send_event 'initialized'
202
+ puts <<~WELCOME
203
+ Ruby REPL: You can run any Ruby expression here.
204
+ Note that output to the STDOUT/ERR printed on the TERMINAL.
205
+ [experimental]
206
+ `,COMMAND` runs `COMMAND` debug command (ex: `,info`).
207
+ `,help` to list all debug commands.
208
+ WELCOME
201
209
  end
202
210
 
203
211
  def send **kw
@@ -271,18 +279,24 @@ module DEBUGGER__
271
279
  ## boot/configuration
272
280
  when 'launch'
273
281
  send_response req
274
- UI_DAP.local_fs_map_set req.dig('arguments', 'localfs') || req.dig('arguments', 'localfsMap')
275
- @is_launch = true
282
+ # `launch` runs on debuggee on the same file system
283
+ UI_DAP.local_fs_map_set req.dig('arguments', 'localfs') || req.dig('arguments', 'localfsMap') || true
284
+ @nonstop = true
276
285
 
277
286
  when 'attach'
278
287
  send_response req
279
288
  UI_DAP.local_fs_map_set req.dig('arguments', 'localfs') || req.dig('arguments', 'localfsMap')
280
- @is_launch = false
289
+
290
+ if req.dig('arguments', 'nonstop') == true
291
+ @nonstop = true
292
+ else
293
+ @nonstop = false
294
+ end
281
295
 
282
296
  when 'configurationDone'
283
297
  send_response req
284
298
 
285
- if @is_launch
299
+ if @nonstop
286
300
  @q_msg << 'continue'
287
301
  else
288
302
  if SESSION.in_subsession?
@@ -419,10 +433,20 @@ module DEBUGGER__
419
433
  }
420
434
  }
421
435
 
436
+ when 'evaluate'
437
+ expr = req.dig('arguments', 'expression')
438
+ if /\A\s*,(.+)\z/ =~ expr
439
+ dbg_expr = $1
440
+ send_response req,
441
+ result: "",
442
+ variablesReference: 0
443
+ debugger do: dbg_expr
444
+ else
445
+ @q_msg << req
446
+ end
422
447
  when 'stackTrace',
423
448
  'scopes',
424
449
  'variables',
425
- 'evaluate',
426
450
  'source',
427
451
  'completions'
428
452
  @q_msg << req
@@ -443,7 +467,11 @@ module DEBUGGER__
443
467
 
444
468
  def puts result
445
469
  # STDERR.puts "puts: #{result}"
446
- # send_event 'output', category: 'stderr', output: "PUTS!!: " + result.to_s
470
+ send_event 'output', category: 'console', output: "#{result&.chomp}\n"
471
+ end
472
+
473
+ def ignore_output_on_suspend?
474
+ true
447
475
  end
448
476
 
449
477
  def event type, *args
@@ -534,8 +562,8 @@ module DEBUGGER__
534
562
  if ref = @var_map[varid]
535
563
  case ref[0]
536
564
  when :globals
537
- vars = global_variables.map do |name|
538
- gv = 'Not implemented yet...'
565
+ vars = global_variables.sort.map do |name|
566
+ gv = eval(name.to_s)
539
567
  {
540
568
  name: name,
541
569
  value: gv.inspect,
@@ -580,6 +608,7 @@ module DEBUGGER__
580
608
  if @frame_map[frame_id]
581
609
  tid, fid = @frame_map[frame_id]
582
610
  expr = req.dig('arguments', 'expression')
611
+
583
612
  if tc = find_waiting_tc(tid)
584
613
  request_tc [:dap, :evaluate, req, fid, expr, context]
585
614
  else
@@ -684,10 +713,26 @@ module DEBUGGER__
684
713
  end
685
714
  end
686
715
 
716
+ class NaiveString
717
+ attr_reader :str
718
+ def initialize str
719
+ @str = str
720
+ end
721
+ end
722
+
687
723
  class ThreadClient
688
- def value_inspect obj
724
+
725
+ MAX_LENGTH = 180
726
+
727
+ def value_inspect obj, short: true
689
728
  # TODO: max length should be configuarable?
690
- DEBUGGER__.safe_inspect obj, short: true, max_length: 4 * 1024
729
+ str = DEBUGGER__.safe_inspect obj, short: short, max_length: MAX_LENGTH
730
+
731
+ if str.encoding == Encoding::UTF_8
732
+ str.scrub
733
+ else
734
+ str.encode(Encoding::UTF_8, invalid: :replace, undef: :replace)
735
+ end
691
736
  end
692
737
 
693
738
  def process_dap args
@@ -702,9 +747,10 @@ module DEBUGGER__
702
747
  frames = []
703
748
  @target_frames.each_with_index do |frame, i|
704
749
  next if i < start_frame
705
- break if (levels -= 1) < 0
706
750
 
707
751
  path = frame.realpath || frame.path
752
+ next if skip_path?(path) && !SESSION.stop_stepping?(path, frame.location.lineno)
753
+ break if (levels -= 1) < 0
708
754
  source_name = path ? File.basename(path) : frame.location.to_s
709
755
 
710
756
  if (path && File.exist?(path)) && (local_path = UI_DAP.remote_to_local_path(path))
@@ -792,13 +838,11 @@ module DEBUGGER__
792
838
  when String
793
839
  vars = [
794
840
  variable('#length', obj.length),
795
- variable('#encoding', obj.encoding)
841
+ variable('#encoding', obj.encoding),
796
842
  ]
843
+ vars << variable('#dump', NaiveString.new(obj)) if obj.length > MAX_LENGTH
797
844
  when Class, Module
798
- vars = obj.instance_variables.map{|iv|
799
- variable(iv, obj.instance_variable_get(iv))
800
- }
801
- vars.unshift variable('%ancestors', obj.ancestors[1..])
845
+ vars << variable('%ancestors', obj.ancestors[1..])
802
846
  when Range
803
847
  vars = [
804
848
  variable('#begin', obj.begin),
@@ -806,10 +850,12 @@ module DEBUGGER__
806
850
  ]
807
851
  end
808
852
 
809
- vars += M_INSTANCE_VARIABLES.bind_call(obj).map{|iv|
810
- variable(iv, M_INSTANCE_VARIABLE_GET.bind_call(obj, iv))
811
- }
812
- vars.unshift variable('#class', M_CLASS.bind_call(obj))
853
+ unless NaiveString === obj
854
+ vars += M_INSTANCE_VARIABLES.bind_call(obj).sort.map{|iv|
855
+ variable(iv, M_INSTANCE_VARIABLE_GET.bind_call(obj, iv))
856
+ }
857
+ vars.unshift variable('#class', M_CLASS.bind_call(obj))
858
+ end
813
859
  end
814
860
  end
815
861
  event! :dap_result, :variable, req, variables: (vars || []), tid: self.id
@@ -914,7 +960,11 @@ module DEBUGGER__
914
960
  [Object, *b.eval('::Module.nesting')].reverse_each{|mod|
915
961
  if cs.all?{|c|
916
962
  if mod.const_defined?(c)
917
- mod = mod.const_get(c)
963
+ begin
964
+ mod = mod.const_get(c)
965
+ rescue Exception
966
+ false
967
+ end
918
968
  else
919
969
  false
920
970
  end
@@ -927,11 +977,17 @@ module DEBUGGER__
927
977
  end
928
978
 
929
979
  def evaluate_result r
930
- v = variable nil, r
931
- v.delete :name
932
- v.delete :value
933
- v[:result] = value_inspect(r)
934
- v
980
+ variable nil, r
981
+ end
982
+
983
+ def type_name obj
984
+ klass = M_CLASS.bind_call(obj)
985
+
986
+ begin
987
+ klass.name || klass.to_s
988
+ rescue Exception => e
989
+ "<Error: #{e.message} (#{e.backtrace.first}>"
990
+ end
935
991
  end
936
992
 
937
993
  def variable_ name, obj, indexedVariables: 0, namedVariables: 0
@@ -942,15 +998,31 @@ module DEBUGGER__
942
998
  vid = 0
943
999
  end
944
1000
 
945
- ivnum = M_INSTANCE_VARIABLES.bind_call(obj).size
1001
+ namedVariables += M_INSTANCE_VARIABLES.bind_call(obj).size
946
1002
 
947
- { name: name,
948
- value: value_inspect(obj),
949
- type: (klass = M_CLASS.bind_call(obj)).name || klass.to_s,
950
- variablesReference: vid,
951
- indexedVariables: indexedVariables,
952
- namedVariables: namedVariables + ivnum,
953
- }
1003
+ if NaiveString === obj
1004
+ str = obj.str.dump
1005
+ vid = indexedVariables = namedVariables = 0
1006
+ else
1007
+ str = value_inspect(obj)
1008
+ end
1009
+
1010
+ if name
1011
+ { name: name,
1012
+ value: str,
1013
+ type: type_name(obj),
1014
+ variablesReference: vid,
1015
+ indexedVariables: indexedVariables,
1016
+ namedVariables: namedVariables,
1017
+ }
1018
+ else
1019
+ { result: str,
1020
+ type: type_name(obj),
1021
+ variablesReference: vid,
1022
+ indexedVariables: indexedVariables,
1023
+ namedVariables: namedVariables,
1024
+ }
1025
+ end
954
1026
  end
955
1027
 
956
1028
  def variable name, obj
@@ -960,7 +1032,7 @@ module DEBUGGER__
960
1032
  when Hash
961
1033
  variable_ name, obj, namedVariables: obj.size
962
1034
  when String
963
- variable_ name, obj, namedVariables: 3 # #to_str, #length, #encoding
1035
+ variable_ name, obj, namedVariables: 3 # #length, #encoding, #to_str
964
1036
  when Struct
965
1037
  variable_ name, obj, namedVariables: obj.size
966
1038
  when Class, Module