backtracie 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,175 @@
1
+ // backtracie: Ruby gem for beautiful backtraces
2
+ // Copyright (C) 2021 Ivo Anjo <ivo@ivoanjo.me>
3
+ //
4
+ // This file is part of backtracie.
5
+ //
6
+ // backtracie is free software: you can redistribute it and/or modify
7
+ // it under the terms of the GNU Lesser General Public License as published by
8
+ // the Free Software Foundation, either version 3 of the License, or
9
+ // (at your option) any later version.
10
+ //
11
+ // backtracie is distributed in the hope that it will be useful,
12
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ // GNU Lesser General Public License for more details.
15
+ //
16
+ // You should have received a copy of the GNU Lesser General Public License
17
+ // along with backtracie. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ // -----------------------------------------------------------------------------
20
+ // The file below has modified versions of code extracted from the Ruby project.
21
+ // The Ruby project copyright and license follow:
22
+ // -----------------------------------------------------------------------------
23
+
24
+ // Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
25
+ // You can redistribute it and/or modify it under either the terms of the
26
+ // 2-clause BSDL (see the file BSDL), or the conditions below:
27
+
28
+ // 1. You may make and give away verbatim copies of the source form of the
29
+ // software without restriction, provided that you duplicate all of the
30
+ // original copyright notices and associated disclaimers.
31
+
32
+ // 2. You may modify your copy of the software in any way, provided that
33
+ // you do at least ONE of the following:
34
+
35
+ // a. place your modifications in the Public Domain or otherwise
36
+ // make them Freely Available, such as by posting said
37
+ // modifications to Usenet or an equivalent medium, or by allowing
38
+ // the author to include your modifications in the software.
39
+
40
+ // b. use the modified software only within your corporation or
41
+ // organization.
42
+
43
+ // c. give non-standard binaries non-standard names, with
44
+ // instructions on where to get the original software distribution.
45
+
46
+ // d. make other distribution arrangements with the author.
47
+
48
+ // 3. You may distribute the software in object code or binary form,
49
+ // provided that you do at least ONE of the following:
50
+
51
+ // a. distribute the binaries and library files of the software,
52
+ // together with instructions (in the manual page or equivalent)
53
+ // on where to get the original distribution.
54
+
55
+ // b. accompany the distribution with the machine-readable source of
56
+ // the software.
57
+
58
+ // c. give non-standard binaries non-standard names, with
59
+ // instructions on where to get the original software distribution.
60
+
61
+ // d. make other distribution arrangements with the author.
62
+
63
+ // 4. You may modify and include the part of the software into any other
64
+ // software (possibly commercial). But some files in the distribution
65
+ // are not written by the author, so that they are not under these terms.
66
+
67
+ // For the list of those files and their copying conditions, see the
68
+ // file LEGAL.
69
+
70
+ // 5. The scripts and library files supplied as input to or produced as
71
+ // output from the software do not automatically fall under the
72
+ // copyright of the software, but belong to whomever generated them,
73
+ // and may be sold commercially, and may be aggregated with this
74
+ // software.
75
+
76
+ // 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
77
+ // IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
78
+ // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
79
+ // PURPOSE.
80
+
81
+ #ifndef RUBY_SHARDS_H
82
+ #define RUBY_SHARDS_H
83
+
84
+ // -----------------------------------------------------------------------------
85
+
86
+ /**********************************************************************
87
+ method.h -
88
+ created at: Wed Jul 15 20:02:33 2009
89
+ Copyright (C) 2009 Koichi Sasada
90
+ **********************************************************************/
91
+
92
+ #ifndef RUBY_MJIT_HEADER_INCLUDED
93
+ typedef enum {
94
+ VM_METHOD_TYPE_ISEQ, /*!< Ruby method */
95
+ VM_METHOD_TYPE_CFUNC, /*!< C method */
96
+ VM_METHOD_TYPE_ATTRSET, /*!< attr_writer or attr_accessor */
97
+ VM_METHOD_TYPE_IVAR, /*!< attr_reader or attr_accessor */
98
+ VM_METHOD_TYPE_BMETHOD,
99
+ VM_METHOD_TYPE_ZSUPER,
100
+ VM_METHOD_TYPE_ALIAS,
101
+ VM_METHOD_TYPE_UNDEF,
102
+ VM_METHOD_TYPE_NOTIMPLEMENTED,
103
+ VM_METHOD_TYPE_OPTIMIZED, /*!< Kernel#send, Proc#call, etc */
104
+ VM_METHOD_TYPE_MISSING, /*!< wrapper for method_missing(id) */
105
+ VM_METHOD_TYPE_REFINED, /*!< refinement */
106
+ } rb_method_type_t;
107
+ #define VM_METHOD_TYPE_MINIMUM_BITS 4
108
+
109
+ // Needed for Ruby 2.6 as this is not defined on any public header
110
+ void rb_hash_bulk_insert(long, const VALUE *, VALUE);
111
+ #endif
112
+
113
+ // -----------------------------------------------------------------------------
114
+
115
+ typedef struct {
116
+ unsigned int is_ruby_frame : 1; // 1 -> ruby frame / 0 -> cfunc frame
117
+
118
+ // for ruby frames where the callable_method_entry is not of type VM_METHOD_TYPE_ISEQ, most of the metadata we
119
+ // want can be found by querying the iseq, and there may not even be an callable_method_entry
120
+ unsigned int should_use_iseq : 1;
121
+ unsigned int should_use_cfunc_name : 1;
122
+
123
+ rb_method_type_t vm_method_type : VM_METHOD_TYPE_MINIMUM_BITS;
124
+ int line_number;
125
+ VALUE iseq;
126
+ VALUE callable_method_entry;
127
+ VALUE self;
128
+ VALUE cfunc_name;
129
+ } raw_location;
130
+
131
+ #ifndef PRE_MJIT_RUBY
132
+ int backtracie_rb_profile_frames(int limit, raw_location *raw_locations);
133
+ int backtracie_rb_profile_frames_for_thread(VALUE thread, int limit, raw_location *raw_locations);
134
+ #endif
135
+ VALUE backtracie_called_id(raw_location *the_location);
136
+ VALUE backtracie_defined_class(raw_location *the_location);
137
+ VALUE backtracie_rb_vm_top_self();
138
+ bool backtracie_iseq_is_block(raw_location *the_location);
139
+ bool backtracie_iseq_is_eval(raw_location *the_location);
140
+ VALUE backtracie_refinement_name(raw_location *the_location);
141
+
142
+ #ifdef PRE_MJIT_RUBY
143
+ int backtracie_profile_frames_from_ruby_locations(VALUE ruby_locations_array, raw_location *raw_locations);
144
+ #endif
145
+
146
+ // -----------------------------------------------------------------------------
147
+
148
+ // Ruby 3.0 finally added support for showing "cfunc frames" (frames for methods written in C) in stack traces:
149
+ // https://github.com/ruby/ruby/pull/3299/files
150
+ //
151
+ // The diff is rather trivial, and it makes a world of difference, given how most of Ruby's core classes are written in C.
152
+ // Thus, the methods below are copied from that PR so that we can make use of this functionality on older Ruby versions.
153
+ #ifdef CFUNC_FRAMES_BACKPORT_NEEDED
154
+ #define backtracie_rb_profile_frame_method_name backported_rb_profile_frame_method_name
155
+
156
+ VALUE backported_rb_profile_frame_method_name(VALUE frame);
157
+ #else // Ruby > 3.0, just use the stock functionality
158
+ #define backtracie_rb_profile_frame_method_name rb_profile_frame_method_name
159
+ #endif
160
+
161
+ // Backport https://github.com/ruby/ruby/pull/3084 (present in 2.7 and 3.0) to Ruby 2.6
162
+ // The interesting bit is actually the fix to rb_profile_frame_classpath BUT since rb_profile_frame_qualified_method_name
163
+ // internally relies on rb_profile_frame_classpath we also need to add a copy of that one as well.
164
+ #ifdef CLASSPATH_BACKPORT_NEEDED
165
+ #define backtracie_rb_profile_frame_classpath backported_rb_profile_frame_classpath
166
+ #define backtracie_rb_profile_frame_qualified_method_name backported_rb_profile_frame_qualified_method_name
167
+
168
+ VALUE backported_rb_profile_frame_classpath(VALUE frame);
169
+ VALUE backported_rb_profile_frame_qualified_method_name(VALUE frame);
170
+ #else
171
+ #define backtracie_rb_profile_frame_classpath rb_profile_frame_classpath
172
+ #define backtracie_rb_profile_frame_qualified_method_name rb_profile_frame_qualified_method_name
173
+ #endif
174
+
175
+ #endif
@@ -26,15 +26,17 @@ module Backtracie
26
26
  attr_accessor :label
