byebug 4.0.4 → 4.0.5

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: 0d5196fdd3dc5f4325d6a7dc03edc403c3f54adc
4
- data.tar.gz: b99153ca69aa352475c74692bd4cf0092b7fafa6
3
+ metadata.gz: 86c24793f077ce32dceea91c8bde07dce922a274
4
+ data.tar.gz: f166af0f5a9b01024978ebf2ebb5d9b7103d8a7b
5
5
  SHA512:
6
- metadata.gz: aab4f3f7ed3f5da8c08b024b8b616fbbb67020cf652e7d9474b83fef9b0abeacee16a19016fd47fb3c4117071a4b1e9d6b0f491c3862626ea58351973bc06912
7
- data.tar.gz: 760d9cd65c9b2a7afad5c7f47d079dc84a1e3b0d0af754099998513a3d6a2ff835fcc661bdab3d0d8100cb0884d0e8d03a902d73763266e1761c7473fe733e09
6
+ metadata.gz: 19d9a87a1f69496bdb00574437c3913b167d2da92d1b1b35c64412a70adfc8309f2bc78bdac5233bea310bd46543af2966b762453318e450ff6d73092626b16d
7
+ data.tar.gz: cfe46396685e6cec68816f38b70183317cf7585e1bbec594de6e670962151a5cd1eb4e1eb2483c0aafe43e94d741589c595c8d8e5a4cecb5124200b617c04b05
@@ -1,3 +1,9 @@
1
+ ## 4.0.5 - 2015-04-02
2
+ ### Fixed
3
+ * #131
4
+ * Thread commands help format should be consistent with the rest of the help
5
+ system now.
6
+
1
7
  ## 4.0.4 - 2015-03-27
2
8
  ### Fixed
3
9
  * #127
@@ -17,6 +17,11 @@ API and a lot of bugs have been recently corrected. Without this fixes,
17
17
  `byebug` will fail to work properly, so make sure you have always the last
18
18
  patch level releases of Ruby installed.
19
19
 
20
+ Also, if you are developing on linux, make sure you have the GNU indent utility
21
+ installed for automatic check of code style in C files. If you're developing in
22
+ MacOSX, just make sure you keep a consistent style if you edit the C-extension
23
+ files. Travis CI will do the automatic check anyways.
24
+
20
25
 
21
26
  ## Getting started
22
27
 
data/GUIDE.md CHANGED
@@ -223,28 +223,28 @@ the output so that it nicely fits our screen.
223
223
  (byebug) set width 80
224
224
  Maximum width of byebug's output is 80
225
225
  (byebug) ps private_methods
226
- Array default_src_encoding open sleep
227
- Complex define_method p spawn
228
- Digest eval pp sprintf
229
- Float exec print srand
230
- Hash exit printf syscall
231
- Integer exit! private system
232
- Pathname fail proc test
233
- Rational fork public throw
234
- String format putc timeout
235
- URI gem_original_require puts trace_var
236
- __callee__ gets raise trap
226
+ Array default_src_encoding open sleep
227
+ Complex define_method p spawn
228
+ Digest eval pp sprintf
229
+ Float exec print srand
230
+ Hash exit printf syscall
231
+ Integer exit! private system
232
+ Pathname fail proc test
233
+ Rational fork public throw
234
+ String format putc timeout
235
+ URI gem_original_require puts trace_var
236
+ __callee__ gets raise trap
237
237
  __dir__ global_variables rand untrace_var
238
- __method__ include readline using
239
- ` initialize readlines warn
240
- abort initialize_clone require y
241
- at_exit initialize_copy require_relative
242
- autoload initialize_dup respond_to_missing?
243
- autoload? iterator? rubygems_require
244
- binding lambda select
245
- block_given? load set_trace_func
246
- caller local_variables singleton_method_added
247
- caller_locations loop singleton_method_removed
238
+ __method__ include readline using
239
+ ` initialize readlines warn
240
+ abort initialize_clone require y
241
+ at_exit initialize_copy require_relative
242
+ autoload initialize_dup respond_to_missing?
243
+ autoload? iterator? rubygems_require
244
+ binding lambda select
245
+ block_given? load set_trace_func
246
+ caller local_variables singleton_method_added
247
+ caller_locations loop singleton_method_removed
248
248
  catch method_missing singleton_method_undefined
