13
13
#include "addr2line.h"
14
14
#include "vm_core.h"
15
15
#include "iseq.h"
16
+ #include "gc.h"
17
+
16
18
#ifdef HAVE_UCONTEXT_H
17
19
#include <ucontext.h>
18
20
#endif
38
40
((rb_control_frame_t *)((ec)->vm_stack + (ec)->vm_stack_size) - \
39
41
(rb_control_frame_t *)(cfp))
40
42
43
+ const char * rb_method_type_name (rb_method_type_t type );
44
+ int ruby_on_ci ;
45
+
41
46
static void
42
47
control_frame_dump (const rb_execution_context_t * ec , const rb_control_frame_t * cfp )
43
48
{
@@ -46,11 +51,10 @@ control_frame_dump(const rb_execution_context_t *ec, const rb_control_frame_t *c
46
51
char ep_in_heap = ' ' ;
47
52
char posbuf [MAX_POSBUF + 1 ];
48
53
int line = 0 ;
49
-
50
54
const char * magic , * iseq_name = "-" , * selfstr = "-" , * biseq_name = "-" ;
51
55
VALUE tmp ;
52
-
53
- const rb_callable_method_entry_t * me ;
56
+ const rb_iseq_t * iseq = NULL ;
57
+ const rb_callable_method_entry_t * me = rb_vm_frame_method_entry ( cfp ) ;
54
58
55
59
if (ep < 0 || (size_t )ep > ec -> vm_stack_size ) {
56
60
ep = (ptrdiff_t )cfp -> ep ;
@@ -110,15 +114,16 @@ control_frame_dump(const rb_execution_context_t *ec, const rb_control_frame_t *c
110
114
line = -1 ;
111
115
}
112
116
else {
113
- pc = cfp -> pc - cfp -> iseq -> body -> iseq_encoded ;
114
- iseq_name = RSTRING_PTR (cfp -> iseq -> body -> location .label );
117
+ iseq = cfp -> iseq ;
118
+ pc = cfp -> pc - iseq -> body -> iseq_encoded ;
119
+ iseq_name = RSTRING_PTR (iseq -> body -> location .label );
115
120
line = rb_vm_get_sourceline (cfp );
116
121
if (line ) {
117
- snprintf (posbuf , MAX_POSBUF , "%s:%d" , RSTRING_PTR (rb_iseq_path (cfp -> iseq )), line );
122
+ snprintf (posbuf , MAX_POSBUF , "%s:%d" , RSTRING_PTR (rb_iseq_path (iseq )), line );
118
123
}
119
124
}
120
125
}
121
- else if (( me = rb_vm_frame_method_entry ( cfp )) != NULL ) {
126
+ else if (me != NULL ) {
122
127
iseq_name = rb_id2name (me -> def -> original_id );
123
128
snprintf (posbuf , MAX_POSBUF , ":%s" , iseq_name );
124
129
line = -1 ;
@@ -148,6 +153,37 @@ control_frame_dump(const rb_execution_context_t *ec, const rb_control_frame_t *c
148
153
fprintf (stderr , "%-1s " , biseq_name );
149
154
}
150
155
fprintf (stderr , "\n" );
156
+
157
+ // additional information for CI machines
158
+ if (ruby_on_ci ) {
159
+ char buff [0x100 ];
160
+
161
+ if (me ) {
162
+ if (imemo_type_p ((VALUE )me , imemo_ment )) {
163
+ fprintf (stderr , " me:\n" );
164
+ fprintf (stderr , " called_id: %s, type: %s\n" , rb_id2name (me -> called_id ), rb_method_type_name (me -> def -> type ));
165
+ fprintf (stderr , " owner class: %s\n" , rb_raw_obj_info (buff , 0x100 , me -> owner ));
166
+ if (me -> owner != me -> defined_class ) {
167
+ fprintf (stderr , " defined_class: %s\n" , rb_raw_obj_info (buff , 0x100 , me -> defined_class ));
168
+ }
169
+ }
170
+ else {
171
+ fprintf (stderr , " me is corrupted (%s)\n" , rb_raw_obj_info (buff , 0x100 , (VALUE )me ));
172
+ }
173
+ }
174
+
175
+ if (iseq ) {
176
+ if (iseq -> body -> local_table_size > 0 ) {
177
+ fprintf (stderr , " lvars:\n" );
178
+ for (unsigned int i = 0 ; i < iseq -> body -> local_table_size ; i ++ ) {
179
+ const VALUE * argv = cfp -> ep - cfp -> iseq -> body -> local_table_size - VM_ENV_DATA_SIZE + 1 ;
180
+ fprintf (stderr , " %s: %s\n" ,
181
+ rb_id2name (iseq -> body -> local_table [i ]),
182
+ rb_raw_obj_info (buff , 0x100 , argv [i ]));
183
+ }
184
+ }
185
+ }
186
+ }
151
187
}
152
188
153
189
void
0 commit comments