27
27
  attr_accessor :lineno
28
28
  attr_accessor :path
29
+ attr_accessor :qualified_method_name
29
30
 
30
31
  # Note: The order of arguments is hardcoded in the native extension in the `new_location` function --
31
32
  # keep them in sync
32
- def initialize(absolute_path, base_label, label, lineno, path, debug)
33
+ def initialize(absolute_path, base_label, label, lineno, path, qualified_method_name, debug)
33
34
  @absolute_path = absolute_path
34
35
  @base_label = base_label
35
36
  @label = label
36
37
  @lineno = lineno
37
38
  @path = path
39
+ @qualified_method_name = qualified_method_name
38
40
  @debug = debug
39
41
 
40
42
  freeze
@@ -47,5 +49,14 @@ module Backtracie
47
49
  "#{@path}:in `#{@label}'"
48
50
  end
49
51
  end
52
+
53
+ # Still WIP
54
+ def fancy_to_s
55
+ if @lineno != 0
56
+ "#{@path}:#{@lineno}:in #{@qualified_method_name}"
57
+ else
58
+ "#{@path}:in #{@qualified_method_name}"
59
+ end
60
+ end
50
61
  end
51
62
  end
@@ -19,5 +19,5 @@
19
19
  # along with backtracie. If not, see <http://www.gnu.org/licenses/>.