249
249
  (byebug)
250
250
  ```
@@ -500,7 +500,7 @@ Run options: --seed 31679
500
500
 
501
501
  [2, 11] in test_triangle.rb
502
502
  2: require_relative 'triangle.rb'
503
- 3:
503
+ 3:
504
504
  4: class TestTriangle < Minitest::Test
505
505
  5: def test_basic
506
506
  6: byebug
@@ -1035,7 +1035,7 @@ run a sleeping thread.
1035
1035
 
1036
1036
  Now we can investigate the problem in the employer's side:
1037
1037
 
1038
- ``bash
1038
+ ```bash
1039
1039
  (byebug) s
1040
1040
  [30, 39] in /path/to/company.rb
1041
1041
  30:
@@ -1088,7 +1088,7 @@ Now we can investigate the problem in the employer's side:
1088
1088
  39: show_off(@results.pop)
1089
1089
  40: end
1090
1090
  (byebug)
1091
- ``
1091
+ ```
1092
1092
 
1093
1093
  Now we can see the problem, the `@results` variable is always empty! The
1094
1094
  employee forgot to leave the results in his manager's deck. We fix it by
@@ -1193,14 +1193,14 @@ get a line trace, `tracer` is most likely faster than `byebug`.
1193
1193
  ```bash
1194
1194
  $ time byebug --trace --no-stop hanoi.rb > /dev/null
1195
1195
 
1196
- real 0m0.743s
1197
- user 0m0.668s
1198
- sys 0m0.068s
1196
+ real 0m0.743s
1197
+ user 0m0.668s
1198
+ sys 0m0.068s
1199
1199
  $ time ruby -rtracer hanoi.rb > /dev/null
1200
1200
 
1201
- real 0m0.077s
1202
- user 0m0.072s
1203
- sys 0m0.004s
1201
+ real 0m0.077s
1202
+ user 0m0.072s
1203
+ sys 0m0.004s
1204
1204
  ```
1205
1205
 
1206
1206
  ### Byebug default options
@@ -1620,19 +1620,40 @@ will just call pretty-print.
1620
1620
  :pretty_inspect,
1621
1621
  :byebug]
1622
1622
  (byebug) putl Kernel.instance_methods
1623
- nil? <=> tainted? frozen? private_methods remove_instance_variable public_send define_singleton_method byebug
1624
- === class untaint to_s public_methods instance_of? respond_to? object_id
1625
- =~ singleton_class untrust inspect instance_variables kind_of? extend to_enum
1626
- !~ clone untrusted? methods instance_variable_get is_a? display enum_for
1627
- eql? dup trust singleton_methods instance_variable_set tap method gem
1628
- hash taint freeze protected_methods instance_variable_defined? send public_method pretty_inspect
1623
+ nil? trust is_a?
1624
+ === freeze tap
1625
+ =~ frozen? send
1626
+ !~ to_s public_send
1627
+ eql? inspect respond_to?
1628
+ hash methods extend
1629
+ <=> singleton_methods display
1630
+ class protected_methods method
1631
+ singleton_class private_methods public_method
1632
+ clone public_methods singleton_method
1633
+ dup instance_variables define_singleton_method
1634
+ itself instance_variable_get object_id
1635
+ taint instance_variable_set to_enum
1636
+ tainted? instance_variable_defined? enum_for
1637
+ untaint remove_instance_variable gem
1638
+ untrust instance_of? pretty_inspect
1639
+ untrusted? kind_of?
1629
1640
  (byebug) ps Kernel.instance_methods
1630
- !~ clone extend instance_of? kind_of? private_methods respond_to? tap untrusted?
1631
- <=> define_singleton_method freeze instance_variable_defined? method protected_methods send to_enum
1632
- === display frozen? instance_variable_get methods public_method singleton_class to_s
1633
- =~ dup gem instance_variable_set nil? public_methods singleton_methods trust
1634
- byebug enum_for hash instance_variables object_id public_send taint untaint
1635
- class eql? inspect is_a? pretty_inspect remove_instance_variable tainted? untrust
1641
+ !~ instance_of? public_send
1642
+ <=> instance_variable_defined? remove_instance_variable
1643
+ === instance_variable_get respond_to?
1644
+ =~ instance_variable_set send
1645
+ class instance_variables singleton_class
1646
+ clone is_a? singleton_method
1647
+ define_singleton_method itself singleton_methods
1648
+ display kind_of? taint
1649
+ dup method tainted?
1650
+ enum_for methods tap
1651
+ eql? nil? to_enum
1652
+ extend object_id to_s
1653
+ freeze pretty_inspect trust
1654
+ frozen? private_methods untaint
1655
+ gem protected_methods untrust
1656
+ hash public_method untrusted?
1636
1657
  ```
