summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2021-06-10 16:03:11 -0700
committerAaron Patterson <tenderlove@ruby-lang.org>2021-06-10 16:31:29 -0700
commitd74e5d5b4fba41a9120b3ed2762cf765478605ad (patch)
tree36793d61ee50b822f6e53678f75e75361fc569d1
parent929cc615a749f467809a865a3d40adcc0b58c667 (diff)
Crash more nicely when the VM isn't fully set up
If we crash but the VM isn't fully alive, we can get an infinite loop.
-rw-r--r--vm_dump.c62
1 files changed, 32 insertions, 30 deletions
diff --git a/vm_dump.c b/vm_dump.c
index ea94ee1985..bc23f7ad12 100644
--- a/vm_dump.c
+++ b/vm_dump.c
@@ -1062,36 +1062,38 @@ rb_vm_bugreport(const void *ctx)
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_AREF(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 if (RB_TYPE_P(name, T_CLASS) || RB_TYPE_P(name, T_MODULE)) {
- const char *const type = RB_TYPE_P(name, T_CLASS) ?
- "class" : "module";
- name = rb_search_class_path(rb_class_real(name));
- if (!RB_TYPE_P(name, T_STRING)) {
- fprintf(stderr, " %4d %s:<unnamed>\n", i, type);
- continue;
- }
- fprintf(stderr, " %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(stderr, " %4d #<%p:%p>\n", i,
- (void *)CLASS_OF(name), (void *)name);
- continue;
- }
- fprintf(stderr, " %4d #<%.*s:%p>\n", i,
- LIMITED_NAME_LENGTH(klass), RSTRING_PTR(klass),
- (void *)name);
- }
- }
+ if (vm->loaded_features) {
+ fprintf(stderr, "* 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(stderr, " %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)) {
+ const char *const type = RB_TYPE_P(name, T_CLASS) ?
+ "class" : "module";
+ name = rb_search_class_path(rb_class_real(name));
+ if (!RB_TYPE_P(name, T_STRING)) {
+ fprintf(stderr, " %4d %s:<unnamed>\n", i, type);
+ continue;
+ }
+ fprintf(stderr, " %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(stderr, " %4d #<%p:%p>\n", i,
+ (void *)CLASS_OF(name), (void *)name);
+ continue;
+ }
+ fprintf(stderr, " %4d #<%.*s:%p>\n", i,
+ LIMITED_NAME_LENGTH(klass), RSTRING_PTR(klass),
+ (void *)name);
+ }
+ }
+ }
fprintf(stderr, "\n");
}