byebug 1.8.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|