1637
1658
 
1638
1659
  Finally, if you need more advanced functionality from REPL's, you can enter
@@ -7,12 +7,12 @@ module Byebug
7
7
  # events occur. Before entering byebug the init script is read.
8
8
  #
9
9
  def self.attach
10
- return errmsg('Byebug already started. Ignoring `byebug` call.') if started?
10
+ unless started?
11
+ self.mode = :attached
11
12
 
12
- setup_cmd_line_args
13
-
14
- start
15
- run_init_script
13
+ start
14
+ run_init_script
15
+ end
16
16
 
17
17
  current_context.step_out(2, true)
18
18
  end
@@ -15,15 +15,14 @@ module Byebug
15
15
  def execute
16
16
  return puts(self.class.help) unless @match[1]
17
17
 
18
- brkpt = line_breakpoint(@match[1]) || method_breakpoint(@match[1])
18
+ b = line_breakpoint(@match[1]) || method_breakpoint(@match[1])
19
+
19
20
  if syntax_valid?(@match[2])
20
- return puts(
21
- pr('break.created', id: brkpt.id, file: brkpt.source, line: brkpt.pos)
22
- )
21
+ return puts(pr('break.created', id: b.id, file: b.source, line: b.pos))
23
22
  end
24
23
 
25
24
  errmsg(pr('break.errors.expression', expr: @match[2]))
26
- brkpt.enabled = false
25
+ b.enabled = false
27
26
  rescue => e
28
27
  errmsg(e.message)
29
28
  end
@@ -7,8 +7,6 @@ module Byebug
7
7
  # Enables the user to catch unhandled assertion when they happen.
8
8
  #
9
9
  class CatchCommand < Command
10
- self.allow_in_control = false
11
-
12
10
  def regexp
13
11
  /^\s* cat(?:ch)? (?:\s+(\S+))? (?:\s+(off))? \s*$/x
14
12
  end
@@ -21,7 +21,7 @@ module Byebug
21
21
  return nil
22
22
  end
23
23
 
24
- @match[1].split(/[ \t]+/).each do |number|
24
+ @match[1].split(/ +/).each do |number|
25
25
  pos, err = get_int(number, 'Delete', 1)
26
26
 
27
27
  return errmsg(err) unless pos
@@ -76,7 +76,7 @@ module Byebug
76
76
 
77
77
  return errmsg(pr('toggle.errors.syntax', toggle: cmd)) unless @match[2]
78
78
 
79
- args = @match[2].split(/[ \t]+/)
79
+ args = @match[2].split(/ +/)
80
80
  param = args.shift
81
81
  subcmd = Command.find(Subcommands, param)
82
82
  if subcmd
@@ -176,7 +176,7 @@ module Byebug
176
176
  def execute
177
177
  return puts(self.class.help) unless @match[1]
178
178
 
179
- args = @match[1].split(/[ \t]+/)
179
+ args = @match[1].split(/ +/)
180
180
  param = args.shift
181
181
  subcmd = Command.find(Subcommands, param)
182
182
  return errmsg "Unknown info command #{param}\n" unless subcmd
