diff options
author | Nobuyoshi Nakada <[email protected]> | 2023-08-04 15:30:36 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <[email protected]> | 2023-09-25 22:57:28 +0900 |
commit | 85984a53e87dfbccb52aba952367fddea4a77870 () | |
tree | d3e1f12d3dc56dd435de5ed4963bf31a959152ea /vm_dump.c | |
parent | ac244938e8b97c8bd42d1dc8ed820091e6ef5537 (diff) |
Abort dumping when output failed
-rw-r--r-- | vm_dump.c | 261 |
1 files changed, 155 insertions, 106 deletions
@@ -46,7 +46,10 @@ const char *rb_method_type_name(rb_method_type_t type); int ruby_on_ci; -static void control_frame_dump(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, FILE *errout) { ptrdiff_t pc = -1; @@ -140,30 +143,30 @@ control_frame_dump(const rb_execution_context_t *ec, const rb_control_frame_t *c line = -1; } - fprintf(errout, "c:%04"PRIdPTRDIFF" ", ((rb_control_frame_t *)(ec->vm_stack + ec->vm_stack_size) - cfp)); if (pc == -1) { - fprintf(errout, "p:---- "); } else { - fprintf(errout, "p:%04"PRIdPTRDIFF" ", pc); } - fprintf(errout, "s:%04"PRIdPTRDIFF" ", cfp->sp - ec->vm_stack); - fprintf(errout, ep_in_heap == ' ' ? "e:%06"PRIdPTRDIFF" " : "E:%06"PRIxPTRDIFF" ", ep % 10000); - fprintf(errout, "%-6s", magic); if (line) { - fprintf(errout, " %s", posbuf); } if (VM_FRAME_FINISHED_P(cfp)) { - fprintf(errout, " [FINISH]"); } if (0) { - fprintf(errout, " \t"); - fprintf(errout, "iseq: %-24s ", iseq_name); - fprintf(errout, "self: %-24s ", selfstr); - fprintf(errout, "%-1s ", biseq_name); } - fprintf(errout, "\n"); // additional information for CI machines if (ruby_on_ci) { @@ -171,35 +174,38 @@ control_frame_dump(const rb_execution_context_t *ec, const rb_control_frame_t *c if (me) { if (IMEMO_TYPE_P(me, imemo_ment)) { - fprintf(errout, " me:\n"); - fprintf(errout, " called_id: %s, type: %s\n", rb_id2name(me->called_id), rb_method_type_name(me->def->type)); - fprintf(errout, " owner class: %s\n", rb_raw_obj_info(buff, 0x100, me->owner)); if (me->owner != me->defined_class) { - fprintf(errout, " defined_class: %s\n", rb_raw_obj_info(buff, 0x100, me->defined_class)); } } else { - fprintf(errout, " me is corrupted (%s)\n", rb_raw_obj_info(buff, 0x100, (VALUE)me)); } } - fprintf(errout, " self: %s\n", rb_raw_obj_info(buff, 0x100, cfp->self)); if (iseq) { if (ISEQ_BODY(iseq)->local_table_size > 0) { - fprintf(errout, " lvars:\n"); for (unsigned int i=0; i<ISEQ_BODY(iseq)->local_table_size; i++) { const VALUE *argv = cfp->ep - ISEQ_BODY(cfp->iseq)->local_table_size - VM_ENV_DATA_SIZE + 1; - fprintf(errout, " %s: %s\n", rb_id2name(ISEQ_BODY(iseq)->local_table[i]), rb_raw_obj_info(buff, 0x100, argv[i])); } } } } } -void rb_vmdebug_stack_dump_raw(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, FILE *errout) { #if 0 @@ -207,58 +213,66 @@ rb_vmdebug_stack_dump_raw(const rb_execution_context_t *ec, const rb_control_fra const VALUE *ep = cfp->ep; VALUE *p, *st, *t; - fprintf(errout, "-- stack frame ------------\n"); for (p = st = ec->vm_stack; p < sp; p++) { - fprintf(errout, "%04ld (%p): %08"PRIxVALUE, (long)(p - st), p, *p); t = (VALUE *)*p; if (ec->vm_stack <= t && t < sp) { - fprintf(errout, " (= %ld)", (long)((VALUE *)GC_GUARDED_PTR_REF((VALUE)t) - ec->vm_stack)); } if (p == ep) - fprintf(errout, " <- ep"); - fprintf(errout, "\n"); } #endif - fprintf(errout, "-- Control frame information " "-----------------------------------------------\n"); while ((void *)cfp < (void *)(ec->vm_stack + ec->vm_stack_size)) { control_frame_dump(ec, cfp, errout); cfp++; } - fprintf(errout, "\n"); } -void rb_vmdebug_stack_dump_raw_current(void) { const rb_execution_context_t *ec = GET_EC(); - rb_vmdebug_stack_dump_raw(ec, ec->cfp, stderr); } -void rb_vmdebug_env_dump_raw(const rb_env_t *env, const VALUE *ep, FILE *errout) { unsigned int i; - fprintf(errout, "-- env --------------------\n"); while (env) { - fprintf(errout, "--\n"); for (i = 0; i < env->env_size; i++) { - fprintf(errout, "%04d: %08"PRIxVALUE" (%p)", i, env->env[i], (void *)&env->env[i]); - if (&env->env[i] == ep) fprintf(errout, " <- ep"); - fprintf(errout, "\n"); } env = rb_vm_env_prev_env(env); } - fprintf(errout, "---------------------------\n"); } -void rb_vmdebug_proc_dump_raw(rb_proc_t *proc, FILE *errout) { const rb_env_t *env; @@ -266,17 +280,21 @@ rb_vmdebug_proc_dump_raw(rb_proc_t *proc, FILE *errout) VALUE val = rb_inspect(vm_block_self(&proc->block)); selfstr = StringValueCStr(val); - fprintf(errout, "-- proc -------------------\n"); - fprintf(errout, "self: %s\n", selfstr); env = VM_ENV_ENVVAL_PTR(vm_block_ep(&proc->block)); rb_vmdebug_env_dump_raw(env, vm_block_ep(&proc->block), errout); } -void rb_vmdebug_stack_dump_th(VALUE thval, FILE *errout) { rb_thread_t *target_th = rb_thread_ptr(thval); - rb_vmdebug_stack_dump_raw(target_th->ec, target_th->ec->cfp, errout); } #if VMDEBUG > 2 @@ -325,12 +343,12 @@ vm_stack_dump_each(const rb_execution_context_t *ec, const rb_control_frame_t *c for (i = 0; i < argc; i++) { rstr = rb_inspect(*ptr); - fprintf(errout, " arg %2d: %8s (%p)\n", i, StringValueCStr(rstr), (void *)ptr++); } for (; i < local_table_size - 1; i++) { rstr = rb_inspect(*ptr); - fprintf(errout, " local %2d: %8s (%p)\n", i, StringValueCStr(rstr), (void *)ptr++); } @@ -347,7 +365,7 @@ vm_stack_dump_each(const rb_execution_context_t *ec, const rb_control_frame_t *c rstr = rb_inspect(*ptr); break; } - fprintf(errout, " stack %2d: %8s (%"PRIdPTRDIFF")\n", i, StringValueCStr(rstr), (ptr - ec->vm_stack)); } } @@ -365,7 +383,7 @@ vm_stack_dump_each(const rb_execution_context_t *ec, const rb_control_frame_t *c } #endif -void rb_vmdebug_debug_print_register(const rb_execution_context_t *ec, FILE *errout) { rb_control_frame_t *cfp = ec->cfp; @@ -382,17 +400,21 @@ rb_vmdebug_debug_print_register(const rb_execution_context_t *ec, FILE *errout) } cfpi = ((rb_control_frame_t *)(ec->vm_stack + ec->vm_stack_size)) - cfp; - fprintf(errout, " [PC] %04"PRIdPTRDIFF", [SP] %04"PRIdPTRDIFF", [EP] %04"PRIdPTRDIFF", [CFP] %04"PRIdPTRDIFF"\n", pc, (cfp->sp - ec->vm_stack), ep, cfpi); } -void rb_vmdebug_thread_dump_regs(VALUE thval, FILE *errout) { - rb_vmdebug_debug_print_register(rb_thread_ptr(thval)->ec, errout); } -void rb_vmdebug_debug_print_pre(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, const VALUE *_pc, FILE *errout) { const rb_iseq_t *iseq = cfp->iseq; @@ -402,10 +424,10 @@ rb_vmdebug_debug_print_pre(const rb_execution_context_t *ec, const rb_control_fr int i; for (i=0; i<(int)VM_CFP_CNT(ec, cfp); i++) { - printf(" "); } - printf("| "); - if(0)printf("[%03ld] ", (long)(cfp->sp - ec->vm_stack)); /* printf("%3"PRIdPTRDIFF" ", VM_CFP_CNT(ec, cfp)); */ if (pc >= 0) { @@ -416,20 +438,24 @@ rb_vmdebug_debug_print_pre(const rb_execution_context_t *ec, const rb_control_fr } #if VMDEBUG > 3 - fprintf(errout, " (1)"); rb_vmdebug_debug_print_register(errout, ec); #endif } -void rb_vmdebug_debug_print_post(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, FILE *errout) { #if VMDEBUG > 9 - rb_vmdebug_stack_dump_raw(ec, cfp, errout); #endif #if VMDEBUG > 3 - fprintf(errout, " (2)"); rb_vmdebug_debug_print_register(errout, ec); #endif /* stack_dump_raw(ec, cfp); */ @@ -438,9 +464,15 @@ rb_vmdebug_debug_print_post(const rb_execution_context_t *ec, const rb_control_f /* stack_dump_thobj(ec); */ vm_stack_dump_each(ec, ec->cfp, errout); - printf ("--------------------------------------------------------------\n"); #endif } VALUE @@ -449,10 +481,11 @@ rb_vmdebug_thread_dump_state(FILE *errout, VALUE self) rb_thread_t *th = rb_thread_ptr(self); rb_control_frame_t *cfp = th->ec->cfp; - fprintf(errout, "Thread state dump:\n"); - fprintf(errout, "pc : %p, sp : %p\n", (void *)cfp->pc, (void *)cfp->sp); - fprintf(errout, "cfp: %p, ep : %p\n", (void *)cfp, (void *)cfp->ep); return Qnil; } @@ -746,19 +779,20 @@ dump_thread(void *arg) info->MaxNameLen = MAX_SYM_NAME; if (pSymFromAddr(ph, addr, &displacement, info)) { if (GetModuleFileName((HANDLE)(uintptr_t)pSymGetModuleBase64(ph, addr), libpath, sizeof(libpath))) - fprintf(errout, "%s", libpath); - fprintf(errout, "(%s+0x%"PRI_64_PREFIX"x)", info->Name, displacement); } - fprintf(errout, " [0x%p]", (void *)(VALUE)addr); memset(&line, 0, sizeof(line)); line.SizeOfStruct = sizeof(line); if (pSymGetLineFromAddr64(ph, addr, &tmp, &line)) - fprintf(errout, " %s:%lu", line.FileName, line.LineNumber); - fprintf(errout, "\n"); } } ResumeThread(th); } CloseHandle(th); @@ -783,7 +817,7 @@ rb_print_backtrace(FILE *errout) if (syms) { int i; for (i=0; i<n; i++) { - fprintf(errout, "%s\n", syms[i]); } free(syms); } @@ -827,21 +861,24 @@ print_machine_register(FILE *errout, size_t reg, const char *reg_name, int col_c ret = snprintf(buf, sizeof(buf), " %3.3s: 0x%.*" PRIxSIZE, reg_name, size_width, reg); if (col_count + ret > max_col) { - fputs("\n", errout); col_count = 0; } col_count += ret; - fputs(buf, errout); return col_count; } -static void rb_dump_machine_register(FILE *errout, const ucontext_t *ctx) { int col_count = 0; - if (!ctx) return; - fprintf(errout, "-- Machine register context " "------------------------------------------------\n"); # if defined __linux__ @@ -1034,13 +1071,17 @@ rb_dump_machine_register(FILE *errout, const ucontext_t *ctx) # endif } # endif - fprintf(errout, "\n\n"); } #else # define rb_dump_machine_register(errout, ctx) ((void)0) #endif /* dump_machine_register */ -void rb_vm_bugreport(const void *ctx, FILE *errout) { const char *cmd = getenv("RUBY_ON_BUG"); @@ -1058,8 +1099,8 @@ rb_vm_bugreport(const void *ctx, FILE *errout) { static bool crashing = false; if (crashing) { - fprintf(errout, "Crashed while printing bug report\n"); - return; } crashing = true; } @@ -1082,26 +1123,26 @@ rb_vm_bugreport(const void *ctx, FILE *errout) // If we get here, hopefully things are intact enough that // we can read these two numbers. It is an estimate because // we are reading without synchronization. - fprintf(errout, "-- Threading information " "---------------------------------------------------\n"); - fprintf(errout, "Total ractor count: %u\n", vm->ractor.cnt); - fprintf(errout, "Ruby thread count for this ractor: %u\n", rb_ec_ractor_ptr(ec)->threads.cnt); fputs("\n", errout); } rb_dump_machine_register(errout, ctx); #if USE_BACKTRACE || defined(_WIN32) - fprintf(errout, "-- C level backtrace information " "-------------------------------------------\n"); rb_print_backtrace(errout); - fprintf(errout, "\n"); #endif /* USE_BACKTRACE */ if (other_runtime_info || vm) { - fprintf(errout, "-- Other runtime information " "-----------------------------------------------\n\n"); } if (vm && !rb_during_gc()) { @@ -1114,16 +1155,16 @@ rb_vm_bugreport(const void *ctx, FILE *errout) name = vm->progname; if (name) { - fprintf(errout, "* Loaded script: %.*s\n", LIMITED_NAME_LENGTH(name), RSTRING_PTR(name)); - fprintf(errout, "\n"); } if (vm->loaded_features) { - fprintf(errout, "* Loaded features:\n\n"); for (i=0; i<RARRAY_LEN(vm->loaded_features); i++) { name = RARRAY_AREF(vm->loaded_features, i); if (RB_TYPE_P(name, T_STRING)) { - fprintf(errout, " %4d %.*s\n", i, LIMITED_NAME_LENGTH(name), RSTRING_PTR(name)); } else if (RB_TYPE_P(name, T_CLASS) || RB_TYPE_P(name, T_MODULE)) { @@ -1131,26 +1172,26 @@ rb_vm_bugreport(const void *ctx, FILE *errout) "class" : "module"; name = rb_search_class_path(rb_class_real(name)); if (!RB_TYPE_P(name, T_STRING)) { - fprintf(errout, " %4d %s:<unnamed>\n", i, type); continue; } - fprintf(errout, " %4d %s:%.*s\n", i, type, LIMITED_NAME_LENGTH(name), RSTRING_PTR(name)); } else { VALUE klass = rb_search_class_path(rb_obj_class(name)); if (!RB_TYPE_P(klass, T_STRING)) { - fprintf(errout, " %4d #<%p:%p>\n", i, (void *)CLASS_OF(name), (void *)name); continue; } - fprintf(errout, " %4d #<%.*s:%p>\n", i, LIMITED_NAME_LENGTH(klass), RSTRING_PTR(klass), (void *)name); } } } - fprintf(errout, "\n"); } { @@ -1158,7 +1199,7 @@ rb_vm_bugreport(const void *ctx, FILE *errout) { FILE *fp = fopen(PROC_MAPS_NAME, "r"); if (fp) { - fprintf(errout, "* Process memory map:\n\n"); while (!feof(fp)) { char buff[0x100]; @@ -1168,7 +1209,7 @@ rb_vm_bugreport(const void *ctx, FILE *errout) } fclose(fp); - fprintf(errout, "\n\n"); } } #endif /* __linux__ */ @@ -1182,14 +1223,14 @@ rb_vm_bugreport(const void *ctx, FILE *errout) mib[2] = KERN_PROC_PID; mib[3] = getpid(); if (sysctl(mib, MIB_KERN_PROC_PID_LEN, &kp, &len, NULL, 0) == -1) { - fprintf(errout, "sysctl: %s\n", strerror(errno)); } else { struct procstat *prstat = procstat_open_sysctl(); - fprintf(errout, "* Process memory map:\n\n"); procstat_vm(prstat, &kp); procstat_close(prstat); - fprintf(errout, "\n"); } #endif /* __FreeBSD__ */ #ifdef __APPLE__ @@ -1199,7 +1240,7 @@ rb_vm_bugreport(const void *ctx, FILE *errout) mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT; natural_t depth = 0; - fprintf(errout, "* Process memory map:\n\n"); while (1) { if (vm_region_recurse(mach_task_self(), &addr, &size, &depth, (vm_region_recurse_info_t)&map, &count) != KERN_SUCCESS) { @@ -1211,17 +1252,17 @@ rb_vm_bugreport(const void *ctx, FILE *errout) depth++; } else { - fprintf(errout, "%lx-%lx %s%s%s", addr, (addr+size), ((map.protection & VM_PROT_READ) != 0 ? "r" : "-"), ((map.protection & VM_PROT_WRITE) != 0 ? "w" : "-"), ((map.protection & VM_PROT_EXECUTE) != 0 ? "x" : "-")); #ifdef HAVE_LIBPROC_H char buff[PATH_MAX]; if (proc_regionfilename(getpid(), addr, buff, sizeof(buff)) > 0) { - fprintf(errout, " %s", buff); } #endif - fprintf(errout, "\n"); } addr += size; @@ -1229,9 +1270,13 @@ rb_vm_bugreport(const void *ctx, FILE *errout) } #endif } } -void rb_vmdebug_stack_dump_all_threads(void) { rb_thread_t *th = NULL; @@ -1241,10 +1286,14 @@ rb_vmdebug_stack_dump_all_threads(void) // TODO: now it only shows current ractor ccan_list_for_each(&r->threads.set, th, lt_node) { #ifdef NON_SCALAR_THREAD_ID - fprintf(errout, "th: %p, native_id: N/A\n", th); #else - fprintf(errout, "th: %p, native_id: %p\n", (void *)th, (void *)(uintptr_t)th->nt->thread_id); #endif - rb_vmdebug_stack_dump_raw(th->ec, th->ec->cfp, errout); } } |