debug 1.0.0.alpha0 → 1.0.0.alpha1

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
  SHA256:
3
- metadata.gz: 58f91a1d4079133e3e7590329d65b7b811490f7158ef96d7b3f826968bc3ad1f
4
- data.tar.gz: 4da17de6911dc4506cb869298d84df46de08121aca704bb9e2643f774015fbb3
3
+ metadata.gz: c921a03e7629b04e9629e77c5c6dac3adfa4acb33f4f72d325315a358d07058c
4
+ data.tar.gz: eac06881f18621e16ac00f7ce628ff64c5aa7b60d99b725cdc30528e4c41b399
5
5
  SHA512:
6
- metadata.gz: baa1a1708b02b63f47d7d751ce9e5830edcdc690c8ca84c956f0e4ce839db5f3f63cf22e856ad4cec43190bb7401b8dcfd13a3d55de72d0a438520a3fab394bc
7
- data.tar.gz: 3816a302b56757b55501950ff2814e21d978a5cdf58a4431d663bd1dfbdaae1c7652e0a9565e4401201b29119cdfaa35f47986eee1b17b0b60c1759ec21f3e6a
6
+ metadata.gz: 299218c5bbfa513df144365e8172ae270a681b3e8e0ab6b7953834d99454947c1a31ce2f6f9aa85b3ae798ac501ea8e4f8892deabf96ca835cb35112fd26a54b
7
+ data.tar.gz: cac005fa02d12e187f586b2718d27d0c1463d03219a050102c9767540692cd609666cd6ea65db83a3bda54471c4a5ff10f06e1305b8ec013d5735b2633a2eebe
data/README.md CHANGED
@@ -2,16 +2,12 @@
2
2
 
3
3
  ## How to install
4
4
 
5
- This is temporary installation guide until gemify.
6
-
7
5
  ```
8
- $ git clone https://github.com/ko1/debug.git
9
- $ gem install debug_inspector
10
- $ gem install iseq_collector
11
- $ export RUBYOPT=-I`pwd`/debug/lib
12
- # or add "-I`pwd`/debug/lib" for the following command
6
+ $ gem install debug
13
7
  ```
14
8
 
9
+ or specify `-Ipath/to/debug/lib` in `RUBYOPT` or each ruby command-line options for development.
10
+
15
11
  # How to use
16
12
 
17
13
  ## Invoke with debugger
@@ -19,7 +15,7 @@ $ export RUBYOPT=-I`pwd`/debug/lib
19
15
  ### REPL debug
20
16
 
21
17
  ```
22
- $ ruby -r debug target.rb
18
+ $ ruby -r debug/repl target.rb
23
19
  ```
24
20
 
25
21
  and you can see the debugger prompt. The program was suspended at the beggining of target.rb. To continue the program, type `c` (or `continue`). See other debug commands below.
data/lib/debug.rb CHANGED
@@ -1,15 +1 @@
1
1
  require_relative 'debug/repl'
2
-
3
- # default break points
4
- DEBUGGER__.add_catch_breakpoint 'RuntimeError'
5
- class Binding
6
- DEBUGGER__.add_line_breakpoint __FILE__, __LINE__ + 1
7
- def bp; nil; end
8
- end
9
-
10
- if $0 == __FILE__
11
- # DEBUGGER__.add_line_breakpoint __dir__ + '/target.rb', 1
12
- # load __dir__ + '/target.rb'
13
- else
14
- DEBUGGER__.add_line_breakpoint $0, 1
15
- end
@@ -1,97 +1,97 @@
1
- module DEBUGGER__
2
- class LineBreakpoint
3
- attr_reader :path, :line, :key
4
-
5
- def initialize type, iseq, line, cond = nil, oneshot: false
6
- @iseq = iseq
7
- @path = iseq.path
8
- @line = line
9
- @type = type
10
- @cond = cond
11
- @oneshot = oneshot
12
- @key = [@path, @line].freeze
13
- setup
14
- enable
15
- end
16
-
17
- def safe_eval b, expr
18
- b.eval(expr)
19
- rescue Exception => e
20
- puts "[EVAL ERROR]"
21
- puts " expr: #{expr}"
22
- puts " err: #{e} (#{e.class})"
23
- nil
24
- end
25
-
26
- def setup
27
- if !@cond
28
- @tp = TracePoint.new(@type) do |tp|
29
- tp.disable if @oneshot
30
- ThreadClient.current.on_breakpoint tp
31
- end
32
- else
33
- @tp = TracePoint.new(@type) do |tp|
34
- next unless safe_eval tp.binding, @cond
35
- tp.disable if @oneshot
36
- ThreadClient.current.on_breakpoint tp
37
- end
38
- end
39
- end
40
-
41
- def enable
42
- if @type == :line
43
- @tp.enable(target: @iseq, target_line: @line)
44
- else
45
- @tp.enable(target: @iseq)
46
- end
47
- rescue ArgumentError
48
- puts @iseq.disasm # for debug
49
- raise
50
- end
51
-
52
- def disable
53
- @tp.disable
54
- end
55
-
56
- def to_s
57
- "line bp #{@iseq.absolute_path}:#{@line} (#{@type})" +
58
- if @cond
59
- "if #{@cond}"
60
- else
61
- ""
62
- end
63
- end
64
-
65
- def inspect
66
- "<#{self.class.name} #{self.to_s}>"
67
- end
68
- end
69
-
70
- class CatchBreakpoint
71
- attr_reader :key
72
-
73
- def initialize pat
74
- @pat = pat
75
- @tp = TracePoint.new(:raise){|tp|
76
- exc = tp.raised_exception
77
- exc.class.ancestors.each{|cls|
78
- if pat === cls.name
79
- puts "catch #{exc.class.inspect} by #{@pat.inspect}"
80
- ThreadClient.current.on_suspend :catch
81
- end
82
- }
83
- }
84
- @tp.enable
85
-
86
- @key = pat.freeze
87
- end
88
-
89
- def disable
90
- @tp.disable
91
- end
92
-
93
- def to_s
94
- "catch bp #{@pat.inspect}"
95
- end
96
- end
97
- end
1
+ module DEBUGGER__
2
+ class LineBreakpoint
3
+ attr_reader :path, :line, :key
4
+
5
+ def initialize type, iseq, line, cond = nil, oneshot: false
6
+ @iseq = iseq
7
+ @path = iseq.path
8
+ @line = line
9
+ @type = type
10
+ @cond = cond
11
+ @oneshot = oneshot
12
+ @key = [@path, @line].freeze
13
+ setup
14
+ enable
15
+ end
16
+
17
+ def safe_eval b, expr
18
+ b.eval(expr)
19
+ rescue Exception => e
20
+ puts "[EVAL ERROR]"
21
+ puts " expr: #{expr}"
22
+ puts " err: #{e} (#{e.class})"
23
+ nil
24
+ end
25
+
26
+ def setup
27
+ if !@cond
28
+ @tp = TracePoint.new(@type) do |tp|
29
+ tp.disable if @oneshot
30
+ ThreadClient.current.on_breakpoint tp
31
+ end
32
+ else
33
+ @tp = TracePoint.new(@type) do |tp|
34
+ next unless safe_eval tp.binding, @cond
35
+ tp.disable if @oneshot
36
+ ThreadClient.current.on_breakpoint tp
37
+ end
38
+ end
39
+ end
40
+
41
+ def enable
42
+ if @type == :line
43
+ @tp.enable(target: @iseq, target_line: @line)
44
+ else
45
+ @tp.enable(target: @iseq)
46
+ end
47
+ rescue ArgumentError
48
+ puts @iseq.disasm # for debug
49
+ raise
50
+ end
51
+
52
+ def disable
53
+ @tp.disable
54
+ end
55
+
56
+ def to_s
57
+ "line bp #{@iseq.absolute_path}:#{@line} (#{@type})" +
58
+ if @cond
59
+ "if #{@cond}"
60
+ else
61
+ ""
62
+ end
63
+ end
64
+
65
+ def inspect
66
+ "<#{self.class.name} #{self.to_s}>"
67
+ end
68
+ end
69
+
70
+ class CatchBreakpoint
71
+ attr_reader :key
72
+
73
+ def initialize pat
74
+ @pat = pat
75
+ @tp = TracePoint.new(:raise){|tp|
76
+ exc = tp.raised_exception
77
+ exc.class.ancestors.each{|cls|
78
+ if pat === cls.name
79
+ puts "catch #{exc.class.inspect} by #{@pat.inspect}"
80
+ ThreadClient.current.on_suspend :catch
81
+ end
82
+ }
83
+ }
84
+ @tp.enable
85
+
86
+ @key = pat.freeze
87
+ end
88
+
89
+ def disable
90
+ @tp.disable
91
+ end
92
+
93
+ def to_s
94
+ "catch bp #{@pat.inspect}"
95
+ end
96
+ end
97
+ end
data/lib/debug/client.rb CHANGED
@@ -1,135 +1,135 @@
1
- require 'socket'
2
- require_relative 'config'
3
-
4
- module DEBUGGER__
5
- class Client
6
- begin
7
- require 'readline'
8
- def readline
9
- Readline.readline("\n(rdb) ", true)
10
- end
11
- rescue LoadError
12
- def readline
13
- print "\n(rdb) "
14
- gets
15
- end
16
- end
17
-
18
- def help
19
- puts "-run -e attach # connect via UNIX Domain socket"
20
- puts "-run -e attach name # connect via UNIX Domain socket with specified name"
21
- puts "-run -e attach port_num # connect via TCP/IP socket with specified port"
22
- puts "-run -e attach host port_num"
23
- puts " # connect via TCP/IP socket with specified host and port"
24
- end
25
-
26
- def initialize argv
27
- case argv.size
28
- when 0
29
- connect_unix
30
- when 1
31
- case arg = argv.shift
32
- when /-h/, /--help/
33
- help
34
- exit
35
- when /\A\d+\z/
36
- connect_tcp nil, arg.to_i
37
- else
38
- connect_unix arg
39
- end
40
- when 2
41
- connect_tcp argv[0], argv[1]
42
- else
43
- help
44
- exit!
45
- end
46
- end
47
-
48
- def cleanup_unix_domain_sockets
49
- Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*') do |file|
50
- if /(\d+)$/ =~ file
51
- begin
52
- Process.kill(0, $1.to_i)
53
- rescue Errno::ESRCH
54
- File.unlink(file)
55
- end
56
- end
57
- end
58
- end
59
-
60
- def connect_unix name = nil
61
- if name
62
- if File.exist? name
63
- @s = Socket.unix(name)
64
- else
65
- @s = Socket.unix(File.join(DEBUGGER__.unix_domain_socket_basedir, name))
66
- end
67
- else
68
- cleanup_unix_domain_sockets
69
- files = Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*')
70
- case files.size
71
- when 0
72
- $stderr.puts "There is no debug sessions."
73
- exit
74
- when 1
75
- @s = Socket.unix(files.first)
76
- else
77
- $stderr.puts "Please select a debug session:"
78
- files.each{|f|
79
- $stderr.puts " #{File.basename(f)}"
80
- }
81
- exit
82
- end
83
- end
84
- end
85
-
86
- def connect_tcp host, port
87
- @s = Socket.tcp(host, port)
88
- end
89
-
90
- def connect
91
- trap(:SIGINT){
92
- @s.puts "pause"
93
- }
94
-
95
- while line = @s.gets
96
- # p line: line
97
- case line
98
- when /^out (.*)/
99
- puts "#{$1}"
100
- when /^input/
101
- prev_trap = trap(:SIGINT, 'DEFAULT')
102
-
103
- begin
104
- line = readline
105
- rescue Interrupt
106
- retry
107
- ensure
108
- trap(:SIGINT, prev_trap)
109
- end
110
-
111
- line = (line || 'quit').strip
112
- @s.puts "command #{line}"
113
- when /^ask (.*)/
114
- print $1
115
- @s.puts "answer #{gets || ''}"
116
- when /^quit/
117
- raise 'quit'
118
- else
119
- puts "(unknown) #{line.inspect}"
120
- end
121
- end
122
- rescue
123
- STDERR.puts "disconnected (#{$!})"
124
- exit
125
- end
126
- end
127
- end
128
-
129
- def connect argv = ARGV
130
- DEBUGGER__::Client.new(argv).connect
131
- end
132
-
133
- if __FILE__ == $0
134
- connect
135
- end
1
+ require 'socket'
2
+ require_relative 'config'
3
+
4
+ module DEBUGGER__
5
+ class Client
6
+ begin
7
+ require 'readline'
8
+ def readline
9
+ Readline.readline("\n(rdb) ", true)
10
+ end
11
+ rescue LoadError
12
+ def readline
13
+ print "\n(rdb) "
14
+ gets
15
+ end
16
+ end
17
+
18
+ def help
19
+ puts "-run -e attach # connect via UNIX Domain socket"
20
+ puts "-run -e attach name # connect via UNIX Domain socket with specified name"
21
+ puts "-run -e attach port_num # connect via TCP/IP socket with specified port"
22
+ puts "-run -e attach host port_num"
23
+ puts " # connect via TCP/IP socket with specified host and port"
24
+ end
25
+
26
+ def initialize argv
27
+ case argv.size
28
+ when 0
29
+ connect_unix
30
+ when 1
31
+ case arg = argv.shift
32
+ when /-h/, /--help/
33
+ help
34
+ exit
35
+ when /\A\d+\z/
36
+ connect_tcp nil, arg.to_i
37
+ else
38
+ connect_unix arg
39
+ end
40
+ when 2
41
+ connect_tcp argv[0], argv[1]
42
+ else
43
+ help
44
+ exit!
45
+ end
46
+ end
47
+
48
+ def cleanup_unix_domain_sockets
49
+ Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*') do |file|
50
+ if /(\d+)$/ =~ file
51
+ begin
52
+ Process.kill(0, $1.to_i)
53
+ rescue Errno::ESRCH
54
+ File.unlink(file)
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ def connect_unix name = nil
61
+ if name
62
+ if File.exist? name
63
+ @s = Socket.unix(name)
64
+ else
65
+ @s = Socket.unix(File.join(DEBUGGER__.unix_domain_socket_basedir, name))
66
+ end
67
+ else
68
+ cleanup_unix_domain_sockets
69
+ files = Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*')
70
+ case files.size
71
+ when 0
72
+ $stderr.puts "There is no debug sessions."
73
+ exit
74
+ when 1
75
+ @s = Socket.unix(files.first)
76
+ else
77
+ $stderr.puts "Please select a debug session:"
78
+ files.each{|f|
79
+ $stderr.puts " #{File.basename(f)}"
80
+ }
81
+ exit
82
+ end
83
+ end
84
+ end
85
+
86
+ def connect_tcp host, port
87
+ @s = Socket.tcp(host, port)
88
+ end
89
+
90
+ def connect
91
+ trap(:SIGINT){
92
+ @s.puts "pause"
93
+ }
94
+
95
+ while line = @s.gets
96
+ # p line: line
97
+ case line
98
+ when /^out (.*)/
99
+ puts "#{$1}"
100
+ when /^input/
101
+ prev_trap = trap(:SIGINT, 'DEFAULT')
102
+
103
+ begin
104
+ line = readline
105
+ rescue Interrupt
106
+ retry
107
+ ensure
108
+ trap(:SIGINT, prev_trap)
109
+ end
110
+
111
+ line = (line || 'quit').strip
112
+ @s.puts "command #{line}"
113
+ when /^ask (.*)/
114
+ print $1
115
+ @s.puts "answer #{gets || ''}"
116
+ when /^quit/
117
+ raise 'quit'
118
+ else
119
+ puts "(unknown) #{line.inspect}"
120
+ end
121
+ end
122
+ rescue
123
+ STDERR.puts "disconnected (#{$!})"
124
+ exit
125
+ end
126
+ end
127
+ end
128
+
129
+ def connect argv = ARGV
130
+ DEBUGGER__::Client.new(argv).connect
131
+ end
132
+
133
+ if __FILE__ == $0
134
+ connect
135
+ end
data/lib/debug/config.rb CHANGED
@@ -1,26 +1,26 @@
1
- module DEBUGGER__
2
- def self.unix_domain_socket_basedir
3
- case
4
- when path = ENV['RUBY_DEBUG_SOCK_DIR']
5
- when path = ENV['XDG_RUNTIME_DIR']
6
- when home = ENV['HOME']
7
- path = File.join(home, '.ruby-debug-sock')
8
- unless File.exist?(path)
9
- Dir.mkdir(path, 0700)
10
- end
11
- else
12
- raise 'specify RUBY_DEBUG_SOCK_DIR environment variable for UNIX domain socket directory.'
13
- end
14
-
15
- path
16
- end
17
-
18
- def self.create_unix_domain_socket_name_prefix
19
- user = ENV['USER'] || 'ruby-debug'
20
- File.join(unix_domain_socket_basedir, "ruby-debug-#{user}")
21
- end
22
-
23
- def self.create_unix_domain_socket_name
24
- create_unix_domain_socket_name_prefix + "-#{Process.pid}"
25
- end
26
- end
1
+ module DEBUGGER__
2
+ def self.unix_domain_socket_basedir
3
+ case
4
+ when path = ENV['RUBY_DEBUG_SOCK_DIR']
5
+ when path = ENV['XDG_RUNTIME_DIR']
6
+ when home = ENV['HOME']
7
+ path = File.join(home, '.ruby-debug-sock')
8
+ unless File.exist?(path)
9
+ Dir.mkdir(path, 0700)
10
+ end
11
+ else
12
+ raise 'specify RUBY_DEBUG_SOCK_DIR environment variable for UNIX domain socket directory.'
13
+ end
14
+
15
+ path
16
+ end
17
+
18
+ def self.create_unix_domain_socket_name_prefix
19
+ user = ENV['USER'] || 'ruby-debug'
20
+ File.join(unix_domain_socket_basedir, "ruby-debug-#{user}")
21
+ end
22
+
23
+ def self.create_unix_domain_socket_name
24
+ create_unix_domain_socket_name_prefix + "-#{Process.pid}"
25
+ end
26
+ end
data/lib/debug/repl.rb CHANGED
@@ -59,9 +59,11 @@ module DEBUGGER__
59
59
  end