@@ -0,0 +1,145 @@
1
+ require 'byebug/command'
2
+
3
+ module Byebug
4
+ #
5
+ # Manipulation of Ruby threads
6
+ #
7
+ class ThreadCommand < Command
8
+ Subcommands = [
9
+ ['current', 1, 'Shows current thread'],
10
+ ['list', 1, 'Lists all threads'],
11
+ ['resume', 1, 'Resumes execution of specified thread number'],
12
+ ['stop', 2, 'Stops execution of specified thread number'],
13
+ ['switch', 2, 'Switches execution to specified thread']
14
+ ].map do |name, min, help|
15
+ Subcmd.new(name, min, help)
16
+ end
17
+
18
+ def regexp
19
+ /^\s* th(?:read)? (?:\s+ (.+))? \s*$/x
20
+ end
21
+
22
+ def execute
23
+ return puts(self.class.help) unless @match[1]
24
+
25
+ name, thnum = @match[1].split(/ +/)[0..1]
26
+ subcmd = Command.find(Subcommands, name)
27
+ return errmsg("Unknown thread command '#{name}'\n") unless subcmd
28
+
29
+ send("thread_#{subcmd.name}", thnum)
30
+ end
31
+
32
+ class << self
33
+ def names
34
+ %w(thread)
35
+ end
36
+
37
+ def description
38
+ prettify <<-EOD
39
+ Commands to manipulate threads.
40
+ EOD
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def thread_list(thnum)
47
+ return errmsg("thread list doesn't need params") unless thnum.nil?
48
+
49
+ contexts = Byebug.contexts.sort_by(&:thnum)
50
+
51
+ thread_list = prc('thread.context', contexts) do |context, _|
52
+ thread_arguments(context)
53
+ end
54
+
55
+ print(thread_list)
56
+ end
57
+
58
+ def thread_current(thnum)
59
+ return errmsg("thread current doesn't need params") unless thnum.nil?
60
+
61
+ display_context(@state.context)
62
+ end
63
+
64
+ def thread_stop(thnum)
65
+ ctx, err = parse_thread_num_for_cmd('thread stop', thnum)
66
+ return errmsg(err) if err
67
+
68
+ ctx.suspend
69
+ display_context(ctx)
70
+ end
71
+
72
+ def thread_resume(thnum)
73
+ ctx, err = parse_thread_num_for_cmd('thread resume', thnum)
74
+ return errmsg(err) if err
75
+ return errmsg(pr('thread.errors.already_running')) unless ctx.suspended?
76
+
77
+ ctx.resume
78
+ display_context(ctx)
79
+ end
80
+
81
+ def thread_switch(thnum)
82
+ ctx, err = parse_thread_num_for_cmd('thread switch', thnum)
83
+ return errmsg(err) if err
84
+
85
+ display_context(ctx)
86
+
87
+ ctx.switch
88
+ @state.proceed
89
+ end
90
+
91
+ def display_context(context)
92
+ puts pr('thread.context', thread_arguments(context))
93
+ end
94
+
95
+ def thread_arguments(context)
96
+ status_flag = if context.suspended?
97
+ '$'
98
+ else
99
+ context.thread == Thread.current ? '+' : ' '
100
+ end
101
+ debug_flag = context.ignored? ? '!' : ' '
102
+
103
+ if context == Byebug.current_context
104
+ file_line = "#{@state.file}:#{@state.line}"
105
+ else
106
+ backtrace = context.thread.backtrace_locations
107
+ if backtrace && backtrace[0]
108
+ file_line = "#{backtrace[0].path}:#{backtrace[0].lineno}"
109
+ end
110
+ end
111
+
112
+ {
113
+ status_flag: status_flag,
114
+ debug_flag: debug_flag,
115
+ id: context.thnum,
116
+ thread: context.thread.inspect,
117
+ file_line: file_line || ''
118
+ }
119
+ end
120
+
121
+ def parse_thread_num(subcmd, arg)
122
+ thnum, err = get_int(arg, subcmd, 1)
123
+ return [nil, err] unless thnum
124
+
125
+ Byebug.contexts.find { |c| c.thnum == thnum }
126
+ end
127
+
128
+ def parse_thread_num_for_cmd(subcmd, arg)
129
+ c, err = parse_thread_num(subcmd, arg)
130
+
131
+ case
132
+ when err
133
+ [c, err]
134
+ when c.nil?
135
+ [nil, pr('thread.errors.no_thread')]
136
+ when @state.context == c
137
+ [c, pr('thread.errors.current_thread')]
138
+ when c.ignored?
139
+ [c, pr('thread.errors.wrong_action', subcmd: subcmd, arg: arg)]
140
+ else
141
+ [c, nil]
142
+ end
143
+ end
144
+ end
145
+ end
@@ -14,7 +14,7 @@ module Byebug
14
14
  def execute
