23 static VALUE sym_output, sym_stdout, sym_string, sym_file;
24 static VALUE sym_full;
40 dump_append(
struct dump_config *dc,
const char *format, ...)
46 vfprintf(dc->
stream, format, vl);
61 dump_append(dc,
"\"");
63 switch ((c = value[i])) {
66 dump_append(dc,
"\\%c", c);
69 dump_append(dc,
"\\u0000");
72 dump_append(dc,
"\\b");
75 dump_append(dc,
"\\t");
78 dump_append(dc,
"\\f");
81 dump_append(dc,
"\\n");
84 dump_append(dc,
"\\r");
88 dump_append(dc,
"\\u%04d", c);
90 dump_append(dc,
"%c", c);
93 dump_append(dc,
"\"");
99 dump_append(dc,
"{\"type\":\"SYMBOL\", \"value\":");
100 dump_append_string_value(dc,
rb_sym2str(obj));
101 dump_append(dc,
"}");
104 static inline const char *
108 #define CASE_TYPE(type) case T_##type: return #type 143 if (value ==
Qtrue) {
144 dump_append(dc,
"true");
146 else if (value ==
Qfalse) {
147 dump_append(dc,
"false");
149 else if (value ==
Qnil) {
150 dump_append(dc,
"null");
153 dump_append(dc,
"%ld",
FIX2LONG(value));
159 dump_append_symbol_value(dc, value);
162 dump_append(dc,
"{}");
167 reachable_object_i(
VALUE ref,
void *data)
175 dump_append(dc,
", \"references\":[\"%p\"", (
void *)ref);
177 dump_append(dc,
", \"%p\"", (
void *)ref);
185 dump_append(dc,
", \"bytesize\":%ld",
RSTRING_LEN(obj));
190 dump_append(dc,
", \"value\":");
191 dump_append_string_value(dc, obj);
196 imemo_name(
int imemo)
199 #define TYPE_STR(t) case(imemo_##t): return #t 224 dump_append_special_const(dc, obj);
235 dump_append(dc,
"{\"address\":\"%p\", \"type\":\"%s\"", (
void *)obj, obj_type(obj));
238 dump_append(dc,
", \"class\":\"%p\"", (
void *)dc->
cur_obj_klass);
240 dump_append(dc,
", \"frozen\":true");
244 dump_append(dc,
"}\n");
252 dump_append(dc,
", \"imemo_type\":\"%s\"", imemo_name(
imemo_type(obj)));
256 dump_append_string_content(dc,
rb_sym2str(obj));
261 dump_append(dc,
", \"embedded\":true");
263 dump_append(dc,
", \"broken\":true");
265 dump_append(dc,
", \"fstring\":true");
267 dump_append(dc,
", \"shared\":true");
269 dump_append_string_content(dc, obj);
278 dump_append(dc,
", \"default\":\"%p\"", (
void *)
RHASH_IFNONE(obj));
282 dump_append(dc,
", \"length\":%ld",
RARRAY_LEN(obj));
284 dump_append(dc,
", \"shared\":true");
286 dump_append(dc,
", \"embedded\":true");
297 dump_append(dc,
", \"struct\":\"%s\"",
RTYPEDDATA_TYPE(obj)->wrap_struct_name);
301 dump_append(dc,
", \"value\":\"%g\"",
RFLOAT_VALUE(obj));
309 fptr =
RFILE(obj)->fptr;
311 dump_append(dc,
", \"fd\":%d", fptr->
fd);
315 dump_append(dc,
"}\n");
321 dump_append(dc,
"]");
324 dump_append(dc,
", \"file\":\"%s\", \"line\":%lu", ainfo->
path, ainfo->
line);
327 dump_append(dc,
", \"method\":\"%s\"",
RSTRING_PTR(m));
333 dump_append(dc,
", \"memsize\":%"PRIuSIZE, memsize);
336 dump_append(dc,
", \"flags\":{");
337 for (i=0; i<n; i++) {
338 dump_append(dc,
"\"%s\":true",
rb_id2name(flags[i]));
339 if (i != n-1) dump_append(dc,
", ");
341 dump_append(dc,
"}");
344 dump_append(dc,
"}\n");
348 heap_i(
void *vstart,
void *vend,
size_t stride,
void *data)
352 for (; v != (
VALUE)vend; v += stride) {
360 root_obj_i(
const char *category,
VALUE obj,
void *data)
365 dump_append(dc,
"]}\n");
367 dump_append(dc,
"{\"type\":\"ROOT\", \"root\":\"%s\", \"references\":[\"%p\"", category, (
void *)obj);
369 dump_append(dc,
", \"%p\"", (
void *)obj);
389 if (output == sym_stdout) {
393 else if (output == sym_file) {
404 else if (output == sym_string) {
420 if (output == sym_string) {
423 else if (output == sym_file) {
449 static const char filename[] =
"rubyobj";
455 output = dump_output(&dc, opts, sym_string, filename);
457 dump_object(obj, &dc);
459 return dump_result(&dc, output);
481 static const char filename[] =
"rubyheap";
487 output = dump_output(&dc, opts, sym_file, filename);
491 if (dc.
roots) dump_append(&dc,
"]}\n");
496 return dump_result(&dc, output);
#define is_broken_string(str)
#define RB_OBJ_GC_FLAGS_MAX
void rb_raise(VALUE exc, const char *fmt,...)
#define is_ascii_string(str)
void rb_objspace_reachable_objects_from_root(void(func)(const char *category, VALUE, void *), void *passing_data)
const char * root_category
void rb_objspace_each_objects(each_obj_callback *callback, void *data)
VALUE rb_path2class(const char *)
PRINTF_ARGS(static void dump_append(struct dump_config *, const char *,...), 2, 3)
#define GetOpenFile(obj, fp)
size_t rb_obj_memsize_of(VALUE obj)
VALUE rb_require(const char *)
VALUE rb_io_get_write_io(VALUE io)
VALUE rb_io_check_io(VALUE io)
#define HASH_PROC_DEFAULT
VALUE rb_str_resurrect(VALUE str)
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
size_t rb_obj_gc_flags(VALUE obj, ID *flags, size_t max)
VALUE rb_str_vcatf(VALUE, const char *, va_list)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
VALUE rb_assoc_new(VALUE car, VALUE cdr)
VALUE rb_obj_frozen_p(VALUE obj)
call-seq: obj.frozen? -> true or false
const char * rb_class2name(VALUE)
const char * rb_id2name(ID)
void Init_objspace_dump(VALUE rb_mObjSpace)
VALUE rb_str_new_cstr(const char *)
#define ENCODING_IS_ASCII8BIT(obj)
struct allocation_info * objspace_lookup_allocation_info(VALUE obj)
#define ENCODING_GET(obj)
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
void rb_objspace_reachable_objects_from(VALUE obj, void(func)(VALUE, void *), void *data)
#define RBASIC_CLASS(obj)
VALUE rb_hash_aref(VALUE hash, VALUE key)
const char * ruby_node_name(int node)
size_t rb_str_capacity(VALUE str)
FILE * rb_io_stdio_file(rb_io_t *fptr)
#define SPECIAL_CONST_P(x)
VALUE rb_define_module(const char *name)
size_t cur_obj_references
#define RTYPEDDATA_TYPE(v)
rb_encoding * rb_enc_from_index(int index)