Dump backtraces to an arbitrary stream when using libprocstat
This commit is contained in:
parent
d2cc4437a1
commit
5eef125afe
@ -6,7 +6,7 @@
|
|||||||
# define KVME_TYPE_MGTDEVICE 8
|
# define KVME_TYPE_MGTDEVICE 8
|
||||||
# endif
|
# endif
|
||||||
void
|
void
|
||||||
procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp)
|
procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp, FILE *errout)
|
||||||
{
|
{
|
||||||
struct kinfo_vmentry *freep, *kve;
|
struct kinfo_vmentry *freep, *kve;
|
||||||
int ptrwidth;
|
int ptrwidth;
|
||||||
@ -17,7 +17,7 @@ procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp)
|
|||||||
#else
|
#else
|
||||||
ptrwidth = 2*sizeof(void *) + 2;
|
ptrwidth = 2*sizeof(void *) + 2;
|
||||||
#endif
|
#endif
|
||||||
fprintf(stderr, "%*s %*s %3s %4s %4s %3s %3s %4s %-2s %-s\n",
|
fprintf(errout, "%*s %*s %3s %4s %4s %3s %3s %4s %-2s %-s\n",
|
||||||
ptrwidth, "START", ptrwidth, "END", "PRT", "RES",
|
ptrwidth, "START", ptrwidth, "END", "PRT", "RES",
|
||||||
"P""RES", "REF", "SHD", "FL", "TP", "PATH");
|
"P""RES", "REF", "SHD", "FL", "TP", "PATH");
|
||||||
|
|
||||||
@ -30,20 +30,20 @@ procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp)
|
|||||||
return;
|
return;
|
||||||
for (i = 0; i < cnt; i++) {
|
for (i = 0; i < cnt; i++) {
|
||||||
kve = &freep[i];
|
kve = &freep[i];
|
||||||
fprintf(stderr, "%#*jx ", ptrwidth, (uintmax_t)kve->kve_start);
|
fprintf(errout, "%#*jx ", ptrwidth, (uintmax_t)kve->kve_start);
|
||||||
fprintf(stderr, "%#*jx ", ptrwidth, (uintmax_t)kve->kve_end);
|
fprintf(errout, "%#*jx ", ptrwidth, (uintmax_t)kve->kve_end);
|
||||||
fprintf(stderr, "%s", kve->kve_protection & KVME_PROT_READ ? "r" : "-");
|
fprintf(errout, "%s", kve->kve_protection & KVME_PROT_READ ? "r" : "-");
|
||||||
fprintf(stderr, "%s", kve->kve_protection & KVME_PROT_WRITE ? "w" : "-");
|
fprintf(errout, "%s", kve->kve_protection & KVME_PROT_WRITE ? "w" : "-");
|
||||||
fprintf(stderr, "%s ", kve->kve_protection & KVME_PROT_EXEC ? "x" : "-");
|
fprintf(errout, "%s ", kve->kve_protection & KVME_PROT_EXEC ? "x" : "-");
|
||||||
fprintf(stderr, "%4d ", kve->kve_resident);
|
fprintf(errout, "%4d ", kve->kve_resident);
|
||||||
fprintf(stderr, "%4d ", kve->kve_private_resident);
|
fprintf(errout, "%4d ", kve->kve_private_resident);
|
||||||
fprintf(stderr, "%3d ", kve->kve_ref_count);
|
fprintf(errout, "%3d ", kve->kve_ref_count);
|
||||||
fprintf(stderr, "%3d ", kve->kve_shadow_count);
|
fprintf(errout, "%3d ", kve->kve_shadow_count);
|
||||||
fprintf(stderr, "%-1s", kve->kve_flags & KVME_FLAG_COW ? "C" : "-");
|
fprintf(errout, "%-1s", kve->kve_flags & KVME_FLAG_COW ? "C" : "-");
|
||||||
fprintf(stderr, "%-1s", kve->kve_flags & KVME_FLAG_NEEDS_COPY ? "N" :
|
fprintf(errout, "%-1s", kve->kve_flags & KVME_FLAG_NEEDS_COPY ? "N" :
|
||||||
"-");
|
"-");
|
||||||
fprintf(stderr, "%-1s", kve->kve_flags & KVME_FLAG_SUPER ? "S" : "-");
|
fprintf(errout, "%-1s", kve->kve_flags & KVME_FLAG_SUPER ? "S" : "-");
|
||||||
fprintf(stderr, "%-1s ", kve->kve_flags & KVME_FLAG_GROWS_UP ? "U" :
|
fprintf(errout, "%-1s ", kve->kve_flags & KVME_FLAG_GROWS_UP ? "U" :
|
||||||
kve->kve_flags & KVME_FLAG_GROWS_DOWN ? "D" : "-");
|
kve->kve_flags & KVME_FLAG_GROWS_DOWN ? "D" : "-");
|
||||||
switch (kve->kve_type) {
|
switch (kve->kve_type) {
|
||||||
case KVME_TYPE_NONE:
|
case KVME_TYPE_NONE:
|
||||||
@ -78,8 +78,8 @@ procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp)
|
|||||||
str = "??";
|
str = "??";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "%-2s ", str);
|
fprintf(errout, "%-2s ", str);
|
||||||
fprintf(stderr, "%-s\n", kve->kve_path);
|
fprintf(errout, "%-s\n", kve->kve_path);
|
||||||
}
|
}
|
||||||
free(freep);
|
free(freep);
|
||||||
}
|
}
|
||||||
|
@ -1121,7 +1121,7 @@ rb_vm_bugreport(const void *ctx, FILE *errout)
|
|||||||
if (vm && ec) {
|
if (vm && ec) {
|
||||||
rb_vmdebug_stack_dump_raw(ec, ec->cfp, errout);
|
rb_vmdebug_stack_dump_raw(ec, ec->cfp, errout);
|
||||||
rb_backtrace_print_as_bugreport(errout);
|
rb_backtrace_print_as_bugreport(errout);
|
||||||
fputs("\n", errout);
|
kputs("\n");
|
||||||
// If we get here, hopefully things are intact enough that
|
// If we get here, hopefully things are intact enough that
|
||||||
// we can read these two numbers. It is an estimate because
|
// we can read these two numbers. It is an estimate because
|
||||||
// we are reading without synchronization.
|
// we are reading without synchronization.
|
||||||
@ -1129,7 +1129,7 @@ rb_vm_bugreport(const void *ctx, FILE *errout)
|
|||||||
"---------------------------------------------------\n");
|
"---------------------------------------------------\n");
|
||||||
kprintf("Total ractor count: %u\n", vm->ractor.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);
|
kprintf("Ruby thread count for this ractor: %u\n", rb_ec_ractor_ptr(ec)->threads.cnt);
|
||||||
fputs("\n", errout);
|
kputs("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_dump_machine_register(errout, ctx);
|
rb_dump_machine_register(errout, ctx);
|
||||||
@ -1230,7 +1230,7 @@ rb_vm_bugreport(const void *ctx, FILE *errout)
|
|||||||
else {
|
else {
|
||||||
struct procstat *prstat = procstat_open_sysctl();
|
struct procstat *prstat = procstat_open_sysctl();
|
||||||
kprintf("* Process memory map:\n\n");
|
kprintf("* Process memory map:\n\n");
|
||||||
procstat_vm(prstat, &kp);
|
procstat_vm(prstat, &kp, errout);
|
||||||
procstat_close(prstat);
|
procstat_close(prstat);
|
||||||
kprintf("\n");
|
kprintf("\n");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user