ruby-changes:52762
From: nobu <ko1@a...>
Date: Tue, 9 Oct 2018 12:22:01 +0900 (JST)
Subject: [ruby-changes:52762] nobu:r64974 (trunk): ext/objspace/objspace_dump.c: print addresses consistently
nobu 2018-10-09 12:21:57 +0900 (Tue, 09 Oct 2018) New Revision: 64974 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=64974 Log: ext/objspace/objspace_dump.c: print addresses consistently The format addresses are printed in are different if you use `ObjectSpace.dump_all(output: :stdout)` vs. `ObjectSpace.dump_all(output: :string)` (or `ObjectSpace.dump`) due to differences in the underlying `vfprintf` implementation. Use `"%#"PRIxVALUE` to format `VALUE`. Co-authored-by: Ashe Connor <ashe@k...> Modified files: trunk/ext/objspace/objspace_dump.c trunk/test/objspace/test_objspace.rb Index: ext/objspace/objspace_dump.c =================================================================== --- ext/objspace/objspace_dump.c (revision 64973) +++ ext/objspace/objspace_dump.c (revision 64974) @@ -172,9 +172,9 @@ reachable_object_i(VALUE ref, void *data https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L172 return; if (dc->cur_obj_references == 0) - dump_append(dc, ", \"references\":[\"%p\"", (void *)ref); + dump_append(dc, ", \"references\":[\"%#"PRIxVALUE"\"", ref); else - dump_append(dc, ", \"%p\"", (void *)ref); + dump_append(dc, ", \"%#"PRIxVALUE"\"", ref); dc->cur_obj_references++; } @@ -235,10 +235,10 @@ dump_object(VALUE obj, struct dump_confi https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L235 if (dc->cur_obj == dc->string) return; - dump_append(dc, "{\"address\":\"%p\", \"type\":\"%s\"", (void *)obj, obj_type(obj)); + dump_append(dc, "{\"address\":\"%#"PRIxVALUE"\", \"type\":\"%s\"", obj, obj_type(obj)); if (dc->cur_obj_klass) - dump_append(dc, ", \"class\":\"%p\"", (void *)dc->cur_obj_klass); + dump_append(dc, ", \"class\":\"%#"PRIxVALUE"\"", dc->cur_obj_klass); if (rb_obj_frozen_p(obj)) dump_append(dc, ", \"frozen\":true"); @@ -274,7 +274,7 @@ dump_object(VALUE obj, struct dump_confi https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L274 case T_HASH: dump_append(dc, ", \"size\":%"PRIuSIZE, (size_t)RHASH_SIZE(obj)); if (FL_TEST(obj, HASH_PROC_DEFAULT)) - dump_append(dc, ", \"default\":\"%p\"", (void *)RHASH_IFNONE(obj)); + dump_append(dc, ", \"default\":\"%#"PRIxVALUE"\"", RHASH_IFNONE(obj)); break; case T_ARRAY: @@ -363,9 +363,9 @@ root_obj_i(const char *category, VALUE o https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L363 if (dc->root_category != NULL && category != dc->root_category) dump_append(dc, "]}\n"); if (dc->root_category == NULL || category != dc->root_category) - dump_append(dc, "{\"type\":\"ROOT\", \"root\":\"%s\", \"references\":[\"%p\"", category, (void *)obj); + dump_append(dc, "{\"type\":\"ROOT\", \"root\":\"%s\", \"references\":[\"%#"PRIxVALUE"\"", category, obj); else - dump_append(dc, ", \"%p\"", (void *)obj); + dump_append(dc, ", \"%#"PRIxVALUE"\"", obj); dc->root_category = category; dc->roots++; Index: test/objspace/test_objspace.rb =================================================================== --- test/objspace/test_objspace.rb (revision 64973) +++ test/objspace/test_objspace.rb (revision 64974) @@ -318,6 +318,62 @@ class TestObjSpace < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/objspace/test_objspace.rb#L318 end end + def test_dump_addresses_match_dump_all_addresses + assert_in_out_err(%w[-robjspace], "#{<<-"begin;"}\n#{<<-'end;'}") do |output, error| + begin; + def dump_my_heap_please + obj = Object.new + puts ObjectSpace.dump(obj) + ObjectSpace.dump_all(output: $stdout) + end + + dump_my_heap_please + end; + needle = JSON.parse(output.first) + addr = needle['address'] + found = output.drop(1).find { |l| JSON.parse(l)['address'] == addr } + assert found, "object #{addr} should be findable in full heap dump" + end + end + + def test_dump_class_addresses_match_dump_all_addresses + assert_in_out_err(%w[-robjspace], "#{<<-"begin;"}\n#{<<-'end;'}") do |output, error| + begin; + def dump_my_heap_please + obj = Object.new + puts ObjectSpace.dump(obj) + ObjectSpace.dump_all(output: $stdout) + end + + dump_my_heap_please + end; + needle = JSON.parse(output.first) + addr = needle['class'] + found = output.drop(1).find { |l| JSON.parse(l)['address'] == addr } + assert found, "object #{addr} should be findable in full heap dump" + end + end + + def test_dump_reference_addresses_match_dump_all_addresses + assert_in_out_err(%w[-robjspace], "#{<<-"begin;"}\n#{<<-'end;'}") do |output, error| + begin; + def dump_my_heap_please + obj = Object.new + obj2 = Object.new + obj2.instance_variable_set(:@ref, obj) + puts ObjectSpace.dump(obj) + ObjectSpace.dump_all(output: $stdout) + end + + dump_my_heap_please + end; + needle = JSON.parse(output.first) + addr = needle['address'] + found = output.drop(1).find { |l| (JSON.parse(l)['references'] || []).include? addr } + assert found, "object #{addr} should be findable in full heap dump" + end + end + def test_dump_all entry = /"bytesize":11, "value":"TEST STRING", "encoding":"UTF-8", "file":"-", "line":4, "method":"dump_my_heap_please", "generation":/ -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/