20
20
 
21
21
  module Backtracie
22
- VERSION = "0.1.0"
22
+ VERSION = "0.2.0"
23
23
  end
metadata CHANGED
@@ -1,41 +1,33 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: backtracie
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivo Anjo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-12 00:00:00.000000000 Z
11
+ date: 2021-06-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Ruby gem for beautiful backtraces
14
14
  email:
15
15
  - ivo@ivoanjo.me
16
16
  executables: []
17
- extensions: []
17
+ extensions:
18
+ - ext/backtracie_native_extension/extconf.rb
18
19
  extra_rdoc_files: []
19
20
  files:
20
21
  - ".editorconfig"
21
- - ".gitignore"
22
- - ".rspec"
23
- - ".ruby-version"
24
- - ".standard.yml"
25
22
  - CODE_OF_CONDUCT.adoc
26
23
  - COPYING
27
24
  - COPYING.LESSER
28
- - DEVELOPMENT_NOTES.adoc
29
25
  - README.adoc
30
- - Rakefile
31
26
  - backtracie.gemspec
32
- - bin/console
33
- - bin/setup
34
27
  - ext/backtracie_native_extension/backtracie.c
35
28
  - ext/backtracie_native_extension/extconf.rb
36
- - ext/backtracie_native_extension/ruby_3.0.0.c
37
- - ext/backtracie_native_extension/ruby_3.0.0.h
38
- - gems.rb
29
+ - ext/backtracie_native_extension/ruby_shards.c
30
+ - ext/backtracie_native_extension/ruby_shards.h
39
31
  - lib/backtracie.rb
40
32
  - lib/backtracie/location.rb
41
33
  - lib/backtracie/version.rb
@@ -52,14 +44,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
52
44
  requirements:
53
45
  - - ">="
54
46
  - !ruby/object:Gem::Version
55
- version: 3.0.0
47
+ version: 2.3.0
56
48
  required_rubygems_version: !ruby/object:Gem::Requirement
57
49
  requirements:
58
50
  - - ">="
59
51
  - !ruby/object:Gem::Version
60
52
  version: '0'
61
53
  requirements: []
62
- rubygems_version: 3.2.3
54
+ rubygems_version: 3.1.4
63
55
  signing_key:
64
56
  specification_version: 4
65
57
  summary: Ruby gem for beautiful backtraces