15
15
  var = @match[1]
16
16
  if global_variables.include?(:"#{var}")
17
- eval("untrace_var(:\"#{var}\")")
17
+ untrace_var(:"#{var}")
18
18
  puts pr('trace.messages.undo', var: var)
19
19
  else
20
20
  errmsg pr('trace.errors.not_global', var: var)
@@ -29,6 +29,9 @@ module Byebug
29
29
  self.class.ignored_files.include?(path)
30
30
  end
31
31
 
32
+ #
33
+ # Context's stack size
34
+ #
32
35
  def stack_size
33
36
  return 0 unless backtrace
34
37
 
@@ -10,12 +10,6 @@ require 'byebug/printers/plain'
10
10
  module Byebug
11
11
  extend self
12
12
 
13
- class NoScript < StandardError
14
- end
15
-
16
- class NonExistentScript < StandardError
17
- end
18
-
19
13
  #
20
14
  # Configuration file used for startup commands. Default value is .byebugrc
21
15
  #
@@ -27,15 +21,15 @@ module Byebug
27
21
  attr_accessor :handler
28
22
  self.handler = CommandProcessor.new
29
23
 
24
+ extend Forwardable
25
+ def_delegators :handler, :errmsg, :puts
26
+
30
27
  #
31
28
  # Main debugger's printer
32
29
  #
33
30
  attr_accessor :printer
34
31
  self.printer = Printers::Plain.new
35
32
 
36
- extend Forwardable
37
- def_delegators :handler, :errmsg, :puts
38
-
39
33
  #
40
34
  # Running mode of the debugger. Can be either:
41
35
  #
@@ -61,26 +55,6 @@ module Byebug
61
55
  run_script(cwd_rc) if File.exist?(cwd_rc) && cwd_rc != home_rc
62
56
  end
63
57
 
64
- #
65
- # Extracts debugged program from command line args
66
- #
67
- def setup_cmd_line_args
68
- unless $PROGRAM_NAME.include?('bin/byebug')
69
- self.mode = :attached
70
- return
71
- end
72
-
73
- self.mode = :standalone
74
-
75
- fail(NoScript, 'You must specify a program to debug...') if $ARGV.empty?
76
-
77
- program = which($ARGV.shift)
78
- program = which($ARGV.shift) if program == which('ruby')
79
- fail(NonExistentScript, "The script doesn't exist") unless program
80
-
81
- $PROGRAM_NAME = program
82
- end
83
-
84
58
  private
85
59
 
86
60
  #
@@ -91,24 +65,6 @@ module Byebug
91
65
  processor = ControlCommandProcessor.new(interface)
92
66
  processor.process_commands
93
67
  end
94
-
95
- #
96
- # Cross-platform way of finding an executable in the $PATH.
97
- # Borrowed from: http://stackoverflow.com/questions/2108727
98
- #
99
- def which(cmd)
100
- return File.expand_path(cmd) if File.exist?(cmd)
101
-
102
- exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
103
- ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
104
- exts.each do |ext|
105
- exe = File.join(path, "#{cmd}#{ext}")
106
- return exe if File.executable?(exe) && !File.directory?(exe)
107
- end
108
- end
109
-
110
- nil
111
- end
112
68
  end
113
69
 
114
70
  #
@@ -88,12 +88,31 @@ module Byebug
88
88
  end
89
89
 
90
90
  #
91
- # Returns true if code is syntactically correct for Ruby.
91
+ # Returns true if code is syntactically correct for Ruby
92
92
  #
93
93
  def syntax_valid?(code)