60
60
  end
61
61
 
62
- SESSION = Session.new(UI_Repl.new)
62
+ initialize_session UI_Repl.new
63
63
 
64
64
  PREV_HANDLER = trap(:SIGINT){
65
65
  ThreadClient.current.on_trap
66
66
  }
67
+
68
+ DEBUGGER__.add_line_breakpoint $0, 1
67
69
  end
data/lib/debug/server.rb CHANGED
@@ -105,7 +105,7 @@ module DEBUGGER__
105
105
  end
106
106
 
107
107
  def pause
108
- $stderr.puts "DEBUG: pause request"
108
+ # $stderr.puts "DEBUG: pause request"
109
109
  Process.kill(:SIGINT, Process.pid)
110
110
  end
111
111
 
data/lib/debug/session.rb CHANGED
@@ -82,12 +82,11 @@ module DEBUGGER__
82
82
  end
83
83
 
84
84
  @management_threads = [@session_server]
85
+ @management_threads << @ui.reader_thread if @ui.respond_to? :reader_thread
85
86
 
86
87
  setup_threads
87
88
  end
88
89
 
89
- attr_reader :management_threads
90
-
91
90
  def source path
92
91
  @sr.get(path)
93
92
  end
@@ -595,4 +594,18 @@ module DEBUGGER__
595
594
  def self.add_catch_breakpoint pat
