summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorKoichi Sasada <[email protected]>2025-06-06 06:46:14 +0900
committerKoichi Sasada <[email protected]>2025-06-06 13:44:15 +0900
commit1baa396e21c272cc9cc1fea4e5d372ae1979fb9f (patch)
tree5cddbbad7aa39a47a2ad17e12b06f9dc5a7e77ec /gc.c
parentead14b19aa5acbdfb2f1ccc53cc7b8b34517b6e9 (diff)
fix `rp(obj)` for any object
Now `rp(obj)` doesn't work if the `obj` is out-of-heap because of `asan_unpoisoning_object()`, so this patch solves it. Also add pointer information and type information to show.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/13534
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/gc.c b/gc.c
index 7b7e31e9ca..7dee915fab 100644
--- a/gc.c
+++ b/gc.c
@@ -4770,6 +4770,7 @@ rb_raw_obj_info_common(char *const buff, const size_t buff_size, const VALUE obj
// const int age = RVALUE_AGE_GET(obj);
if (rb_gc_impl_pointer_to_heap_p(rb_gc_get_objspace(), (void *)obj)) {
+ APPEND_F("%p %s/", (void *)obj, obj_type_name(obj));
// TODO: fixme
// APPEND_F("%p [%d%s%s%s%s%s%s] %s ",
// (void *)obj, age,
@@ -4797,7 +4798,7 @@ rb_raw_obj_info_common(char *const buff, const size_t buff_size, const VALUE obj
else if (RTEST(RBASIC(obj)->klass)) {
VALUE class_path = rb_class_path_cached(RBASIC(obj)->klass);
if (!NIL_P(class_path)) {
- APPEND_F("(%s)", RSTRING_PTR(class_path));
+ APPEND_F("%s ", RSTRING_PTR(class_path));
}
}
}
@@ -5032,15 +5033,35 @@ rb_asan_poisoned_object_p(VALUE obj)
return __asan_region_is_poisoned(ptr, rb_gc_obj_slot_size(obj));
}
+static void
+raw_obj_info(char *const buff, const size_t buff_size, VALUE obj)
+{
+ size_t pos = rb_raw_obj_info_common(buff, buff_size, obj);
+ pos = rb_raw_obj_info_buitin_type(buff, buff_size, obj, pos);
+ if (pos >= buff_size) {} // truncated
+}
+
const char *
rb_raw_obj_info(char *const buff, const size_t buff_size, VALUE obj)
{
- asan_unpoisoning_object(obj) {
- size_t pos = rb_raw_obj_info_common(buff, buff_size, obj);
- pos = rb_raw_obj_info_buitin_type(buff, buff_size, obj, pos);
- if (pos >= buff_size) {} // truncated
- }
+ void *objspace = rb_gc_get_objspace();
+ if (SPECIAL_CONST_P(obj)) {
+ raw_obj_info(buff, buff_size, obj);
+ }
+ else if (!rb_gc_impl_pointer_to_heap_p(objspace, (const void *)obj)) {
+ snprintf(buff, buff_size, "out-of-heap:%p", (void *)obj);
+ }
+#if 0 // maybe no need to check it?
+ else if (0 && rb_gc_impl_garbage_object_p(objspace, obj)) {
+ snprintf(buff, buff_size, "garbage:%p", (void *)obj);
+ }
+#endif
+ else {
+ asan_unpoisoning_object(obj) {
+ raw_obj_info(buff, buff_size, obj);
+ }
+ }
return buff;
}