94
- eval("BEGIN {return true}\n#{code}", nil, '', 0)
95
- rescue SyntaxError
96
- false
94
+ return true unless code
95
+
96
+ without_stderr do
97
+ begin
98
+ RubyVM::InstructionSequence.compile(code)
99
+ true
100
+ rescue SyntaxError
101
+ false
102
+ end
103
+ end
104
+ end
105
+
106
+ #
107
+ # Temporarily disable output to $stderr
108
+ #
109
+ def without_stderr
110
+ stderr = $stderr
111
+ $stderr.reopen(IO::NULL)
112
+
113
+ yield
114
+ ensure
115
+ $stderr.reopen(stderr)
97
116
  end
98
117
 
99
118
  #
@@ -1,12 +1,28 @@
1
1
  require 'optparse'
2
2
  require 'English'
3
3
  require 'byebug/core'
4
+ require 'byebug/helper'
4
5
 
5
6
  module Byebug
6
7
  #
7
8
  # Responsible for starting the debugger when started from the command line.
8
9
  #
9
10
  class Runner
11
+ #
12
+ # Error class signaling absence of a script to debug
13
+ #
14
+ class NoScript < StandardError; end
15
+
16
+ #
17
+ # Error class signaling a non existent script to debug
18
+ #
19
+ class NonExistentScript < StandardError; end
20
+
21
+ #
22
+ # Error class signaling a script with invalid Ruby syntax
23
+ #
24
+ class InvalidScript < StandardError; end
25
+
10
26
  #
11
27
  # Special working modes that don't actually start the debugger.
12
28
  #
@@ -36,27 +52,6 @@ module Byebug
36
52
  EOB
37
53
  end
38
54
 
39
- #
40
- # Debugs a script only if syntax checks okay.
41
- #
42
- def debug_program
43
- check_syntax($PROGRAM_NAME)
44
-
45
- status = Byebug.debug_load($PROGRAM_NAME, @stop)
46
- Byebug.puts "#{status}\n#{status.backtrace}" if status
47
- end
48
-
49
- #
50
- # Exits and outputs error message if syntax of the given program is invalid.
51
- #
52
- def check_syntax(program_name)
53
- output = `ruby -c "#{program_name}" 2>&1`
54
- return unless $CHILD_STATUS.exitstatus != 0
55
-
56
- Byebug.errmsg(output)
57
- exit($CHILD_STATUS.exitstatus)
58
- end
59
-
60
55
  #
61
56
  # Starts byebug to debug a program
62
57
  #
@@ -78,7 +73,7 @@ module Byebug
78
73
  return
79
74
  end
80
75
 
81
- Byebug.setup_cmd_line_args
76
+ setup_cmd_line_args
82
77
 
83
78
  loop do
84
79
  debug_program
@@ -90,6 +85,11 @@ module Byebug
90
85
  end
91
86
  end
92
87
 
88
+ private
89
+
90
+ #
91
+ # Processes options passed from the command line
92
+ #
93
93
  def prepare_options
94
94
  OptionParser.new(banner, 25) do |opts|
95
95
  opts.banner = banner
@@ -139,5 +139,50 @@ module Byebug
139
139
  end
140
140
  end
141
141
  end
142
+
143
+ #
144
+ # Extracts debugged program from command line args
145
+ #
146
+ def setup_cmd_line_args
147
+ Byebug.mode = :standalone
148
+
149
+ fail(NoScript, 'You must specify a program to debug...') if $ARGV.empty?
150
+
151
+ program = which($ARGV.shift)
152
+ program = which($ARGV.shift) if program == which('ruby')
153
+ fail(NonExistentScript, "The script doesn't exist") unless program
154
+
155
+ $PROGRAM_NAME = program
156
+ end
157
+
158
+ include ParseFunctions
159
+ #
160
+ # Debugs a script only if syntax checks okay.
161
+ #
162
+ def debug_program
163
+ ok = syntax_valid?(File.read($PROGRAM_NAME))
164
+ fail(InvalidScript, 'The script has incorrect syntax') unless ok
165
+
166
+ error = Byebug.debug_load($PROGRAM_NAME, @stop)
167
+ Byebug.puts "#{status}\n#{status.backtrace}" if error
168
+ end
169
+
170
+ #
171
+ # Cross-platform way of finding an executable in the $PATH.
172
+ # Borrowed from: http://stackoverflow.com/questions/2108727
173
+ #
174
+ def which(cmd)
175
+ return File.expand_path(cmd) if File.exist?(cmd)
176
+
177
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
178
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
179
+ exts.each do |ext|
180
+ exe = File.join(path, "#{cmd}#{ext}")
181
+ return exe if File.executable?(exe) && !File.directory?(exe)
182
+ end
183
+ end
184
+
185
+ nil
186
+ end
142
187
  end