data/.gitignore DELETED
@@ -1,33 +0,0 @@
1
- *.gem
2
- *.rbc
3
- /.config
4
- /coverage/
5
- /InstalledFiles
6
- /pkg/
7
- /spec/reports/
8
- /spec/examples.txt
9
- /test/tmp/
10
- /test/version_tmp/
11
- /tmp/
12
-
13
- # Used by dotenv library to load environment variables.
14
- # .env
15
-
16
- ## Documentation cache and generated files:
17
- /.yardoc/
18
- /_yardoc/
19
- /doc/
20
- /rdoc/
21
-
22
- ## Environment normalization:
23
- /.bundle/
24
- /vendor/bundle
25
- /lib/bundler/man/
26
-
27
- gems.locked
28
- Gemfile.lock
29
-
30
- *.o
31
- *.so
32
- ext/**/extconf.h
33
- ext/**/Makefile
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --require spec_helper
2
- --order defined
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- ruby-3.0.0
data/.standard.yml DELETED
@@ -1,14 +0,0 @@
1
- # Currently we only support >= 3.0.0 but I suspect we'll be able to support as far back as the Ruby version that
2
- # introduced mjit without a lot of trouble, so let's avoid making the code dependent on 3.0-only features
3
- ruby_version: 2.6
4
-
5
- ignore:
6
- - 'spec/unit/interesting_backtrace_helper.rb': # let's just say this file is special
7
- - Lint/UselessTimes
8
- - Style/EvalWithLocation
9
- - Style/GlobalVars
10
- - Style/MissingRespondToMissing
11
- - 'ext/backtracie_native_extension/extconf.rb':
12
- - Style/GlobalVars
13
- - 'spec/unit/backtracie_spec.rb':
14
- - Style/EvalWithLocation
@@ -1,399 +0,0 @@
1
- = Development Notes
2
-
3
- == Ideas to explore
4
-
5
- === Understand why `rb_profile_frames` does not return the correct iseq for a block.
6
-
7
- Given
8
-
9
- [source,ruby]
10
- ----
11
- def run
12
- puts "Backtracie: " + Backtracie.caller_locations.first.label
13
- puts "Ruby: " + caller_locations.first.label
14
- end
15
-
16
- def run2
17
- 1.times do
18
- run
19
- end
20
- end
21
- ----
22
-
23
- the output is
24
-
25
- ----
26
- Backtracie: run2
27
- Ruby: block in run2
28
- ----
29
-
30
- this is because inside `rb_profile_frames` the code goes
31
-
32
- [source,c]
33
- ----
34
- /* record frame info */
35
- cme = rb_vm_frame_method_entry(cfp);
36
- if (cme && cme->def->type == VM_METHOD_TYPE_ISEQ) {
37
- buff[i] = (VALUE)cme;
38
- }
39
- else {
40
- buff[i] = (VALUE)cfp->iseq;
41
- }
42
- ----
43
-
44
- and in this case the first branch is taken (we get the `cme`, not the `cfp->iseq`). I have no idea why.
45
-
46
- ==== Update:
47
-
48
- When using the `cfp->iseq` instead of the `cme`, in many cases, the `full_label`, `classpath`, `qualified_method_name`, `singleton_method_p` and `first_lineno` become less accurate.
49
-
50
- Why "less accurate"? Consider the following slightly compacted diff taken with backtracie and either `cme` or `cfp->iseq usage`, using the `interesting_backtrace_helper.rb`, looking at the output in the debug fields for the `Backtracie::Location` instances:
51
-
52
- [source, diff]
53
- ----
54
- --- cfp->iseq
55
- +++ cme
56
- @@ -6,16 +6,16 @@
57
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
58
- "hello",
59
- "hello",
60
- - "ClassA#hello",
61
- + "hello",
62
- 18,
63
- - "ClassA",
64
- + nil,
65
- false,
66
- "hello",
67
- - "ClassA#hello"],
68
- + "hello"],
69
- @@ -23,16 +23,16 @@
70
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
71
- "hello",
72
- "hello",
73
- - "ModuleB::ClassB#hello",
74
- + "hello",
75
- 27,
76
- - "ModuleB::ClassB",
77
- + nil,
78
- false,
79
- "hello",
80
- - "ModuleB::ClassB#hello"],
81
- + "hello"],
82
- @@ -40,16 +40,16 @@
83
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
84
- "hello",
85
- "hello",
86
- - "ModuleC.hello",
87
- + "hello",
88
- 34,
89
- - "ModuleC",
90
- - true,
91
- + nil,
92
- + false,
93
- "hello",
94
- - "ModuleC.hello"],
95
- + "hello"],
96
- @@ -57,16 +57,16 @@
97
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
98
- "hello",
99
- "hello",
100
- - "ClassWithStaticMethod.hello",
101
- + "hello",
102
- 40,
103
- - "ClassWithStaticMethod",
104
- - true,
105
- + nil,
106
- + false,
107
- "hello",
108
- - "ClassWithStaticMethod.hello"],
109
- + "hello"],
110
- @@ -74,16 +74,16 @@
111
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
112
- "hello",
113
- "hello",
114
- - "ModuleD#hello",
115
- + "hello",
116
- 46,
117
- - "ModuleD",
118
- + nil,
119
- false,
120
- "hello",
121
- - "ModuleD#hello"],
122
- + "hello"],
123
- @@ -125,16 +125,16 @@
124
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
125
- "hello",
126
- "hello",
127
- - "#<ClassD:0x0000556485af28e8>.hello",
128
- + "hello",
129
- 63,
130
- - "#<ClassD:0x0000556485af28e8>",
131
- - true,
132
- + nil,
133
- + false,
134
- "hello",
135
- - "#<ClassD:0x0000556485af28e8>.hello"],
136
- + "hello"],
137
- @@ -142,16 +142,16 @@
138
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
139
- "hello",
140
- "hello",
141
- - "ClassE#hello",
142
- + "hello",
143
- 68,
144
- - "ClassE",
145
- + nil,
146
- false,
147
- "hello",
148
- - "ClassE#hello"],
149
- + "hello"],
150
- @@ -176,16 +176,16 @@
151
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
152
- "hello",
153
- "hello",
154
- - "#<Module:0x0000556485af2140>#hello",
155
- + "hello",
156
- 82,
157
- - "#<Module:0x0000556485af2140>",
158
- + nil,
159
- false,
160
- "hello",
161
- - "#<Module:0x0000556485af2140>#hello"],
162
- + "hello"],
163
- @@ -193,16 +193,16 @@
164
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
165
- "hello",
166
- "hello",
167
- - "ModuleE.hello",
168
- + "hello",
169
- 92,
170
- - "ModuleE",
171
- - true,
172
- + nil,
173
- + false,
174
- "hello",
175
- - "ModuleE.hello"],
176
- + "hello"],
177
- @@ -210,33 +210,33 @@
178
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
179
- "method_missing",
180
- "method_missing",
181
- - "ClassH#method_missing",
182
- + "method_missing",
183
- 98,
184
- - "ClassH",
185
- + nil,
186
- false,
187
- "method_missing",
188
- - "ClassH#method_missing"],
189
- + "method_missing"],
190
- @label="method_missing",
191
- @lineno=101,
192
- @path="/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb">,
193
- - #<Backtracie::Location:0x0000556486191a00
194
- + #<Backtracie::Location:0x0000563ca3800df0
195
- @absolute_path="/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
196
- @base_label="hello",
197
- @debug=
198
- ["/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
199
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
200
- + "block in hello",
201
- "hello",
202
- - "hello",
203
- - "ClassF#hello",
204
- - 106,
205
- - "ClassF",
206
- + "block in hello",
207
- + 107,
208
- + nil,
209
- false,
210
- "hello",
211
- - "ClassF#hello"],
212
- - @label="hello",
213
- + "hello"],
214
- + @label="block in hello",
215
- @@ -252,16 +252,16 @@
216
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
217
- "hello",
218
- "hello",
219
- - "ClassF#hello",
220
- + "hello",
221
- 106,
222
- - "ClassF",
223
- + nil,
224
- false,
225
- "hello",
226
- - "ClassF#hello"],
227
- + "hello"],
228
- @@ -286,16 +286,16 @@
229
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
230
- "hello",
231
- "hello",
232
- - "#<Class:0x0000556485af0a70>.hello",
233
- + "hello",
234
- 121,
235
- - "#<Class:0x0000556485af0a70>",
236
- - true,
237
- + nil,
238
- + false,
239
- "hello",
240
- - "#<Class:0x0000556485af0a70>.hello"],
241
- + "hello"],
242
- @@ -303,16 +303,16 @@
243
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
244
- "hello",
245
- "hello",
246
- - "#<Class:0x0000556485af07a0>#hello",
247
- + "hello",
248
- 126,
249
- - "#<Class:0x0000556485af07a0>",
250
- + nil,
251
- false,
252
- "hello",
253
- - "#<Class:0x0000556485af07a0>#hello"],
254
- + "hello"],
255
- @@ -320,16 +320,16 @@
256
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
257
- "hello",
258
- "hello",
259
- - "#<Module:0x0000556485af0430>.hello",
260
- + "hello",
261
- 132,
262
- - "#<Module:0x0000556485af0430>",
263
- - true,
264
- + nil,
265
- + false,
266
- "hello",
267
- - "#<Module:0x0000556485af0430>.hello"],
268
- + "hello"],
269
- @@ -337,33 +337,33 @@
270
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
271
- "method_with_complex_parameters",
272
- "method_with_complex_parameters",
273
- - "Object#method_with_complex_parameters",
274
- + "method_with_complex_parameters",
275
- 137,
276
- - "Object",
277
- + nil,
278
- false,
279
- "method_with_complex_parameters",
280
- - "Object#method_with_complex_parameters"],
281
- + "method_with_complex_parameters"],
282
- @label="method_with_complex_parameters",
283
- @lineno=138,
284
- @path="/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb">,
285
- - #<Backtracie::Location:0x00005564861925e0
286
- + #<Backtracie::Location:0x0000563ca3801d90
287
- @absolute_path="/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
288
- @base_label="hello",
289
- @debug=
290
- ["/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
291
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
292
- + "block (2 levels) in hello",
293
- "hello",
294
- - "hello",
295
- - "ClassJ#hello",
296
- - 146,
297
- - "ClassJ",
298
- + "block (2 levels) in hello",
299
- + 148,
300
- + nil,
301
- false,
302
- "hello",
303
- - "ClassJ#hello"],
304
- - @label="hello",
305
- + "hello"],
306
- @@ -371,33 +371,33 @@
307
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
308
- "hello_helper",
309
- "hello_helper",
310
- - "ClassJ#hello_helper",
311
- + "hello_helper",
312
- 142,
313
- - "ClassJ",
314
- + nil,
315
- false,
316
- "hello_helper",
317
- - "ClassJ#hello_helper"],
318
- + "hello_helper"],
319
- @label="hello_helper",
320
- @lineno=143,
321
- @path="/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb">,
322
- - #<Backtracie::Location:0x0000556486192928
323
- + #<Backtracie::Location:0x0000563ca3801f70
324
- @absolute_path="/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
325
- @base_label="hello",
326
- @debug=
327
- ["/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
328
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
329
- + "block in hello",
330
- "hello",
331
- - "hello",
332
- - "ClassJ#hello",
333
- - 146,
334
- - "ClassJ",
335
- + "block in hello",
336
- + 147,
337
- + nil,
338
- false,
339
- "hello",
340
- - "ClassJ#hello"],
341
- - @label="hello",
342
- + "hello"],
343
- @@ -405,16 +405,16 @@
344
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
345
- "hello_helper",
346
- "hello_helper",
347
- - "ClassJ#hello_helper",
348
- + "hello_helper",
349
- 142,
350
- - "ClassJ",
351
- + nil,
352
- false,
353
- "hello_helper",
354
- - "ClassJ#hello_helper"],
355
- + "hello_helper"],
356
- @@ -422,16 +422,16 @@
357
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
358
- "hello",
359
- "hello",
360
- - "ClassJ#hello",
361
- + "hello",
362
- 146,
363
- - "ClassJ",
364
- + nil,
365
- false,
366
- "hello",
367
- - "ClassJ#hello"],
368
- + "hello"],
369
- @@ -439,16 +439,16 @@
370
- "/ruby/backtracie/spec/unit/interesting_backtrace_helper.rb",
371
- "top_level_hello",
372
- "top_level_hello",
373
- - "Object#top_level_hello",
374
- + "top_level_hello",
375
- 155,
376
- - "Object",
377
- + nil,
378
- false,
379
- "top_level_hello",
380
- - "Object#top_level_hello"],
381
- + "top_level_hello"],
382
- ----
383
-
384
- We can see that we miss the information about module/class names (we only get methods), we lose the singleton info, etc. The `first_lineno` numbers that move (which is not very important since we get the exact line via a different method). The only thing that is correct in the `cfp->iseq` version is getting "block in method" in the few places where we were missing it.
385
-
386
- So clearly the `cme` version in upstream Ruby is correct almost all of the time, except for the `label` missing the "block in method" in a few cases.
387
-
388
- This seems to point to the "block in method" issue either being an implementation bug (I still don't quite understand what the two different objects being used here represent) OR more of a "limitation" -- perhaps it's awkward to provide the correct label on the objects that miss it, and since the current MRI object returns one `VALUE` per stack frame, not two, the slight issue is just ignored.
389
-
390
- == TODO
391
-
392
- * Benchmarking
393
- * Tackle FIXMEs
394
- * Support Ruby < 3.0
395
- * Support showing class name, e.g. https://ivoanjo.me/blog/2020/07/05/ruby-experiment-include-class-names-in-backtraces/
396
- * Go beyond class name, e.g. https://ivoanjo.me/blog/2020/07/19/better-backtraces-in-ruby-using-tracepoint/
397
- * Implement equivalents to `Kernel#caller`, `Thread#backtrace`
398
- * Implement limits (similar to the arguments passed to the regular Ruby APIs)
399
- * User documentation