596
595
  ::DEBUGGER__::SESSION.add_catch_breakpoint pat
597
596
  end
597
+
598
+ class << self
599
+ define_method :initialize_session do |ui|
600
+ ::DEBUGGER__.const_set(:SESSION, Session.new(ui))
601
+
602
+ # default breakpoints
603
+ ::DEBUGGER__.add_catch_breakpoint 'RuntimeError'
604
+
605
+ Binding.module_eval do
606
+ ::DEBUGGER__.add_line_breakpoint __FILE__, __LINE__ + 1
607
+ def bp; nil; end
608
+ end
609
+ end
610
+ end
598
611
  end
@@ -18,6 +18,5 @@ module DEBUGGER__
18
18
  end
19
19
  end
20
20
 
21
- SESSION = Session.new(s = UI_TcpServer.new)
22
- SESSION.management_threads << s.reader_thread
21
+ initialize_session UI_TcpServer.new
23
22
  end
@@ -14,6 +14,5 @@ module DEBUGGER__
14
14
  end
15
15
  end
16
16
 
17
- SESSION = Session.new(s = UI_UnixDomainServer.new)
18
- SESSION.management_threads << s.reader_thread
17
+ initialize_session UI_UnixDomainServer.new
19
18
  end
data/lib/debug/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module DEBUGGER__
2
- VERSION = "1.0.0.alpha0"
2
+ VERSION = "1.0.0.alpha1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: debug
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.alpha0
4
+ version: 1.0.0.alpha1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koichi Sasada