143
188
  end
@@ -1,3 +1,3 @@
1
1
  module Byebug
2
- VERSION = '4.0.4'
2
+ VERSION = '4.0.5'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: byebug
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.4
4
+ version: 4.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Rodriguez
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-03-27 00:00:00.000000000 Z
13
+ date: 2015-04-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: columnize
@@ -102,7 +102,7 @@ files:
102
102
  - lib/byebug/commands/show.rb
103
103
  - lib/byebug/commands/source.rb
104
104
  - lib/byebug/commands/stepping.rb
105
- - lib/byebug/commands/threads.rb
105
+ - lib/byebug/commands/thread.rb
106
106
  - lib/byebug/commands/tracevar.rb
107
107
  - lib/byebug/commands/undisplay.rb
108
108
  - lib/byebug/commands/untracevar.rb
@@ -165,7 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
165
  version: '0'
166
166
  requirements: []
167
167
  rubyforge_project:
168
- rubygems_version: 2.4.6
168
+ rubygems_version: 2.4.5
169
169
  signing_key:
170
170
  specification_version: 4
171
171
  summary: Ruby 2.0 fast debugger - base + CLI
@@ -1,237 +0,0 @@
1
- require 'byebug/command'
2
-
3
- #
4
- # TODO: Implement thread commands as a single command with subcommands, just
5
- # like `info`, `var`, `enable` and `disable`. This allows consistent help
6
- # format and we can go back to showing help for a single command in the `help`
7
- # command.
8
- #
9
- module Byebug
10
- #
11
- # Utilities to assist commands related to threads.
12
- #
13
- module ThreadFunctions
14
- def display_context(context, should_show_top_frame = true)
15
- puts pr('thread.context',
16
- thread_arguments(context, should_show_top_frame))
17
- end
18
-
19
- def thread_arguments(context, should_show_top_frame = true)
20
- status_flag = if context.suspended?
21
- '$'
22
- else
23
- context.thread == Thread.current ? '+' : ' '
24
- end
25
- debug_flag = context.ignored? ? '!' : ' '
26
-
27
- if should_show_top_frame
28
- if context == Byebug.current_context
29
- file_line = "#{@state.file}:#{@state.line}"
30
- else
31
- backtrace = context.thread.backtrace_locations
32
- if backtrace && backtrace[0]
33
- file_line = "#{backtrace[0].path}:#{backtrace[0].lineno}"
34
- end
35
- end
36
- end
37
- {
38
- status_flag: status_flag,
39
- debug_flag: debug_flag,
40
- id: context.thnum,
41
- thread: context.thread.inspect,
42
- file_line: file_line || ''
43
- }
44
- end
45
-
46
- def parse_thread_num(subcmd, arg)
47
- thnum, err = get_int(arg, subcmd, 1)
48
- return [nil, err] unless thnum
49
-
50
- Byebug.contexts.find { |c| c.thnum == thnum }
51
- end
52
-
53
- def parse_thread_num_for_cmd(subcmd, arg)
54
- c, err = parse_thread_num(subcmd, arg)
55
-
56
- case
57
- when err
58
- [c, err]
59
- when c.nil?
60
- [nil, pr('thread.errors.no_thread')]
61
- when @state.context == c
62
- [c, pr('thread.errors.current_thread')]
63
- when c.ignored?
64
- [c, pr('thread.errors.wrong_action', subcmd: subcmd, arg: arg)]
65
- else
66
- [c, nil]
67
- end
68
- end
69
- end
70
-
71
- #
72
- # List current threads.
73
- #
74
- class ThreadListCommand < Command
75
- include ThreadFunctions
76
-
77
- self.allow_in_control = true
78
-
79
- def regexp
80
- /^\s* th(?:read)? \s+ l(?:ist)? \s*$/x
81
- end
82
-
83
- def execute
84
- contexts = Byebug.contexts.sort_by(&:thnum)
85
-
86
- thread_list = prc('thread.context', contexts) do |context, _|
87
- thread_arguments(context)
88
- end
89
-
90
- print(thread_list)
91
- end
92
-
93
- class << self
94
- def names
95
- %w(thread)
96
- end
97
-
98
- def description
99
- prettify <<-EOD
100
- th[read] l[ist] Lists all threads.
101
- EOD
102
- end
103
- end
104
- end
105
-
106
- #
107
- # Show current thread.
108
- #
109
- class ThreadCurrentCommand < Command
110
- include ThreadFunctions
111
-
112
- def regexp
113
- /^\s* th(?:read)? \s+ (?:cur(?:rent)?)? \s*$/x
114
- end
115
-
116
- def execute
117
- display_context(@state.context)
118
- end
119
-
120
- class << self
121
- def names
122
- %w(thread)
123
- end
124
-
125
- def description
126
- prettify <<-EOD
127
- th[read] cur[rent] Shows current thread.
128
- EOD
129
- end
130
- end
131
- end
132
-
133
- #
134
- # Stop execution of a thread.
135
- #
136
- class ThreadStopCommand < Command
137
- include ThreadFunctions
138
-
139
- self.allow_in_control = true
140
- self.allow_in_post_mortem = false
141
-
142
- def regexp
143
- /^\s* th(?:read)? \s+ stop \s* (\S*) \s*$/x
144
- end
145
-
146
- def execute
147
- c, err = parse_thread_num_for_cmd('thread stop', @match[1])
148
- return errmsg(err) if err
149
-
150
- c.suspend
151
- display_context(c)
152
- end
153
-
154
- class << self
155
- def names
156
- %w(thread)
157
- end
158
-
159
- def description
160
- prettify <<-EOD
161
- th[read] stop <n> Stops thread <n>.
162
- EOD
163
- end
164
- end
165
- end
166
-
167
- #
168
- # Resume execution of a thread.
169
- #
170
- class ThreadResumeCommand < Command
171
- include ThreadFunctions
172
-
173
- self.allow_in_control = true
174
- self.allow_in_post_mortem = false
175
-
176
- def regexp
177
- /^\s* th(?:read)? \s+ resume \s* (\S*) \s*$/x
178
- end
179
-
180
- def execute
181
- c, err = parse_thread_num_for_cmd('thread resume', @match[1])
182
- return errmsg(err) if err
183
- return errmsg pr('thread.errors.already_running') unless c.suspended?
184
-
185
- c.resume
186
- display_context(c)
187
- end
188
-
189
- class << self
190
- def names
191
- %w(thread)
192
- end
193
-
194
- def description
195
- prettify <<-EOD
196
- th[read] resume <n> Resumes thread <n>.
197
- EOD
198
- end
199
- end
200
- end
201
-
202
- #
203
- # Switch execution to a different thread.
204
- #
205
- class ThreadSwitchCommand < Command
206
- include ThreadFunctions
207
-
208
- self.allow_in_control = true
209
- self.allow_in_post_mortem = false
210
-
211
- def regexp
212
- /^\s* th(?:read)? \s+ sw(?:itch)? (?:\s+(\S+))? \s*$/x
213
- end
214
-
215
- def execute
216
- c, err = parse_thread_num_for_cmd('thread switch', @match[1])
217
- return errmsg(err) if err
218
-
219
- display_context(c)
220
-
221
- c.switch
222
- @state.proceed
223
- end
224
-
225
- class << self
226
- def names
227
- %w(thread)
228
- end
229
-
230
- def description
231
- prettify <<-EOD
232
- th[read] sw[itch] <n> Switches thread context to <n>.
233
- EOD
234
- end
235
- end
236
- end
237
- end