29#define BUFFER_CAPACITY 4096
53 if (written < dc->buffer_len) {
67buffer_ensure_capa(
struct dump_config *dc,
unsigned long requested)
78static void buffer_append(
struct dump_config *dc,
const char *cstr,
unsigned long len)
81 buffer_ensure_capa(dc,
len);
87# define dump_append(dc, str) buffer_append(dc, (str), (long)strlen(str))
90dump_append_ld(
struct dump_config *dc,
const long number)
93 buffer_ensure_capa(dc, width);
100dump_append_lu(
struct dump_config *dc,
const unsigned long number)
103 buffer_ensure_capa(dc, width);
110dump_append_g(
struct dump_config *dc,
const double number)
115 if (required >= capa_left) {
116 buffer_ensure_capa(dc, required);
124dump_append_d(
struct dump_config *dc,
const int number)
127 buffer_ensure_capa(dc, width);
134dump_append_sizet(
struct dump_config *dc,
const size_t number)
137 buffer_ensure_capa(dc, width);
147 const int width = (
sizeof(c) *
CHAR_BIT / 4) + 5;
148 buffer_ensure_capa(dc, width);
154 buffer_ensure_capa(dc, 1);
166 char *buffer_start, *buffer_end;
168 buffer_start = buffer_end = &buffer[
sizeof(buffer)];
169 *--buffer_start =
'"';
174 *--buffer_start =
'x';
175 *--buffer_start =
'0';
176 *--buffer_start =
'"';
177 buffer_append(dc, buffer_start, buffer_end - buffer_start);
189 switch ((c = value[i])) {
218 dump_append_c(dc, c);
227 dump_append(dc,
"{\"type\":\"SYMBOL\", \"value\":");
228 dump_append_string_value(dc,
rb_sym2str(obj));
232static inline const char *
236#define CASE_TYPE(type) case T_##type: return #type
272 if (value ==
Qtrue) {
275 else if (value ==
Qfalse) {
278 else if (value ==
Qnil) {
282 dump_append_ld(dc,
FIX2LONG(value));
284 else if (FLONUM_P(value)) {
288 dump_append_symbol_value(dc, value);
296reachable_object_i(
VALUE ref,
void *data)
305 dump_append_ref(dc, ref);
309 dump_append_ref(dc, ref);
325 if (is_ascii_string(obj)) {
327 dump_append_string_value(dc, obj);
341 dump_append_special_const(dc, obj);
357 dump_append_ref(dc, obj);
382 dump_append_string_content(dc,
rb_sym2str(obj));
386 if (STR_EMBED_P(obj))
388 if (is_broken_string(obj))
392 if (STR_SHARED_P(obj))
395 dump_append_string_content(dc, obj);
406 dump_append_sizet(dc, (
size_t)
RHASH_SIZE(obj));
426 if (!
NIL_P(mod_name)) {
435 if (RTYPEDDATA_P(obj)) {
437 dump_append(dc, RTYPEDDATA_TYPE(obj)->wrap_struct_name);
450 dump_append_lu(dc, ROBJECT_NUMIV(obj));
454 fptr =
RFILE(obj)->fptr;
457 dump_append_d(dc, fptr->
fd);
481 dump_append_lu(dc, ainfo->
line);
486 dump_append_string_value(dc, m);
494 dump_append_sizet(dc, memsize);
499 for (i=0; i<n; i++) {
512heap_i(
void *vstart,
void *vend,
size_t stride,
void *data)
516 for (; v != (
VALUE)vend; v += stride) {
517 void *
ptr = asan_poisoned_object_p(v);
518 asan_unpoison_object(v,
false);
524 asan_poison_object(v);
531root_obj_i(
const char *category,
VALUE obj,
void *data)
538 dump_append(dc,
"{\"type\":\"ROOT\", \"root\":\"");
541 dump_append_ref(dc, obj);
545 dump_append_ref(dc, obj);
596 dump_output(&dc, output,
Qnil,
Qnil);
598 dump_object(obj, &dc);
600 return dump_result(&dc);
607 dump_output(&dc, output, full,
since);
618 return dump_result(&dc);
#define RUBY_ASSERT(expr)
Asserts that the given expression is truthy iff RUBY_DEBUG is truthy.
#define rb_define_module_function(klass, mid, func, arity)
Defines klass#mid and makes it a module function.
rb_encoding * rb_enc_from_index(int index)
#define RSTRING_LEN(string)
#define RSTRING_PTR(string)
size_t rb_obj_memsize_of(VALUE obj)
void rb_objspace_reachable_objects_from(VALUE obj, void(func)(VALUE, void *), void *data)
const char * rb_imemo_name(enum imemo_type type)
void rb_objspace_each_objects(each_obj_callback *callback, void *data)
void rb_objspace_reachable_objects_from_root(void(func)(const char *category, VALUE, void *), void *passing_data)
size_t rb_obj_gc_flags(VALUE obj, ID *flags, size_t max)
VALUE rb_define_module(const char *name)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_obj_frozen_p(VALUE)
#define ENCODING_GET(obj)
#define ENCODING_IS_ASCII8BIT(obj)
VALUE rb_str_cat(VALUE, const char *, long)
size_t rb_str_capacity(VALUE)
const char * rb_id2name(ID)
ssize_t rb_io_bufwrite(VALUE io, const void *buf, size_t size)
#define DECIMAL_SIZE_OF_BITS(n)
#define RB_OBJ_GC_FLAGS_MAX
Internal header for Hash.
Internal header for String.
#define MEMCPY(p1, p2, type, n)
#define MEMMOVE(p1, p2, type, n)
struct allocation_info * objspace_lookup_allocation_info(VALUE obj)
void Init_objspace_dump(VALUE rb_mObjSpace)
#define dump_append(dc, str)
const char ruby_hexdigits[]
#define RARRAY_EMBED_FLAG
Internal header for ASAN / MSAN / etc.
size_t cur_obj_references
char buffer[BUFFER_CAPACITY]
unsigned int partial_dump
const char * root_category