debug 1.6.3 → 1.7.0

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.
@@ -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