Project

General

Profile

Feature #14801 » show_stack.patch

proof-of-concept patch for show_stack method - duerst (Martin Dürst), 06/01/2018 02:03 AM

View differences:

object.c (working copy)
895 895
    return obj;
896 896
}
897 897

  
898
/*
899
 *  call-seq:
900
 *    obj.show_stack -> obj
901
 *
902
 *  Outputs the current stack to stderr (similar to when there's an internal error).
903
 *
904
 *  This method is only expected to work on C Ruby.
905
 */
898 906

  
907
void rb_vmdebug_stack_show_raw_current(void); /* sloppy, should move to header file */
908
static VALUE
909
rb_obj_show_stack(VALUE obj)
910
{
911
    rb_vmdebug_stack_show_raw_current();
912
    return obj;
913
}
914

  
915

  
899 916
/*
900 917
 * Document-method: inherited
901 918
 *
......
4098 4115
    rb_define_method(rb_mKernel, "kind_of?", rb_obj_is_kind_of, 1);
4099 4116
    rb_define_method(rb_mKernel, "is_a?", rb_obj_is_kind_of, 1);
4100 4117
    rb_define_method(rb_mKernel, "tap", rb_obj_tap, 0);
4118
    rb_define_method(rb_mKernel, "show_stack", rb_obj_show_stack, 0);
4101 4119

  
4102 4120
    rb_define_global_function("sprintf", rb_f_sprintf, -1); /* in sprintf.c */
4103 4121
    rb_define_global_function("format", rb_f_sprintf, -1);  /* in sprintf.c */
vm.c (working copy)
453 453
    return hash;
454 454
}
455 455

  
456
/*
457
 *  call-seq:
458
 *    RubyVM.show_stack -> nil
459
 *
460
 *  Outputs the current stack to stderr (similar to when there's an internal error).
461
 *
462
 *  This method is only expected to work on C Ruby.
463
 */
464

  
465
void rb_vmdebug_stack_show_raw_current(void); /* sloppy, should move to header file */
466
static VALUE
467
vm_show_stack(int argc, VALUE *argv, VALUE self)
468
{
469
    rb_vmdebug_stack_show_raw_current();
470
    return Qnil;
471
}
472

  
456 473
/* control stack frame */
457 474

  
458 475
static void
......
2840 2857
    rb_undef_alloc_func(rb_cRubyVM);
2841 2858
    rb_undef_method(CLASS_OF(rb_cRubyVM), "new");
2842 2859
    rb_define_singleton_method(rb_cRubyVM, "stat", vm_stat, -1);
2860
    
2861
    rb_define_singleton_method(rb_cRubyVM, "show_stack", vm_show_stack, 0);
2843 2862

  
2844 2863
    /* FrozenCore (hidden) */
2845 2864
    fcore = rb_class_new(rb_cBasicObject);
vm_dump.c (working copy)
137 137
    fprintf(stderr, "\n");
138 138
}
139 139

  
140
// new function, to show stack during execution
141
// modified from rb_vmdebug_stack_dump_raw
142
void rb_vmdebug_stack_show_raw_current(void)
143
{
144
    const rb_execution_context_t *ec = GET_EC();
145
    const rb_control_frame_t *cfp = (rb_control_frame_t*) (ec->vm_stack + ec->vm_stack_size) - 1;
146
    const rb_control_frame_t *cfp_end = ec->cfp;
147
    VALUE *sp = cfp_end->sp, *ep;
148
    VALUE *p, *st, *t;
149

  
150

  
151
    fprintf(stderr, "-- Control Frames "
152
	    "-----------------------------------------------\n");
153
    while (cfp > cfp_end) {   // skip show_stack method itself
154
	control_frame_dump(ec, cfp);
155
	cfp--;
156
    }
157
    fprintf(stderr, "\n");
158

  
159
    fprintf(stderr, "-- Internal Stack ------------\n");
160
    for (p = sp-4, st = ec->vm_stack, cfp = cfp_end+1; p-3 >= ec->vm_stack; p--) {
161
        ep = (VALUE *)cfp->ep;
162
	fprintf(stderr, "%04ld (%p): %016"PRIxVALUE, (long)(p - st), p, *p);
163

  
164
	t = (VALUE *)*p;
165
	if (ec->vm_stack <= t && t < sp) {
166
	    fprintf(stderr, " (= %ld)", (long)((VALUE *)t - ec->vm_stack));
167
	}
168
        else if (p == ep) {
169
            fprintf(stderr, " (flags) <- Environment Pointer");
170
            fprintf(stderr, " (%ld)", ((rb_control_frame_t *)(ec->vm_stack + ec->vm_stack_size) - cfp));
171
        }
172
        else if (p == ep-1) {
173
            fprintf(stderr, " (specval)");
174
        }
175
        else if (p == ep-2) {
176
            fprintf(stderr, " (me_cref)");
177
            cfp++;
178
        }
179
        else {
180
            VALUE klass = rb_obj_class(*p);
181
            VALUE val = rb_mod_name(klass);
182
            if (!NIL_P(val)) {
183
                fprintf(stderr, " %s", RSTRING_PTR(val));
184
                if (FIXNUM_P(*p))
185
                    fprintf(stderr, ":    %d", FIX2INT(*p));
186
                else if (RB_TYPE_P(*p, T_FLOAT))
187
	            fprintf(stderr, ":      %g", RFLOAT_VALUE(*p));
188
                else if (klass == rb_cFalseClass)
189
                    fprintf(stderr, ": false");
190
                else if (klass == rb_cTrueClass)
191
                    fprintf(stderr, ":  true");
192
                else if (klass == rb_cNilClass)
193
                    fprintf(stderr, ":   nil");
194
                else if (klass == rb_cSymbol)
195
                    fprintf(stderr, ":     :%s", RSTRING_PTR(rb_sym_to_s(*p)));
196
                else if (klass == rb_cString && RSTRING_LEN(*p)<= 20)
197
                    fprintf(stderr, ":     '%s'", RSTRING_PTR(*p));
198
            }
199
        }
200
        if (p == (VALUE *)cfp->sp)
201
            fprintf(stderr, " <- Stack Pointer (%ld)", ((rb_control_frame_t *)(ec->vm_stack + ec->vm_stack_size) - cfp));
202

  
203
	fprintf(stderr, "\n");
204
    }
205
    fprintf(stderr, "\n");
206
}
207

  
140 208
void
141 209
rb_vmdebug_stack_dump_raw(const rb_execution_context_t *ec, const rb_control_frame_t *cfp)
142 210
{