Created
December 13, 2012 02:02
-
-
Save Vasfed/4273437 to your computer and use it in GitHub Desktop.
Ruby Symbol#to_proc bug example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Ruby is 2.0.0-p-1 (ruby 2.0.0dev (2012-11-01 trunk 37411) [x86_64-darwin12.2.0]) | |
A in ObjectSpace: 1 | |
Proc is 70320301647720, object is 70320301647780 | |
Object was not collected! | |
And will never be: here is the path from object to ruby VM: | |
,{"id":70320301647780,"bt":"T_OBJECT","class":70320301647860,"ivs":{}} | |
,{"id":70320301647740,"bt":"T_DATA","class":70320296186060,"type_name":"VM/env","size":96,"env":[70320301647780,70320301647740],"local_size":2,"prev_envval":null,"block":{"iseq":null,"self":"some_sym","class":null}} | |
,{"id":70320301647720,"bt":"T_DATA","class":70320296189040,"type_name":"proc","size":72,"is_lambda":0,"blockprocval":null,"envval":70320301647740,"block":{"iseq":70320301647760,"self":"some_sym","class":70320296248660}} | |
,{"id":70320295908000,"bt":"T_ARRAY","class":null,"val":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"full_name",70320295907760,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"to_sym",70320299984460,null,null,null,null,null,null,"some_sym",70320301647720]} | |
,{"id":70320296251960,"bt":"T_ARRAY","class":null,"val":[70320296251560,70320296247420,70320296238760,70320296236100,70320296236060,70320296235960,70320296235880,70320296235800,70320296235720,70320296235640,70320296235560,70320296235480,70320296235400,70320296235320,70320296235240,70320296235160,70320296235080,70320296235000,70320296234920,70320296234840,70320296234760,70320296234680,70320296234600,70320296234520,70320296234440,70320296234360,70320296234280,70320296234200,70320296234120,70320296234040,70320296233960,70320296233880,70320296233800,70320296233720,70320296233640,70320296233560,70320296233480,70320296233400,70320296233320,70320296233240,70320296233160,70320296233080,70320296233000,70320296232920,70320296232840,70320296232740,70320296232660,70320296232260,70320296232180,70320296232100,70320296232020,70320296231900,70320296231820,70320296231680,70320296231600,70320296231500,70320296231420,70320296231180,70320296231060,70320296230980,70320296222680,70320296222600,70320296222520,70320296222440,70320296222360,70320296222280,70320296222200,70320296222120,70320296222040,70320296221960,70320296221880,70320296221800,70320296221720,70320296221640,70320296221560,70320296221480,70320296221400,70320296221320,70320296221240,70320296221160,70320296221080,70320296221000,70320296220920,70320296220840,70320296220760,70320296220680,70320296220600,70320296220520,70320296220340,70320296220260,70320296220060,70320296219980,70320296219880,70320296219800,70320296219700,70320296219620,70320296219540,70320296219460,70320296219380,70320296219300,70320296219220,70320296219140,70320296219060,70320296216540,70320296216460,70320296216380,70320296215840,70320296214820,70320296205880,70320296205800,"\n",70320296202680,70320296202420,70320296200120,70320296199480,70320296198360,70320296198260,70320296198200,70320296189660,70320296189080,70320296188220,70320296187360,70320296186940,70320296186540,70320296186360,70320296186260,70320296186120,70320296186060,70320296184220,70320296183960,70320296183880,70320296183720,70320296182340,70320296182200,70320296182140,70320296182080,70320296182020,"_",70320296173360,70320296173260,70320296173200,70320296173140,"/",".eE","",70320296173020,"_","ruby",70320295888140,70320295887940,70320295908000,70320296003380,70320296021860,70320296021800,70320296021560,70320296021480,70320296021400,70320296021260,70320296055080,70320296054960,70320300281120,70320300725660,86400000000000,70320300249200,70320300249080,70320300248920,70320300248540,70320295992560,70320295991820,70320295991300,70320295991040,70320295990340,70320295988660,70320295987540,70320295986940,70320295985520,70320295975580,70320295975140,70320295974280,70320295974100,70320295973840,70320295973740,70320295973600,70320295973520,70320295973420,70320301698800,70320301698700,70320301698640,70320301698520]} | |
,{"id":70320296184120,"bt":"T_DATA","class":70320296186160,"type_name":"VM","size":1304,"thgroup_default":70320296182960,"mark_object_ary":70320296251960,"load_path":70320296189240,"loaded_features":70320296189180,"top_self":70320296252000,"coverages":null,"threads":["id",70367631233216]} | |
70320296184120 - is VM and is never collected :) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source :rubygems | |
gem 'colorize' | |
gem 'heap_dump', git:'git://github.com/Vasfed/heap_dump.git' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'bundler/setup' | |
require 'heap_dump' | |
require 'colorize' | |
puts "Ruby is #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} (#{RUBY_DESCRIPTION})" | |
if ARGV.size > 0 | |
puts "Replacing native Symbol#to_proc.".red | |
class Symbol; def to_proc; proc{|a| a.send self }; end; end | |
end | |
class A | |
def get_block_id █ block.object_id; end | |
def some_method_with_symbol_to_proc | |
$id = object_id+1 # +1 is just to make grepping nicer; this is fixnum, no reference | |
get_block_id(&:some_sym) | |
end | |
end | |
def closure_method | |
#temporary object should be collected: | |
A.new.some_method_with_symbol_to_proc | |
end | |
def nop; end | |
proc_id = closure_method | |
nop # to clean register | |
HeapDump.dump($dump = 'dump.json', true) #calls gc | |
@id = $id - 1 | |
puts "A in ObjectSpace: #{ObjectSpace.each_object(A){}}" | |
puts "\nProc is #{proc_id.to_s.green}, object is #{@id.to_s.red}" | |
if (s = `grep #{@id} #{$dump} | grep T_OBJECT`).empty? | |
puts "Wow, everything is ok (have you replaced the Symbol#to_proc call or using 1.9.2?)".green | |
else | |
puts "Object was not collected!".red | |
puts "And will never be: here is the path from object to ruby VM:" | |
def colored_puts str | |
puts @colors.inject(str){|str,(s,c)| str.gsub(s.to_s, "#{s}".colorize(c))} | |
str | |
end | |
def inspection_step color | |
(s = `grep #{@id} #{$dump} | grep -v id\\":#{@id} | grep -v #{@id.to_i + 1}`) =~ /,\{"id":(\d+)/ | |
@colors[@id = $1] = color | |
colored_puts s | |
end | |
@colors = {@id => :red} | |
colored_puts s | |
([:yellow, :green, :blue, :magenta, :cyan]*3).each{|c| | |
if inspection_step(c) =~ /"type_name":"VM"/ | |
colored_puts "#{@id} - is VM and is never collected :)" | |
break | |
end | |
} | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment