void rb_print_backtrace(void) { #if HAVE_BACKTRACE #define MAX_NATIVE_TRACE 1024 static void *trace[MAX_NATIVE_TRACE]; int n = (int)backtrace(trace, MAX_NATIVE_TRACE); #if defined(USE_ELF) && defined(HAVE_DLADDR) && !defined(__sparc) rb_dump_backtrace_with_lines(n, trace); #else char **syms = backtrace_symbols(trace, n); if (syms) { int i; for (i=0; i<n; i++) { fprintf(stderr, "%s\n", syms[i]); } free(syms); } #endif #elif defined(_WIN32) DWORD tid = GetCurrentThreadId(); HANDLE th = (HANDLE)_beginthread(dump_thread, 0, &tid); if (th != (HANDLE)-1) WaitForSingleObject(th, INFINITE); #endif }
void rb_vm_bugreport(void) { #ifdef __linux__ # define PROC_MAPS_NAME "/proc/self/maps" #endif #ifdef PROC_MAPS_NAME enum {other_runtime_info = 1}; #else enum {other_runtime_info = 0}; #endif const rb_vm_t *const vm = GET_VM(); if (vm) { SDR(); rb_backtrace_print_as_bugreport(); fputs("\n", stderr); } #if HAVE_BACKTRACE || defined(_WIN32) fprintf(stderr, "-- C level backtrace information " "-------------------------------------------\n"); { #if defined __APPLE__ fprintf(stderr, "\n"); fprintf(stderr, " See Crash Report log file under the one of following:\n" " * ~/Library/Logs/CrashReporter\n" " * /Library/Logs/CrashReporter\n" " * ~/Library/Logs/DiagnosticReports\n" " * /Library/Logs/DiagnosticReports\n" " the more detail of.\n"); #elif HAVE_BACKTRACE #define MAX_NATIVE_TRACE 1024 static void *trace[MAX_NATIVE_TRACE]; int n = backtrace(trace, MAX_NATIVE_TRACE); char **syms = backtrace_symbols(trace, n); if (syms) { #ifdef USE_ELF rb_dump_backtrace_with_lines(n, trace, syms); #else int i; for (i=0; i<n; i++) { fprintf(stderr, "%s\n", syms[i]); } #endif free(syms); } #elif defined(_WIN32) DWORD tid = GetCurrentThreadId(); HANDLE th = (HANDLE)_beginthread(dump_thread, 0, &tid); if (th != (HANDLE)-1) WaitForSingleObject(th, INFINITE); #endif } fprintf(stderr, "\n"); #endif /* HAVE_BACKTRACE */ if (other_runtime_info || vm) { fprintf(stderr, "-- Other runtime information " "-----------------------------------------------\n\n"); } if (vm) { int i; VALUE name; long len; const int max_name_length = 1024; # define LIMITED_NAME_LENGTH(s) \ (((len = RSTRING_LEN(s)) > max_name_length) ? max_name_length : (int)len) name = vm->progname; fprintf(stderr, "* Loaded script: %.*s\n", LIMITED_NAME_LENGTH(name), RSTRING_PTR(name)); fprintf(stderr, "\n"); fprintf(stderr, "* Loaded features:\n\n"); for (i=0; i<RARRAY_LEN(vm->loaded_features); i++) { name = RARRAY_PTR(vm->loaded_features)[i]; if (RB_TYPE_P(name, T_STRING)) { fprintf(stderr, " %4d %.*s\n", i, LIMITED_NAME_LENGTH(name), RSTRING_PTR(name)); } else { fprintf(stderr, " %4d #<%s:%p>\n", i, rb_class2name(CLASS_OF(name)), (void *)name); } } fprintf(stderr, "\n"); } { #ifdef PROC_MAPS_NAME { FILE *fp = fopen(PROC_MAPS_NAME, "r"); if (fp) { fprintf(stderr, "* Process memory map:\n\n"); while (!feof(fp)) { char buff[0x100]; size_t rn = fread(buff, 1, 0x100, fp); if (fwrite(buff, 1, rn, stderr) != rn) break; } fclose(fp); fprintf(stderr, "\n\n"); } } #endif /* __linux__ */ } }
void rb_vm_bugreport(void) { rb_vm_t *vm = GET_VM(); if (vm) { int i = 0; SDR(); if (rb_backtrace_each(bugreport_backtrace, &i)) { fputs("\n", stderr); } } #if HAVE_BACKTRACE || defined(_WIN32) fprintf(stderr, "-- C level backtrace information " "-------------------------------------------\n"); { #if defined __MACH__ && defined __APPLE__ fprintf(stderr, "\n"); fprintf(stderr, " See Crash Report log file under " "~/Library/Logs/CrashReporter or\n"); fprintf(stderr, " /Library/Logs/CrashReporter, for " "the more detail of.\n"); #elif HAVE_BACKTRACE #define MAX_NATIVE_TRACE 1024 static void *trace[MAX_NATIVE_TRACE]; int n = backtrace(trace, MAX_NATIVE_TRACE); char **syms = backtrace_symbols(trace, n); if (syms) { #ifdef USE_ELF rb_dump_backtrace_with_lines(n, trace, syms); #else int i; for (i=0; i<n; i++) { fprintf(stderr, "%s\n", syms[i]); } #endif free(syms); } #elif defined(_WIN32) DWORD tid = GetCurrentThreadId(); HANDLE th = (HANDLE)_beginthread(dump_thread, 0, &tid); if (th != (HANDLE)-1) WaitForSingleObject(th, INFINITE); #endif } fprintf(stderr, "\n"); #endif /* HAVE_BACKTRACE */ fprintf(stderr, "-- Other runtime information " "-----------------------------------------------\n\n"); { int i; fprintf(stderr, "* Loaded script: %s\n", StringValueCStr(vm->progname)); fprintf(stderr, "\n"); fprintf(stderr, "* Loaded features:\n\n"); for (i=0; i<RARRAY_LEN(vm->loaded_features); i++) { fprintf(stderr, " %4d %s\n", i, StringValueCStr(RARRAY_PTR(vm->loaded_features)[i])); } fprintf(stderr, "\n"); #if __linux__ { FILE *fp = fopen("/proc/self/maps", "r"); if (fp) { fprintf(stderr, "* Process memory map:\n\n"); while (!feof(fp)) { char buff[0x100]; size_t rn = fread(buff, 1, 0x100, fp); fwrite(buff, 1, rn, stderr); } fclose(fp); fprintf(stderr, "\n\n"); } } #endif /* __linux__ */ } }