static VALUE thread_backtrace(VALUE self) { rb_thread_t t = find_thread(self); struct FRAME *frame, *prev_frame; char buf[BUFSIZ]; VALUE ary; NODE *n; if (t == rb_curr_thread) { frame = ruby_frame; } else { frame = convert_pointer(t, t->frame); } ary = rb_ary_new(); if (frame->last_func == ID_ALLOCATOR) { frame = convert_pointer(t, frame->prev); } for (; frame && (n = frame->node); frame = prev_frame) { prev_frame = convert_pointer(t, frame->prev); if (prev_frame && prev_frame->last_func) { if (prev_frame->node == n) { if (prev_frame->last_func == frame->last_func) continue; } snprintf(buf, BUFSIZ, "%s:%d:in `%s'", n->nd_file, nd_line(n), rb_id2name(prev_frame->last_func)); } else { snprintf(buf, BUFSIZ, "%s:%d", n->nd_file, nd_line(n)); } rb_ary_push(ary, rb_str_new2(buf)); } return ary; }
static void coverage_event_coverage_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass) { char *sourcefile; unsigned int sourceline; static unsigned int in_hook = 0; if(in_hook) { return; } in_hook++; #if COVERAGE_DEBUG_EVENTS do { int status; VALUE old_exception; old_exception = rb_gv_get("$!"); rb_protect(rb_inspect, klass, &status); if(!status) { printf("EVENT: %d %s %s %s %d\n", event, klass ? RSTRING(rb_inspect(klass))->ptr : "", mid ? (mid == ID_ALLOCATOR ? "ID_ALLOCATOR" : rb_id2name(mid)) : "unknown", node ? node->nd_file : "", node ? nd_line(node) : 0); } else { printf("EVENT: %d %s %s %d\n", event, mid ? (mid == ID_ALLOCATOR ? "ID_ALLOCATOR" : rb_id2name(mid)) : "unknown", node ? node->nd_file : "", node ? nd_line(node) : 0); } rb_gv_set("$!", old_exception); } while (0); #endif if(event & RUBY_EVENT_C_CALL) { coverage_mark_caller(); } if(event & (RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN | RUBY_EVENT_CLASS)) { in_hook--; return; } if(node == NULL) { in_hook--; return; } sourcefile = node->nd_file; sourceline = nd_line(node) - 1; coverage_increase_counter_cached(sourcefile, sourceline); if(event & RUBY_EVENT_CALL) coverage_mark_caller(); in_hook--; }
static VALUE newobj_tramp() { VALUE ret = rb_newobj(); struct obj_track *tracker = NULL; if (track_objs) { tracker = malloc(sizeof(*tracker)); if (tracker) { if (ruby_current_node && ruby_current_node->nd_file && *ruby_current_node->nd_file) { tracker->source = strdup(ruby_current_node->nd_file); tracker->line = nd_line(ruby_current_node); } else if (ruby_sourcefile) { tracker->source = strdup(ruby_sourcefile); tracker->line = ruby_sourceline; } else { tracker->source = strdup("__null__"); tracker->line = 0; } tracker->obj = ret; st_insert(objs, (st_data_t)ret, (st_data_t)tracker); } else { fprintf(stderr, "Warning, unable to allocate a tracker. You are running dangerously low on RAM!\n"); } } return ret; }
NODE * ruby_debug_print_node(int level, int debug_level, const char *header, const NODE *node) { if (level < debug_level) { fprintf(stderr, "DBG> %s: %s (%lu)\n", header, ruby_node_name(nd_type(node)), nd_line(node)); } return (NODE *)node; }
static void coverage_mark_caller() { struct FRAME *frame = ruby_frame; NODE *n; if (frame->last_func == ID_ALLOCATOR) frame = frame->prev; for (; frame && (n = frame->node); frame = frame->prev) { if (frame->prev && frame->prev->last_func) { if (frame->prev->node == n) { if (frame->prev->last_func == frame->last_func) continue; } coverage_increase_counter_uncached(n->nd_file, nd_line(n) - 1, 1); } else { coverage_increase_counter_uncached(n->nd_file, nd_line(n) - 1, 1); } break; } }
/* The number of the line where the code associated with note are defined in the ruby source file */ VALUE rb_node_line(VALUE self) { NODE* _node; Data_Get_Struct(self,NODE,_node); #ifdef RUBY1_8 return INT2FIX(nd_line(_node)); #endif #ifdef RUBY1_9 return INT2FIX(0); #endif }
/* Emit jit instructions to set the current sourceline and sourcefile. */ static VALUE function_set_ruby_source(VALUE self, VALUE node_v) { #ifndef RUBY_VM NODE * n; jit_function_t function; Data_Get_Struct(self, struct _jit_function, function); Data_Get_Struct(node_v, NODE, n); // TODO: type check VALUE value_objects = (VALUE)jit_function_get_meta(function, RJT_VALUE_OBJECTS); jit_constant_t c; c.type = jit_type_int; c.un.int_value = nd_line(n); jit_value_t line = jit_value_create_constant(function, &c); c.type = jit_type_void_ptr; c.un.ptr_value = n->nd_file; jit_value_t file = jit_value_create_constant(function, &c); c.type = jit_type_void_ptr; c.un.ptr_value = n; jit_value_t node = jit_value_create_constant(function, &c); c.type = jit_type_void_ptr; c.un.ptr_value = &ruby_sourceline; jit_value_t ruby_sourceline_ptr = jit_value_create_constant(function, &c); c.type = jit_type_void_ptr; c.un.ptr_value = &ruby_sourcefile; jit_value_t ruby_sourcefile_ptr = jit_value_create_constant(function, &c); c.type = jit_type_void_ptr; c.un.ptr_value = &ruby_current_node; jit_value_t ruby_current_node_ptr = jit_value_create_constant(function, &c); jit_insn_store_relative(function, ruby_sourceline_ptr, 0, line); jit_insn_store_relative(function, ruby_sourcefile_ptr, 0, file); jit_insn_store_relative(function, ruby_current_node_ptr, 0, node); rb_ary_push(value_objects, node_v); #else /* TODO: Not sure what to do on 1.9 yet */ #endif return Qnil; }
/* * Return the source file and line number of the given object and method. */ VALUE Looksee_source_location(VALUE self, VALUE unbound_method) { if (!rb_obj_is_kind_of(unbound_method, rb_cUnboundMethod)) rb_raise(rb_eTypeError, "expected UnboundMethod, got %s", rb_obj_classname(unbound_method)); struct METHOD *method; Data_Get_Struct(unbound_method, struct METHOD, method); NODE *node; switch (nd_type(method->body)) { // Can't be a FBODY or ZSUPER. case NODE_SCOPE: node = method->body->nd_defn; break; case NODE_BMETHOD: { struct BLOCK *block; Data_Get_Struct(method->body->nd_orig, struct BLOCK, block); (node = block->frame.node) || (node = block->body); // Proc#to_s suggests this may be NULL sometimes. if (!node) return Qnil; } break; case NODE_DMETHOD: { struct METHOD *original_method; NODE *body = method->body; Data_Get_Struct(body->nd_orig, struct METHOD, original_method); node = original_method->body->nd_defn; } break; default: return Qnil; } VALUE file = rb_str_new2(node->nd_file); VALUE line = INT2NUM(nd_line(node)); VALUE location = rb_ary_new2(2); rb_ary_store(location, 0, file); rb_ary_store(location, 1, line); return location; }
void ruby_backtrace_each(sanspleur_backtrace_iter_func* iterator, void* arg) { struct FRAME *frame = ruby_frame; NODE *n; for (; frame && (n = frame->node); frame = frame->prev) { ID function_id = 0; const char* function_name = NULL; const char* file_name = NULL; int line_number = 0; ID class_id = 0; const char* class_name = NULL; function_id = frame->last_func; if (function_id) function_name = rb_id2name(function_id); file_name = n->nd_file; line_number = nd_line(n); class_id = frame->last_class; if (class_id) class_name = rb_class2name(class_id); iterator(arg, file_name, line_number, function_name, function_id, class_name, class_id); } }
int main(void) { alt_u16 *pFrameBuffer; // システム初期化 IOWR(LED_7SEG_BASE, 0, ~0x71733d77); // FPGAと表示する IOWR(BLCON_BASE, 0, (0<<8)); // バックライトOFF systeminit(); // ファイルシステム初期化 mmcfs_setup(); // VGA初期化 nd_GsVgaInit(); pFrameBuffer = (alt_u16 *)alt_uncached_malloc(na_VRAM_size); if (pFrameBuffer == NULL) { printf("[!] Framebuffer assignment failed.\n"); return -1; } nd_GsVgaSetBuffer((nd_u32)pFrameBuffer); nd_GsEglPage((nd_u32)pFrameBuffer,(nd_u32)pFrameBuffer,0); nd_color(nd_COLORGRAY, 0, 256); nd_boxfill(0, 0, window_xmax, window_ymax); nd_color(nd_COLORWHITE, 0, 256); nd_line(0,0, 0,window_ymax); nd_color(nd_COLORRED, 0, 256); nd_line(window_xmax,0, window_xmax,window_ymax); nd_color(nd_COLORLIGHTGREEN, 0, 256); nd_line(0,0, window_xmax,0); nd_color(nd_COLORBLUE, 0, 256); nd_line(0,window_ymax, window_xmax,window_ymax); nd_GsVgaScanOn(); IOWR(BLCON_BASE, 0, (1<<8)|0); // バックライトON、輝度最大 // 画像を展開 loadbmp("mmcfs:/de0/test.bmp",pFrameBuffer); printf("done.\n"); while(1) {} // 終了処理 nd_GsVgaScanOff(); alt_uncached_free(pFrameBuffer); return 0; }
void obj_dump(VALUE obj, yajl_gen gen) { int type; yajl_gen_map_open(gen); yajl_gen_cstr(gen, "_id"); yajl_gen_value(gen, obj); struct obj_track *tracker = NULL; if (st_lookup(objs, (st_data_t)obj, (st_data_t *)&tracker) && BUILTIN_TYPE(obj) != T_NODE) { yajl_gen_cstr(gen, "file"); yajl_gen_cstr(gen, tracker->source); yajl_gen_cstr(gen, "line"); yajl_gen_integer(gen, tracker->line); } yajl_gen_cstr(gen, "type"); switch (type=BUILTIN_TYPE(obj)) { case T_DATA: yajl_gen_cstr(gen, "data"); if (RBASIC(obj)->klass) { yajl_gen_cstr(gen, "class"); yajl_gen_value(gen, RBASIC(obj)->klass); yajl_gen_cstr(gen, "class_name"); VALUE name = rb_classname(RBASIC(obj)->klass); if (RTEST(name)) yajl_gen_cstr(gen, RSTRING(name)->ptr); else yajl_gen_cstr(gen, 0); } break; case T_FILE: yajl_gen_cstr(gen, "file"); break; case T_FLOAT: yajl_gen_cstr(gen, "float"); yajl_gen_cstr(gen, "data"); yajl_gen_double(gen, RFLOAT(obj)->value); break; case T_BIGNUM: yajl_gen_cstr(gen, "bignum"); yajl_gen_cstr(gen, "negative"); yajl_gen_bool(gen, RBIGNUM(obj)->sign == 0); yajl_gen_cstr(gen, "length"); yajl_gen_integer(gen, RBIGNUM(obj)->len); yajl_gen_cstr(gen, "data"); yajl_gen_string(gen, RBIGNUM(obj)->digits, RBIGNUM(obj)->len); break; case T_MATCH: yajl_gen_cstr(gen, "match"); yajl_gen_cstr(gen, "data"); yajl_gen_value(gen, RMATCH(obj)->str); break; case T_REGEXP: yajl_gen_cstr(gen, "regexp"); yajl_gen_cstr(gen, "length"); yajl_gen_integer(gen, RREGEXP(obj)->len); yajl_gen_cstr(gen, "data"); yajl_gen_cstr(gen, RREGEXP(obj)->str); break; case T_SCOPE: yajl_gen_cstr(gen, "scope"); struct SCOPE *scope = (struct SCOPE *)obj; if (scope->local_tbl) { int i = 1; int n = scope->local_tbl[0]; VALUE *list = &scope->local_vars[-1]; VALUE cur = *list++; yajl_gen_cstr(gen, "node"); yajl_gen_value(gen, cur); if (n) { yajl_gen_cstr(gen, "variables"); yajl_gen_map_open(gen); while (n--) { cur = *list++; yajl_gen_cstr(gen, scope->local_tbl[i] == 95 ? "_" : rb_id2name(scope->local_tbl[i])); yajl_gen_value(gen, cur); i++; } yajl_gen_map_close(gen); } } break; case T_NODE: yajl_gen_cstr(gen, "node"); yajl_gen_cstr(gen, "node_type"); yajl_gen_cstr(gen, nd_type_str(obj)); yajl_gen_cstr(gen, "file"); yajl_gen_cstr(gen, RNODE(obj)->nd_file); yajl_gen_cstr(gen, "line"); yajl_gen_integer(gen, nd_line(obj)); yajl_gen_cstr(gen, "node_code"); yajl_gen_integer(gen, nd_type(obj)); switch (nd_type(obj)) { case NODE_SCOPE: break; } break; case T_STRING: yajl_gen_cstr(gen, "string"); yajl_gen_cstr(gen, "length"); yajl_gen_integer(gen, RSTRING(obj)->len); if (FL_TEST(obj, ELTS_SHARED|FL_USER3)) { yajl_gen_cstr(gen, "shared"); yajl_gen_value(gen, RSTRING(obj)->aux.shared); yajl_gen_cstr(gen, "flags"); yajl_gen_array_open(gen); if (FL_TEST(obj, ELTS_SHARED)) yajl_gen_cstr(gen, "elts_shared"); if (FL_TEST(obj, FL_USER3)) yajl_gen_cstr(gen, "str_assoc"); yajl_gen_array_close(gen); } else { yajl_gen_cstr(gen, "data"); yajl_gen_string(gen, (unsigned char *)RSTRING(obj)->ptr, RSTRING(obj)->len); } break; case T_VARMAP: yajl_gen_cstr(gen, "varmap"); struct RVarmap *vars = (struct RVarmap *)obj; if (vars->next) { yajl_gen_cstr(gen, "next"); yajl_gen_value(gen, (VALUE)vars->next); } if (vars->id) { yajl_gen_cstr(gen, "data"); yajl_gen_map_open(gen); yajl_gen_cstr(gen, rb_id2name(vars->id)); yajl_gen_value(gen, vars->val); yajl_gen_map_close(gen); } break; case T_CLASS: case T_MODULE: case T_ICLASS: yajl_gen_cstr(gen, type==T_CLASS ? "class" : type==T_MODULE ? "module" : "iclass"); yajl_gen_cstr(gen, "name"); VALUE name = rb_classname(obj); if (RTEST(name)) yajl_gen_cstr(gen, RSTRING(name)->ptr); else yajl_gen_cstr(gen, 0); yajl_gen_cstr(gen, "super"); yajl_gen_value(gen, RCLASS(obj)->super); yajl_gen_cstr(gen, "super_name"); VALUE super_name = rb_classname(RCLASS(obj)->super); if (RTEST(super_name)) yajl_gen_cstr(gen, RSTRING(super_name)->ptr); else yajl_gen_cstr(gen, 0); if (FL_TEST(obj, FL_SINGLETON)) { yajl_gen_cstr(gen, "singleton"); yajl_gen_bool(gen, 1); } if (RCLASS(obj)->iv_tbl && RCLASS(obj)->iv_tbl->num_entries) { yajl_gen_cstr(gen, "ivars"); yajl_gen_map_open(gen); st_foreach(RCLASS(obj)->iv_tbl, each_ivar, (st_data_t)gen); yajl_gen_map_close(gen); } if (type != T_ICLASS && RCLASS(obj)->m_tbl && RCLASS(obj)->m_tbl->num_entries) { yajl_gen_cstr(gen, "methods"); yajl_gen_map_open(gen); st_foreach(RCLASS(obj)->m_tbl, each_ivar, (st_data_t)gen); yajl_gen_map_close(gen); } break; case T_OBJECT: yajl_gen_cstr(gen, "object"); yajl_gen_cstr(gen, "class"); yajl_gen_value(gen, RBASIC(obj)->klass); yajl_gen_cstr(gen, "class_name"); yajl_gen_cstr(gen, rb_obj_classname(obj)); struct RClass *klass = RCLASS(obj); if (klass->iv_tbl && klass->iv_tbl->num_entries) { yajl_gen_cstr(gen, "ivars"); yajl_gen_map_open(gen); st_foreach(klass->iv_tbl, each_ivar, (st_data_t)gen); yajl_gen_map_close(gen); } break; case T_ARRAY: yajl_gen_cstr(gen, "array"); struct RArray *ary = RARRAY(obj); yajl_gen_cstr(gen, "length"); yajl_gen_integer(gen, ary->len); if (FL_TEST(obj, ELTS_SHARED)) { yajl_gen_cstr(gen, "shared"); yajl_gen_value(gen, ary->aux.shared); } else if (ary->len) { yajl_gen_cstr(gen, "data"); yajl_gen_array_open(gen); int i; for(i=0; i < ary->len; i++) yajl_gen_value(gen, ary->ptr[i]); yajl_gen_array_close(gen); } break; case T_HASH: yajl_gen_cstr(gen, "hash"); struct RHash *hash = RHASH(obj); yajl_gen_cstr(gen, "length"); if (hash->tbl) yajl_gen_integer(gen, hash->tbl->num_entries); else yajl_gen_integer(gen, 0); yajl_gen_cstr(gen, "default"); yajl_gen_value(gen, hash->ifnone); if (hash->tbl && hash->tbl->num_entries) { yajl_gen_cstr(gen, "data"); //yajl_gen_map_open(gen); yajl_gen_array_open(gen); st_foreach(hash->tbl, each_hash_entry, (st_data_t)gen); yajl_gen_array_close(gen); //yajl_gen_map_close(gen); } break; default: yajl_gen_cstr(gen, "unknown"); } yajl_gen_cstr(gen, "code"); yajl_gen_integer(gen, BUILTIN_TYPE(obj)); yajl_gen_map_close(gen); }