summaryrefslogtreecommitdiff
path: root/vm_dump.c
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 /vm_dump.c
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.
Diffstat (limited to 'vm_dump.c')
-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");
}