Abort dumping when output failed
This commit is contained in:
parent
ac244938e8
commit
85984a53e8
@ -1678,13 +1678,13 @@ VALUE rb_proc_alloc(VALUE klass);
|
||||
VALUE rb_proc_dup(VALUE self);
|
||||
|
||||
/* for debug */
|
||||
extern void rb_vmdebug_stack_dump_raw(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, FILE *);
|
||||
extern void rb_vmdebug_debug_print_pre(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, const VALUE *_pc, FILE *);
|
||||
extern void rb_vmdebug_debug_print_post(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, FILE *);
|
||||
extern bool rb_vmdebug_stack_dump_raw(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, FILE *);
|
||||
extern bool rb_vmdebug_debug_print_pre(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, const VALUE *_pc, FILE *);
|
||||
extern bool rb_vmdebug_debug_print_post(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, FILE *);
|
||||
|
||||
#define SDR() rb_vmdebug_stack_dump_raw(GET_EC(), GET_EC()->cfp, stderr)
|
||||
#define SDR2(cfp) rb_vmdebug_stack_dump_raw(GET_EC(), (cfp), stderr)
|
||||
void rb_vm_bugreport(const void *, FILE *);
|
||||
bool rb_vm_bugreport(const void *, FILE *);
|
||||
typedef void (*ruby_sighandler_t)(int);
|
||||
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 4, 5)
|
||||
NORETURN(void rb_bug_for_fatal_signal(ruby_sighandler_t default_sighandler, int sig, const void *, const char *fmt, ...));
|
||||
|
261
vm_dump.c
261
vm_dump.c
@ -46,7 +46,10 @@
|
||||
const char *rb_method_type_name(rb_method_type_t type);
|
||||
int ruby_on_ci;
|
||||
|
||||
static void
|
||||
#define kprintf(...) if (fprintf(errout, __VA_ARGS__) < 0) goto error
|
||||
#define kputs(s) if (fputs(s, errout) < 0) goto error
|
||||
|
||||
static bool
|
||||
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" ",
|
||||
kprintf("c:%04"PRIdPTRDIFF" ",
|
||||
((rb_control_frame_t *)(ec->vm_stack + ec->vm_stack_size) - cfp));
|
||||
if (pc == -1) {
|
||||
fprintf(errout, "p:---- ");
|
||||
kprintf("p:---- ");
|
||||
}
|
||||
else {
|
||||
fprintf(errout, "p:%04"PRIdPTRDIFF" ", pc);
|
||||
kprintf("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);
|
||||
kprintf("s:%04"PRIdPTRDIFF" ", cfp->sp - ec->vm_stack);
|
||||
kprintf(ep_in_heap == ' ' ? "e:%06"PRIdPTRDIFF" " : "E:%06"PRIxPTRDIFF" ", ep % 10000);
|
||||
kprintf("%-6s", magic);
|
||||
if (line) {
|
||||
fprintf(errout, " %s", posbuf);
|
||||
kprintf(" %s", posbuf);
|
||||
}
|
||||
if (VM_FRAME_FINISHED_P(cfp)) {
|
||||
fprintf(errout, " [FINISH]");
|
||||
kprintf(" [FINISH]");
|
||||
}
|
||||
if (0) {
|
||||
fprintf(errout, " \t");
|
||||
fprintf(errout, "iseq: %-24s ", iseq_name);
|
||||
fprintf(errout, "self: %-24s ", selfstr);
|
||||
fprintf(errout, "%-1s ", biseq_name);
|
||||
kprintf(" \t");
|
||||
kprintf("iseq: %-24s ", iseq_name);
|
||||
kprintf("self: %-24s ", selfstr);
|
||||
kprintf("%-1s ", biseq_name);
|
||||
}
|
||||
fprintf(errout, "\n");
|
||||
kprintf("\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));
|
||||
kprintf(" me:\n");
|
||||
kprintf(" called_id: %s, type: %s\n", rb_id2name(me->called_id), rb_method_type_name(me->def->type));
|
||||
kprintf(" 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));
|
||||
kprintf(" 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));
|
||||
kprintf(" 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));
|
||||
kprintf(" 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");
|
||||
kprintf(" 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",
|
||||
kprintf(" %s: %s\n",
|
||||
rb_id2name(ISEQ_BODY(iseq)->local_table[i]),
|
||||
rb_raw_obj_info(buff, 0x100, argv[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
error:
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
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");
|
||||
kprintf("-- stack frame ------------\n");
|
||||
for (p = st = ec->vm_stack; p < sp; p++) {
|
||||
fprintf(errout, "%04ld (%p): %08"PRIxVALUE, (long)(p - st), p, *p);
|
||||
kprintf("%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));
|
||||
kprintf(" (= %ld)", (long)((VALUE *)GC_GUARDED_PTR_REF((VALUE)t) - ec->vm_stack));
|
||||
}
|
||||
|
||||
if (p == ep)
|
||||
fprintf(errout, " <- ep");
|
||||
kprintf(" <- ep");
|
||||
|
||||
fprintf(errout, "\n");
|
||||
kprintf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
fprintf(errout, "-- Control frame information "
|
||||
kprintf("-- 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");
|
||||
kprintf("\n");
|
||||
return true;
|
||||
|
||||
error:
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
rb_vmdebug_stack_dump_raw_current(void)
|
||||
{
|
||||
const rb_execution_context_t *ec = GET_EC();
|
||||
rb_vmdebug_stack_dump_raw(ec, ec->cfp, stderr);
|
||||
return rb_vmdebug_stack_dump_raw(ec, ec->cfp, stderr);
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
rb_vmdebug_env_dump_raw(const rb_env_t *env, const VALUE *ep, FILE *errout)
|
||||
{
|
||||
unsigned int i;
|
||||
fprintf(errout, "-- env --------------------\n");
|
||||
kprintf("-- env --------------------\n");
|
||||
|
||||
while (env) {
|
||||
fprintf(errout, "--\n");
|
||||
kprintf("--\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");
|
||||
kprintf("%04d: %08"PRIxVALUE" (%p)", i, env->env[i], (void *)&env->env[i]);
|
||||
if (&env->env[i] == ep) kprintf(" <- ep");
|
||||
kprintf("\n");
|
||||
}
|
||||
|
||||
env = rb_vm_env_prev_env(env);
|
||||
}
|
||||
fprintf(errout, "---------------------------\n");
|
||||
kprintf("---------------------------\n");
|
||||
return true;
|
||||
|
||||
error:
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
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);
|
||||
kprintf("-- proc -------------------\n");
|
||||
kprintf("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);
|
||||
return true;
|
||||
|
||||
error:
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
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);
|
||||
return 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),
|
||||
kprintf(" 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),
|
||||
kprintf(" 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),
|
||||
kprintf(" 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
|
||||
bool
|
||||
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",
|
||||
kprintf(" [PC] %04"PRIdPTRDIFF", [SP] %04"PRIdPTRDIFF", [EP] %04"PRIdPTRDIFF", [CFP] %04"PRIdPTRDIFF"\n",
|
||||
pc, (cfp->sp - ec->vm_stack), ep, cfpi);
|
||||
return true;
|
||||
|
||||
error:
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
rb_vmdebug_thread_dump_regs(VALUE thval, FILE *errout)
|
||||
{
|
||||
rb_vmdebug_debug_print_register(rb_thread_ptr(thval)->ec, errout);
|
||||
return rb_vmdebug_debug_print_register(rb_thread_ptr(thval)->ec, errout);
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
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(" ");
|
||||
kprintf(" ");
|
||||
}
|
||||
printf("| ");
|
||||
if(0)printf("[%03ld] ", (long)(cfp->sp - ec->vm_stack));
|
||||
kprintf("| ");
|
||||
if(0) kprintf("[%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)");
|
||||
kprintf(" (1)");
|
||||
rb_vmdebug_debug_print_register(errout, ec);
|
||||
#endif
|
||||
return true;
|
||||
|
||||
error:
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
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);
|
||||
if (!rb_vmdebug_stack_dump_raw(ec, cfp, errout)) goto errout;
|
||||
#endif
|
||||
|
||||
#if VMDEBUG > 3
|
||||
fprintf(errout, " (2)");
|
||||
kprintf(" (2)");
|
||||
rb_vmdebug_debug_print_register(errout, ec);
|
||||
#endif
|
||||
/* stack_dump_raw(ec, cfp); */
|
||||
@ -438,8 +464,14 @@ 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
|
||||
kprintf
|
||||
("--------------------------------------------------------------\n");
|
||||
#endif
|
||||
return true;
|
||||
|
||||
#if VMDEBUG > 2
|
||||
error:
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -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);
|
||||
kprintf("Thread state dump:\n");
|
||||
kprintf("pc : %p, sp : %p\n", (void *)cfp->pc, (void *)cfp->sp);
|
||||
kprintf("cfp: %p, ep : %p\n", (void *)cfp, (void *)cfp->ep);
|
||||
|
||||
error:
|
||||
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)",
|
||||
kprintf("%s", libpath);
|
||||
kprintf("(%s+0x%"PRI_64_PREFIX"x)",
|
||||
info->Name, displacement);
|
||||
}
|
||||
fprintf(errout, " [0x%p]", (void *)(VALUE)addr);
|
||||
kprintf(" [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");
|
||||
kprintf(" %s:%lu", line.FileName, line.LineNumber);
|
||||
kprintf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
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]);
|
||||
kprintf("%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);
|
||||
kputs("\n");
|
||||
col_count = 0;
|
||||
}
|
||||
col_count += ret;
|
||||
fputs(buf, errout);
|
||||
kputs(buf);
|
||||
return col_count;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
rb_dump_machine_register(FILE *errout, const ucontext_t *ctx)
|
||||
{
|
||||
int col_count = 0;
|
||||
if (!ctx) return;
|
||||
if (!ctx) return true;
|
||||
|
||||
fprintf(errout, "-- Machine register context "
|
||||
kprintf("-- 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");
|
||||
kprintf("\n\n");
|
||||
return true;
|
||||
|
||||
error:
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
# define rb_dump_machine_register(errout, ctx) ((void)0)
|
||||
#endif /* dump_machine_register */
|
||||
|
||||
void
|
||||
bool
|
||||
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;
|
||||
kprintf("Crashed while printing bug report\n");
|
||||
return true;
|
||||
}
|
||||
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 "
|
||||
kprintf("-- 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);
|
||||
kprintf("Total ractor count: %u\n", vm->ractor.cnt);
|
||||
kprintf("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 "
|
||||
kprintf("-- C level backtrace information "
|
||||
"-------------------------------------------\n");
|
||||
rb_print_backtrace(errout);
|
||||
|
||||
|
||||
fprintf(errout, "\n");
|
||||
kprintf("\n");
|
||||
#endif /* USE_BACKTRACE */
|
||||
|
||||
if (other_runtime_info || vm) {
|
||||
fprintf(errout, "-- Other runtime information "
|
||||
kprintf("-- 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",
|
||||
kprintf("* Loaded script: %.*s\n",
|
||||
LIMITED_NAME_LENGTH(name), RSTRING_PTR(name));
|
||||
fprintf(errout, "\n");
|
||||
kprintf("\n");
|
||||
}
|
||||
if (vm->loaded_features) {
|
||||
fprintf(errout, "* Loaded features:\n\n");
|
||||
kprintf("* 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,
|
||||
kprintf(" %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);
|
||||
kprintf(" %4d %s:<unnamed>\n", i, type);
|
||||
continue;
|
||||
}
|
||||
fprintf(errout, " %4d %s:%.*s\n", i, type,
|
||||
kprintf(" %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,
|
||||
kprintf(" %4d #<%p:%p>\n", i,
|
||||
(void *)CLASS_OF(name), (void *)name);
|
||||
continue;
|
||||
}
|
||||
fprintf(errout, " %4d #<%.*s:%p>\n", i,
|
||||
kprintf(" %4d #<%.*s:%p>\n", i,
|
||||
LIMITED_NAME_LENGTH(klass), RSTRING_PTR(klass),
|
||||
(void *)name);
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(errout, "\n");
|
||||
kprintf("\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");
|
||||
kprintf("* 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");
|
||||
kprintf("\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));
|
||||
kprintf("sysctl: %s\n", strerror(errno));
|
||||
}
|
||||
else {
|
||||
struct procstat *prstat = procstat_open_sysctl();
|
||||
fprintf(errout, "* Process memory map:\n\n");
|
||||
kprintf("* Process memory map:\n\n");
|
||||
procstat_vm(prstat, &kp);
|
||||
procstat_close(prstat);
|
||||
fprintf(errout, "\n");
|
||||
kprintf("\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");
|
||||
kprintf("* 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),
|
||||
kprintf("%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);
|
||||
kprintf(" %s", buff);
|
||||
}
|
||||
#endif
|
||||
fprintf(errout, "\n");
|
||||
kprintf("\n");
|
||||
}
|
||||
|
||||
addr += size;
|
||||
@ -1229,9 +1270,13 @@ rb_vm_bugreport(const void *ctx, FILE *errout)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
|
||||
error:
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
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);
|
||||
kprintf("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);
|
||||
kprintf("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);
|
||||
if (!rb_vmdebug_stack_dump_raw(th->ec, th->ec->cfp, errout)) goto error;
|
||||
}
|
||||
return true;
|
||||
|
||||
error:
|
||||
return false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user