byebug 1.8.2 → 2.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -1
- data/GUIDE.md +14 -22
- data/README.md +69 -6
- data/bin/byebug +3 -20
- data/ext/byebug/breakpoint.c +185 -101
- data/ext/byebug/byebug.c +393 -214
- data/ext/byebug/byebug.h +34 -15
- data/ext/byebug/context.c +327 -102
- data/ext/byebug/extconf.rb +1 -1
- data/ext/byebug/locker.c +54 -0
- data/ext/byebug/threads.c +113 -0
- data/lib/byebug.rb +19 -58
- data/lib/byebug/command.rb +18 -19
- data/lib/byebug/commands/breakpoints.rb +1 -4
- data/lib/byebug/commands/catchpoint.rb +1 -1
- data/lib/byebug/commands/condition.rb +1 -1
- data/lib/byebug/commands/control.rb +2 -3
- data/lib/byebug/commands/display.rb +2 -7
- data/lib/byebug/commands/edit.rb +1 -1
- data/lib/byebug/commands/enable.rb +12 -12
- data/lib/byebug/commands/eval.rb +4 -4
- data/lib/byebug/commands/finish.rb +1 -1
- data/lib/byebug/commands/frame.rb +12 -8
- data/lib/byebug/commands/info.rb +20 -52
- data/lib/byebug/commands/kill.rb +1 -5
- data/lib/byebug/commands/list.rb +2 -1
- data/lib/byebug/commands/quit.rb +1 -1
- data/lib/byebug/commands/repl.rb +2 -2
- data/lib/byebug/commands/save.rb +1 -1
- data/lib/byebug/commands/set.rb +84 -90
- data/lib/byebug/commands/show.rb +44 -53
- data/lib/byebug/commands/skip.rb +1 -1
- data/lib/byebug/commands/stepping.rb +5 -4
- data/lib/byebug/commands/threads.rb +202 -0
- data/lib/byebug/commands/trace.rb +1 -1
- data/lib/byebug/helper.rb +3 -3
- data/lib/byebug/interface.rb +2 -20
- data/lib/byebug/processor.rb +21 -100
- data/lib/byebug/remote.rb +3 -3
- data/lib/byebug/version.rb +1 -1
- data/old_doc/byebug.1 +0 -6
- data/old_doc/byebug.texi +29 -46
- data/test/breakpoints_test.rb +44 -65
- data/test/conditions_test.rb +0 -9
- data/test/continue_test.rb +2 -2
- data/test/display_test.rb +4 -23
- data/test/edit_test.rb +2 -16
- data/test/eval_test.rb +4 -13
- data/test/examples/thread.rb +32 -0
- data/test/finish_test.rb +1 -13
- data/test/frame_test.rb +5 -12
- data/test/help_test.rb +2 -12
- data/test/info_test.rb +8 -18
- data/test/kill_test.rb +1 -10
- data/test/list_test.rb +5 -14
- data/test/method_test.rb +1 -10
- data/test/post_mortem_test.rb +247 -14
- data/test/quit_test.rb +0 -9
- data/test/reload_test.rb +1 -15
- data/test/repl_test.rb +1 -9
- data/test/restart_test.rb +3 -18
- data/test/save_test.rb +1 -13
- data/test/set_test.rb +35 -32
- data/test/show_test.rb +8 -27
- data/test/source_test.rb +1 -8
- data/test/stepping_test.rb +65 -96
- data/test/support/test_dsl.rb +12 -17
- data/test/test_helper.rb +1 -1
- data/test/thread_test.rb +106 -0
- data/test/trace_test.rb +5 -17
- data/test/variables_test.rb +1 -10
- metadata +9 -7
- data/lib/byebug/commands/jump.rb +0 -52
- data/test/jump_test.rb +0 -77
- data/test/support/context.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb2fb8a1795fb10ac0b9a08f34c9384590f2ed68
|
4
|
+
data.tar.gz: ddcc06fdb4be593c69905dc4a0277ea5bf2d945e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd5bec3e835cec6a85de603e4437e013f86fa5e9f239a243fcfa9540b17324a27a075b3a7c78520d2390d8a32e698f8939006e46fbe7f56e547bd008ceb73958
|
7
|
+
data.tar.gz: de559dec1bf1265a8e8cacb7431b1617a53ad10dafb24c4ae728714116c5d80580d52e180665fe46632578e8bb198bc9fe8240f989e815f56a80240883c5cad9
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# 2.0.0
|
2
|
+
|
3
|
+
* Various bug fixes
|
4
|
+
* "Official" definition of a command API
|
5
|
+
* Thread support
|
6
|
+
|
7
|
+
|
1
8
|
## 1.8.2
|
2
9
|
|
3
10
|
* More user friendly regexps for commands
|
@@ -91,7 +98,7 @@ containing the character '%'
|
|
91
98
|
|
92
99
|
## 1.1.0
|
93
100
|
|
94
|
-
* Post
|
101
|
+
* Post-mortem support
|
95
102
|
|
96
103
|
|
97
104
|
## 1.0.3
|
data/GUIDE.md
CHANGED
@@ -589,7 +589,6 @@ byebug 1.6.1
|
|
589
589
|
Usage: byebug [options] <script.rb> -- <script.rb parameters>
|
590
590
|
|
591
591
|
Options:
|
592
|
-
-A, --annotate LEVEL Set annotation level
|
593
592
|
-d, --debug Set $DEBUG=true
|
594
593
|
-I, --include PATH Add PATH (single or multiple:path:list) to $LOAD_PATH
|
595
594
|
--no-quit Do not quit when script finishes
|
@@ -614,10 +613,6 @@ letter option name, such as `-h`. The list of options is detailed below:
|
|
614
613
|
* **-h | --help**. It causes `byebug` to print some basic help and exit
|
615
614
|
* **-v | --version**. It causes `byebug` to print its version number and
|
616
615
|
exit.
|
617
|
-
* **-A | --annotate <level>**. Set gdb-style annotation `level`, a number.
|
618
|
-
Additional information is output automatically when program state is changed.
|
619
|
-
This can be used by front-ends such as GNU Emacs to post this updated
|
620
|
-
information without having to poll for it.
|
621
616
|
* **-d | --debug**. Set `$DEBUG` to `true`. Compatible with Ruby's.
|
622
617
|
* **-I | --include <path>**. Add `path` to load path. `path` can be a single
|
623
618
|
path ar a colon separated path list.
|
@@ -674,8 +669,8 @@ puts "rocky's byebugrc run"
|
|
674
669
|
Here are the default values in `options`
|
675
670
|
|
676
671
|
```
|
677
|
-
#<OpenStruct
|
678
|
-
|
672
|
+
#<OpenStruct nx=false, quit=true, restart_script=nil, script=nil, stop=true,
|
673
|
+
tracing=false, verbose_long=false>
|
679
674
|
```
|
680
675
|
|
681
676
|
### Command Files
|
@@ -819,9 +814,7 @@ be `(byebug:ctrl)` and in post-mortem debugging it will be
|
|
819
814
|
`(byebug:post-mortem)`.
|
820
815
|
|
821
816
|
Whenever `byebug` gives an error message such as for an invalid command or an invalid
|
822
|
-
location position, it will generally preface the message with `***`.
|
823
|
-
annotation mode is on then the message is put in a `begin-error` annotation and no
|
824
|
-
`***` appears.
|
817
|
+
location position, it will generally preface the message with `***`.
|
825
818
|
|
826
819
|
### Command Help
|
827
820
|
|
@@ -834,12 +827,11 @@ short list of named classes of commands
|
|
834
827
|
Type "help <command-name>" for help on a specific command
|
835
828
|
|
836
829
|
Available commands:
|
837
|
-
backtrace
|
838
|
-
info
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
var
|
830
|
+
backtrace delete enable help method ps save step where
|
831
|
+
break disable eval info next putl set trace
|
832
|
+
catch display exit irb p quit show undisplay
|
833
|
+
condition down finish kill pp reload skip up
|
834
|
+
continue edit frame list pry restart source var
|
843
835
|
```
|
844
836
|
|
845
837
|
With a command name as `help` argument, `byebug` displays short information on how to
|
@@ -859,11 +851,11 @@ A number of commands, namely `info`, `set`, `show`, `enable` and `disable`, have
|
|
859
851
|
sub-parameters or _subcommands_. When you ask for help for one of these commands, you
|
860
852
|
will get help for all of the subcommands that command offers. Sometimes you may want
|
861
853
|
help only on a subcommand and to do this just follow the command with its subcommand
|
862
|
-
name. For example `help
|
863
|
-
Furthermore it will give longer help than the summary
|
864
|
-
you ask for help. You don't need to list the full
|
865
|
-
letters to make that subcommand distinct from
|
866
|
-
`help
|
854
|
+
name. For example, `help info breakpoints`will just give help about the `info
|
855
|
+
breakpoints` command. Furthermore it will give longer help than the summary
|
856
|
+
information that appears when you ask for help. You don't need to list the full
|
857
|
+
subcommand name, just enough of the letters to make that subcommand distinct from
|
858
|
+
others will do. For example, `help info b` is the same as `help info breakpoints`.
|
867
859
|
|
868
860
|
Some examples follow.
|
869
861
|
|
@@ -902,7 +894,7 @@ With an integer argument, list info on that breakpoint.
|
|
902
894
|
```
|
903
895
|
|
904
896
|
```bash
|
905
|
-
(byebug) help info
|
897
|
+
(byebug) help info b
|
906
898
|
Status of user-settable breakpoints.
|
907
899
|
Without argument, list info about all breakpoints.
|
908
900
|
With an integer argument, list info on that breakpoint.
|
data/README.md
CHANGED
@@ -8,8 +8,7 @@ _Debugging in Ruby 2.0_
|
|
8
8
|
Byebug is a simple to use, feature rich debugger for Ruby 2.0. It uses the new
|
9
9
|
TracePoint API for execution control and the new Debug Inspector API for call
|
10
10
|
stack navigation, so it doesn't depend on internal core sources. It's developed
|
11
|
-
as a C extension, so it's fast. And it has a full test suite so it's
|
12
|
-
reliable.
|
11
|
+
as a C extension, so it's fast. And it has a full test suite so it's reliable.
|
13
12
|
|
14
13
|
It allows you to see what is going on _inside_ a Ruby program while it executes
|
15
14
|
and can do four main kinds of things to help you catch bugs in the act:
|
@@ -52,7 +51,7 @@ Former [debugger](https://github.com/cldwalker/debugger) or
|
|
52
51
|
[ruby-debug](https://github.com/mark-moseley/ruby-debug) users, notice:
|
53
52
|
|
54
53
|
* Some gems (rails, rspec) implement debugging flags (-d, --debugger) that early
|
55
|
-
require and start the debugger.
|
54
|
+
require and start the debugger. These flags are a performance penalty and Byebug
|
56
55
|
doesn't need them anymore so my recommendation is not to use them.
|
57
56
|
* Stopping execution using the word `debugger` doesn't work anymore unless you
|
58
57
|
explicitly alias it. Similarly, the startup configuration file is now called
|
@@ -66,7 +65,7 @@ no longer need to set them in the startup file.
|
|
66
65
|
* Works on 2.0.0 and it doesn't on 1.9.x.
|
67
66
|
* Has no MRI internal source code dependencies, just a clean API.
|
68
67
|
* Fixes most of debugger's current open issues:
|
69
|
-
- Post
|
68
|
+
- Post-mortem mode segfaulting.
|
70
69
|
- Line number wrongly shown as zero in backtrace.
|
71
70
|
- Line tracing.
|
72
71
|
- Colon delimited include paths.
|
@@ -76,11 +75,72 @@ no longer need to set them in the startup file.
|
|
76
75
|
- `byebug` can now be placed at the end of a block or method call.
|
77
76
|
* Very actively mantained.
|
78
77
|
* Editor agnostic: no external editor built-in support.
|
79
|
-
* No thread support. Haven't had time to look at it and I don't know whether
|
80
|
-
the new debugging API supports it yet.
|
81
78
|
* Pry command is built-in. No need of external gem like debugger-pry.
|
82
79
|
|
83
80
|
|
81
|
+
## Semantic Versioning
|
82
|
+
|
83
|
+
Byebug tries to follow [semantic versioning](semver.org). Backwards
|
84
|
+
compatibility doesn't seem like a critic issue for a debugger because it's not
|
85
|
+
supposed to be used permanently by any program, let alone in production
|
86
|
+
environments. However, I still like the idea of giving some meaning to version
|
87
|
+
changes.
|
88
|
+
|
89
|
+
Byebug's public API is determined by its set of commands
|
90
|
+
|
91
|
+
+-----------+----------+------------------------------------------------+
|
92
|
+
| Command | Aliases | Subcommands |
|
93
|
+
+-----------+----------+------------------------------------------------+
|
94
|
+
| backtrace | bt|where | |
|
95
|
+
| break | | |
|
96
|
+
| catch | | |
|
97
|
+
| condition | | |
|
98
|
+
| continue | | |
|
99
|
+
| delete | | |
|
100
|
+
| disable | | breakpoints|display |
|
101
|
+
| display | | |
|
102
|
+
| down | | |
|
103
|
+
| edit | | |
|
104
|
+
| enable | | breakpoints|display |
|
105
|
+
| finish | | |
|
106
|
+
| frame | | |
|
107
|
+
| help | | |
|
108
|
+
| info | | args|breakpoints|catch|display|file|files |
|
109
|
+
| | | global_variables|instance_variables|line |
|
110
|
+
| | | locals|program|stack|variables |
|
111
|
+
| irb | | |
|
112
|
+
| kill | | |
|
113
|
+
| list | | |
|
114
|
+
| method | | instance|iv |
|
115
|
+
| next | | |
|
116
|
+
| p | eval | |
|
117
|
+
| pp | | |
|
118
|
+
| pry | | |
|
119
|
+
| ps | | |
|
120
|
+
| putl | | |
|
121
|
+
| quit | exit | |
|
122
|
+
| reload | | |
|
123
|
+
| restart | | |
|
124
|
+
| save | | |
|
125
|
+
| set | | args|autoeval|autoirb|autolist|autoreload |
|
126
|
+
| | | basename|callstyle|forcestep|fullpath|history |
|
127
|
+
| | | linetrace|linetrace_plus|listsize|post_mortem |
|
128
|
+
| | | stack_trace_on_error|testing|width |
|
129
|
+
| show | | args|autoeval|autoirb|autolist|autoreload |
|
130
|
+
| | | basename|callstyle|commands|forcestep|fullpath |
|
131
|
+
| | | history|linetrace|linetrace_plus|listsize |
|
132
|
+
| | | post_mortem|stack_trace_on_error|width |
|
133
|
+
| skip | | |
|
134
|
+
| source | | |
|
135
|
+
| step | | |
|
136
|
+
| thread | | current|list|resume|stop|switch |
|
137
|
+
| trace | | |
|
138
|
+
| undisplay | | |
|
139
|
+
| up | | |
|
140
|
+
| var | | class|constant|global|instance|local|ct |
|
141
|
+
+-----------+----------+------------------------------------------------+
|
142
|
+
|
143
|
+
|
84
144
|
## Getting Started
|
85
145
|
|
86
146
|
A handful of commands are enough to get started using `byebug`. The following
|
@@ -241,6 +301,8 @@ quit without being prompted, suffix the command with an exclamation mark, e.g.,
|
|
241
301
|
`step`, `finish`, `continue` and `break` commands to pry using byebug.
|
242
302
|
* [ruby-debug-passenger](https://github.com/davejamesmiller/ruby-debug-passenger)
|
243
303
|
adds a rake task that restarts Passenger with byebug connected.
|
304
|
+
* [minitest-byebug](https://github.com/kaspth/minitest-byebug) starts a byebug
|
305
|
+
session on minitest failures.
|
244
306
|
|
245
307
|
|
246
308
|
## Credits
|
@@ -255,6 +317,7 @@ software, specially:
|
|
255
317
|
* Dennis Ushakov, author of [debase](https://github.com/denofevil/debase), the
|
256
318
|
starting point of this.
|
257
319
|
* Logo by [Ivlichev Victor Petrovich](http://www.aha-soft.com/)
|
320
|
+
* @kevjames3 for testing, bug reports and the interest in the project.
|
258
321
|
|
259
322
|
[1]: https://badge.fury.io/rb/byebug.png
|
260
323
|
[2]: http://badge.fury.io/rb/byebug
|
data/bin/byebug
CHANGED
@@ -12,12 +12,6 @@
|
|
12
12
|
#
|
13
13
|
#=== Options
|
14
14
|
#
|
15
|
-
#<tt>-A | --annotate</tt> <i>level</i>::
|
16
|
-
# Set gdb-style annotation to <i>level</i>, a number. Additional information
|
17
|
-
# is output automatically when program state is changed. This can be used by
|
18
|
-
# front-ends such as GNU Emacs to post this updated information without
|
19
|
-
# having to poll for it.
|
20
|
-
#
|
21
15
|
#<tt>-d | --debug</tt>::
|
22
16
|
# Set $DEBUG true.
|
23
17
|
#
|
@@ -74,11 +68,8 @@ def debug_program(options)
|
|
74
68
|
puts output
|
75
69
|
exit $?.exitstatus
|
76
70
|
end
|
77
|
-
print "\032\032starting\n" if Byebug.annotate and Byebug.annotate > 2
|
78
|
-
|
79
71
|
if bt = Byebug.debug_load(Byebug::PROG_SCRIPT, options.stop)
|
80
|
-
|
81
|
-
print "Uncaught exception: #{bt}\n"
|
72
|
+
p bt, bt.backtrace
|
82
73
|
end
|
83
74
|
end
|
84
75
|
|
@@ -98,7 +89,6 @@ def whence_file(prog_script)
|
|
98
89
|
end
|
99
90
|
|
100
91
|
options = OpenStruct.new(
|
101
|
-
'annotate' => Byebug.annotate,
|
102
92
|
'nx' => false,
|
103
93
|
'post_mortem' => false,
|
104
94
|
'quit' => true,
|
@@ -119,8 +109,6 @@ EOB
|
|
119
109
|
opts.separator ""
|
120
110
|
opts.separator "Options:"
|
121
111
|
|
122
|
-
opts.on("-A", "--annotate LEVEL", Integer, "Set annotation level") {
|
123
|
-
|annotate| Byebug.annotate = annotate }
|
124
112
|
opts.on("-d", "--debug", "Set $DEBUG=true") {
|
125
113
|
$DEBUG = true }
|
126
114
|
opts.on('-I', '--include PATH', String,
|
@@ -246,14 +234,9 @@ Byebug.tracing = options.tracing
|
|
246
234
|
loop do
|
247
235
|
begin
|
248
236
|
debug_program(options)
|
249
|
-
rescue
|
250
|
-
|
251
|
-
puts "Uncaught Syntax Error\n"
|
252
|
-
rescue
|
253
|
-
print $!.backtrace.map{|l| "\t#{l}"}.join("\n"), "\n"
|
254
|
-
print "Uncaught exception: #{$!}\n"
|
237
|
+
rescue Exception
|
238
|
+
p $!, $@
|
255
239
|
end
|
256
|
-
print "The program finished.\n" unless Byebug.annotate.to_i > 1
|
257
240
|
|
258
241
|
break if options.quit
|
259
242
|
|
data/ext/byebug/breakpoint.c
CHANGED
@@ -21,37 +21,78 @@ eval_expression(VALUE args)
|
|
21
21
|
return rb_funcall2(rb_mKernel, idEval, 2, RARRAY_PTR(args));
|
22
22
|
}
|
23
23
|
|
24
|
+
/*
|
25
|
+
* call-seq:
|
26
|
+
* breakpoint.enabled? -> bool
|
27
|
+
*
|
28
|
+
* Returns +true+ if breakpoint is enabled, false otherwise.
|
29
|
+
*/
|
24
30
|
static VALUE
|
25
|
-
|
31
|
+
brkpt_enabled(VALUE self)
|
26
32
|
{
|
27
33
|
breakpoint_t *breakpoint;
|
28
34
|
|
29
35
|
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
30
|
-
return
|
36
|
+
return breakpoint->enabled;
|
31
37
|
}
|
32
38
|
|
33
|
-
|
39
|
+
/*
|
40
|
+
* call-seq:
|
41
|
+
* breakpoint.enabled = bool
|
42
|
+
*
|
43
|
+
* Enables or disables breakpoint.
|
44
|
+
*/
|
34
45
|
static VALUE
|
35
|
-
|
46
|
+
brkpt_set_enabled(VALUE self, VALUE bool)
|
36
47
|
{
|
37
48
|
breakpoint_t *breakpoint;
|
38
49
|
|
39
50
|
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
40
|
-
return
|
51
|
+
return breakpoint->enabled = bool;
|
41
52
|
}
|
42
53
|
|
54
|
+
/*
|
55
|
+
* call-seq:
|
56
|
+
* breakpoint.expr -> string
|
57
|
+
*
|
58
|
+
* Returns a conditional expression which indicates when this breakpoint should
|
59
|
+
* be activated.
|
60
|
+
*/
|
43
61
|
static VALUE
|
44
|
-
|
62
|
+
brkpt_expr(VALUE self)
|
45
63
|
{
|
46
|
-
|
64
|
+
breakpoint_t *breakpoint;
|
47
65
|
|
48
|
-
|
49
|
-
|
50
|
-
|
66
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
67
|
+
return breakpoint->expr;
|
68
|
+
}
|
69
|
+
|
70
|
+
/*
|
71
|
+
* call-seq:
|
72
|
+
* breakpoint.expr = string | nil
|
73
|
+
*
|
74
|
+
* Sets or unsets the conditional expression which indicates when this
|
75
|
+
* breakpoint should be activated.
|
76
|
+
*/
|
77
|
+
static VALUE
|
78
|
+
brkpt_set_expr(VALUE self, VALUE expr)
|
79
|
+
{
|
80
|
+
breakpoint_t *breakpoint;
|
81
|
+
|
82
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
83
|
+
breakpoint->expr = NIL_P(expr) ? expr: StringValue(expr);
|
84
|
+
return expr;
|
51
85
|
}
|
52
86
|
|
87
|
+
/*
|
88
|
+
* call-seq:
|
89
|
+
* breakpoint.hit_condition -> symbol
|
90
|
+
*
|
91
|
+
* Returns the hit condition of the breakpoint: +nil+ if it is an
|
92
|
+
* unconditional breakpoint, or :greater_or_equal, :equal or :modulo otherwise
|
93
|
+
*/
|
53
94
|
static VALUE
|
54
|
-
|
95
|
+
brkpt_hit_condition(VALUE self)
|
55
96
|
{
|
56
97
|
breakpoint_t *breakpoint;
|
57
98
|
|
@@ -70,8 +111,18 @@ Breakpoint_hit_condition(VALUE self)
|
|
70
111
|
}
|
71
112
|
}
|
72
113
|
|
114
|
+
/*
|
115
|
+
* call-seq:
|
116
|
+
* breakpoint.hit_condition = symbol
|
117
|
+
*
|
118
|
+
* Sets the hit condition of the breakpoint which must be one of the following
|
119
|
+
* values:
|
120
|
+
*
|
121
|
+
* +nil+ if it is an unconditional breakpoint, or
|
122
|
+
* :greater_or_equal(:ge), :equal(:eq), :modulo(:mod)
|
123
|
+
*/
|
73
124
|
static VALUE
|
74
|
-
|
125
|
+
brkpt_set_hit_condition(VALUE self, VALUE value)
|
75
126
|
{
|
76
127
|
breakpoint_t *breakpoint;
|
77
128
|
ID id_value;
|
@@ -90,90 +141,78 @@ Breakpoint_set_hit_condition(VALUE self, VALUE value)
|
|
90
141
|
return value;
|
91
142
|
}
|
92
143
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
static VALUE
|
101
|
-
Breakpoint_create(VALUE klass)
|
102
|
-
{
|
103
|
-
breakpoint_t *breakpoint = ALLOC(breakpoint_t);
|
104
|
-
|
105
|
-
return Data_Wrap_Struct(klass, Breakpoint_mark, xfree, breakpoint);
|
106
|
-
}
|
107
|
-
|
144
|
+
/*
|
145
|
+
* call-seq:
|
146
|
+
* breakpoint.hit_count -> int
|
147
|
+
*
|
148
|
+
* Returns the number of times this breakpoint has been hit.
|
149
|
+
*/
|
108
150
|
static VALUE
|
109
|
-
|
151
|
+
brkpt_hit_count(VALUE self)
|
110
152
|
{
|
111
153
|
breakpoint_t *breakpoint;
|
112
154
|
|
113
155
|
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
114
|
-
|
115
|
-
breakpoint->type = FIXNUM_P(pos) ? BP_POS_TYPE : BP_METHOD_TYPE;
|
116
|
-
if(breakpoint->type == BP_POS_TYPE)
|
117
|
-
breakpoint->pos.line = FIX2INT(pos);
|
118
|
-
else
|
119
|
-
breakpoint->pos.mid = SYM2ID(pos);
|
120
|
-
|
121
|
-
breakpoint->id = ++breakpoint_max;
|
122
|
-
breakpoint->source = StringValue(source);
|
123
|
-
breakpoint->enabled = Qtrue;
|
124
|
-
breakpoint->expr = NIL_P(expr) ? expr : StringValue(expr);
|
125
|
-
breakpoint->hit_count = 0;
|
126
|
-
breakpoint->hit_value = 0;
|
127
|
-
breakpoint->hit_condition = HIT_COND_NONE;
|
128
|
-
|
129
|
-
return Qnil;
|
156
|
+
return INT2FIX(breakpoint->hit_count);
|
130
157
|
}
|
131
158
|
|
159
|
+
/*
|
160
|
+
* call-seq:
|
161
|
+
* breakpoint.hit_value -> int
|
162
|
+
*
|
163
|
+
* Returns the hit value of the breakpoint, namely, a value to build a
|
164
|
+
* condition on the number of hits of the breakpoint.
|
165
|
+
*/
|
132
166
|
static VALUE
|
133
|
-
|
167
|
+
brkpt_hit_value(VALUE self)
|
134
168
|
{
|
135
|
-
|
136
|
-
int id;
|
137
|
-
VALUE breakpoint_object;
|
138
|
-
breakpoint_t *breakpoint;
|
139
|
-
|
140
|
-
if (breakpoints == Qnil) return Qnil;
|
141
|
-
|
142
|
-
id = FIX2INT(id_value);
|
169
|
+
breakpoint_t *breakpoint;
|
143
170
|
|
144
|
-
|
145
|
-
|
146
|
-
breakpoint_object = rb_ary_entry(breakpoints, i);
|
147
|
-
Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint);
|
148
|
-
if(breakpoint->id == id)
|
149
|
-
{
|
150
|
-
rb_ary_delete_at(breakpoints, i);
|
151
|
-
return breakpoint_object;
|
152
|
-
}
|
153
|
-
}
|
154
|
-
return Qnil;
|
171
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
172
|
+
return INT2FIX(breakpoint->hit_value);
|
155
173
|
}
|
156
174
|
|
175
|
+
/*
|
176
|
+
* call-seq:
|
177
|
+
* breakpoint.hit_value = int
|
178
|
+
*
|
179
|
+
* Sets the hit value of the breakpoint. This allows the user to set conditions
|
180
|
+
* on the number of hits to enable/disable the breakpoint.
|
181
|
+
*/
|
157
182
|
static VALUE
|
158
|
-
|
183
|
+
brkpt_set_hit_value(VALUE self, VALUE value)
|
159
184
|
{
|
160
|
-
|
185
|
+
breakpoint_t *breakpoint;
|
161
186
|
|
162
|
-
|
163
|
-
|
187
|
+
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
188
|
+
breakpoint->hit_value = FIX2INT(value);
|
189
|
+
return value;
|
164
190
|
}
|
165
191
|
|
192
|
+
/*
|
193
|
+
* call-seq:
|
194
|
+
* breakpoint.id -> int
|
195
|
+
*
|
196
|
+
* Returns the id of the breakpoint.
|
197
|
+
*/
|
166
198
|
static VALUE
|
167
|
-
|
199
|
+
brkpt_id(VALUE self)
|
168
200
|
{
|
169
201
|
breakpoint_t *breakpoint;
|
170
202
|
|
171
203
|
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
172
|
-
return breakpoint->
|
204
|
+
return INT2FIX(breakpoint->id);
|
173
205
|
}
|
174
206
|
|
207
|
+
/*
|
208
|
+
* call-seq:
|
209
|
+
* breakpoint.pos -> string or int
|
210
|
+
*
|
211
|
+
* Returns the position of this breakpoint, either a method name or a line
|
212
|
+
* number.
|
213
|
+
*/
|
175
214
|
static VALUE
|
176
|
-
|
215
|
+
brkpt_pos(VALUE self)
|
177
216
|
{
|
178
217
|
breakpoint_t *breakpoint;
|
179
218
|
|
@@ -184,42 +223,83 @@ Breakpoint_pos(VALUE self)
|
|
184
223
|
return INT2FIX(breakpoint->pos.line);
|
185
224
|
}
|
186
225
|
|
187
|
-
|
226
|
+
/*
|
227
|
+
* call-seq:
|
228
|
+
* breakpoint.source -> string
|
229
|
+
*
|
230
|
+
* Returns the source file of the breakpoint.
|
231
|
+
*/
|
188
232
|
static VALUE
|
189
|
-
|
233
|
+
brkpt_source(VALUE self)
|
190
234
|
{
|
191
235
|
breakpoint_t *breakpoint;
|
192
236
|
|
193
237
|
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
194
|
-
return breakpoint->
|
238
|
+
return breakpoint->source;
|
239
|
+
}
|
240
|
+
|
241
|
+
static void
|
242
|
+
mark_breakpoint(breakpoint_t *breakpoint)
|
243
|
+
{
|
244
|
+
rb_gc_mark(breakpoint->source);
|
245
|
+
rb_gc_mark(breakpoint->expr);
|
195
246
|
}
|
196
247
|
|
197
248
|
static VALUE
|
198
|
-
|
249
|
+
brkpt_create(VALUE klass)
|
199
250
|
{
|
200
|
-
breakpoint_t *breakpoint;
|
251
|
+
breakpoint_t *breakpoint = ALLOC(breakpoint_t);
|
201
252
|
|
202
|
-
|
203
|
-
breakpoint->expr = NIL_P(expr) ? expr: StringValue(expr);
|
204
|
-
return expr;
|
253
|
+
return Data_Wrap_Struct(klass, mark_breakpoint, xfree, breakpoint);
|
205
254
|
}
|
206
255
|
|
207
256
|
static VALUE
|
208
|
-
|
257
|
+
brkpt_initialize(VALUE self, VALUE source, VALUE pos, VALUE expr)
|
209
258
|
{
|
210
259
|
breakpoint_t *breakpoint;
|
211
260
|
|
212
261
|
Data_Get_Struct(self, breakpoint_t, breakpoint);
|
213
|
-
|
262
|
+
|
263
|
+
breakpoint->type = FIXNUM_P(pos) ? BP_POS_TYPE : BP_METHOD_TYPE;
|
264
|
+
if(breakpoint->type == BP_POS_TYPE)
|
265
|
+
breakpoint->pos.line = FIX2INT(pos);
|
266
|
+
else
|
267
|
+
breakpoint->pos.mid = SYM2ID(pos);
|
268
|
+
|
269
|
+
breakpoint->id = ++breakpoint_max;
|
270
|
+
breakpoint->source = StringValue(source);
|
271
|
+
breakpoint->enabled = Qtrue;
|
272
|
+
breakpoint->expr = NIL_P(expr) ? expr : StringValue(expr);
|
273
|
+
breakpoint->hit_count = 0;
|
274
|
+
breakpoint->hit_value = 0;
|
275
|
+
breakpoint->hit_condition = HIT_COND_NONE;
|
276
|
+
|
277
|
+
return Qnil;
|
214
278
|
}
|
215
279
|
|
216
280
|
static VALUE
|
217
|
-
|
281
|
+
brkpt_remove(VALUE self, VALUE breakpoints, VALUE id_value)
|
218
282
|
{
|
219
|
-
|
283
|
+
int i;
|
284
|
+
int id;
|
285
|
+
VALUE breakpoint_object;
|
286
|
+
breakpoint_t *breakpoint;
|
220
287
|
|
221
|
-
|
222
|
-
|
288
|
+
if (breakpoints == Qnil) return Qnil;
|
289
|
+
|
290
|
+
id = FIX2INT(id_value);
|
291
|
+
|
292
|
+
for(i = 0; i < RARRAY_LEN(breakpoints); i++)
|
293
|
+
{
|
294
|
+
breakpoint_object = rb_ary_entry(breakpoints, i);
|
295
|
+
Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint);
|
296
|
+
if(breakpoint->id == id)
|
297
|
+
{
|
298
|
+
rb_ary_delete_at(breakpoints, i);
|
299
|
+
return breakpoint_object;
|
300
|
+
}
|
301
|
+
}
|
302
|
+
return Qnil;
|
223
303
|
}
|
224
304
|
|
225
305
|
int
|
@@ -422,26 +502,30 @@ find_breakpoint_by_method(VALUE breakpoints, VALUE klass, ID mid, VALUE binding,
|
|
422
502
|
return Qnil;
|
423
503
|
}
|
424
504
|
|
425
|
-
|
505
|
+
void
|
426
506
|
Init_breakpoint(VALUE mByebug)
|
427
507
|
{
|
428
508
|
breakpoint_max = 0;
|
509
|
+
|
429
510
|
cBreakpoint = rb_define_class_under(mByebug, "Breakpoint", rb_cObject);
|
430
|
-
|
431
|
-
|
432
|
-
rb_define_method(cBreakpoint, "
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
rb_define_method(cBreakpoint, "
|
437
|
-
rb_define_method(cBreakpoint, "
|
438
|
-
rb_define_method(cBreakpoint, "
|
439
|
-
rb_define_method(cBreakpoint, "
|
440
|
-
rb_define_method(cBreakpoint, "
|
441
|
-
rb_define_method(cBreakpoint, "
|
442
|
-
rb_define_method(cBreakpoint, "
|
443
|
-
rb_define_method(cBreakpoint, "hit_value
|
444
|
-
|
511
|
+
|
512
|
+
rb_define_alloc_func(cBreakpoint, brkpt_create);
|
513
|
+
rb_define_method(cBreakpoint, "initialize", brkpt_initialize, 3);
|
514
|
+
|
515
|
+
rb_define_singleton_method(cBreakpoint, "remove", brkpt_remove, 2);
|
516
|
+
|
517
|
+
rb_define_method(cBreakpoint, "enabled?" , brkpt_enabled , 0);
|
518
|
+
rb_define_method(cBreakpoint, "enabled=" , brkpt_set_enabled , 1);
|
519
|
+
rb_define_method(cBreakpoint, "expr" , brkpt_expr , 0);
|
520
|
+
rb_define_method(cBreakpoint, "expr=" , brkpt_set_expr , 1);
|
521
|
+
rb_define_method(cBreakpoint, "hit_count" , brkpt_hit_count , 0);
|
522
|
+
rb_define_method(cBreakpoint, "hit_condition" , brkpt_hit_condition , 0);
|
523
|
+
rb_define_method(cBreakpoint, "hit_condition=", brkpt_set_hit_condition, 1);
|
524
|
+
rb_define_method(cBreakpoint, "hit_value" , brkpt_hit_value , 0);
|
525
|
+
rb_define_method(cBreakpoint, "hit_value=" , brkpt_set_hit_value , 1);
|
526
|
+
rb_define_method(cBreakpoint, "id" , brkpt_id , 0);
|
527
|
+
rb_define_method(cBreakpoint, "pos" , brkpt_pos , 0);
|
528
|
+
rb_define_method(cBreakpoint, "source" , brkpt_source , 0);
|
445
529
|
|
446
530
|
idEval = rb_intern("eval");
|
447
531
|
}
|