-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Small context leak #798
Comments
Yeah, let’s definitely close this gap. We should probably do another review On Fri, Oct 16, 2015 at 1:16 PM, Richard Schneeman <notifications@github.com
|
I was curious if we could write tooling around this. We would need to detect when a proc scope is created and what the local and instance variables are when it is created. It looks like we can get that from TracePoint: TracePoint.new(:b_call) do |tp|
puts tp.binding.local_variables.inspect
puts self.instance_variables.inspect
file_line = "#{tp.path}:#{tp.lineno}"
puts file_line.inspect
end.enable
a = nil
@boo = "foo"
->() {}.call Then we would need to know what block objects are retained. If we know the block objects being retained, we can work backwards find out what variables the blocks have reference to, and boom...we've built an automated context leak detector. Unfortunately i've not figured out this second part. i.e. how do you ask Ruby if an object is retained? You can use require 'objspace'
ObjectSpace.trace_object_allocations do
a = Proc.new {}
b = -> {}
def foo(&block)
return block
end
c = foo do
end
end
ObjectSpace.each_object(Proc) do |obj|
puts obj
end However the |
💥 thanks! |
When you create a block, it retains references to current variables in scope. We are creating blocks while trapping signals here:
puma/lib/puma/cluster.rb
Lines 332 to 334 in d56ad84
Thread.list
I think this should be fine for 99% of the cases, since most threads already running at that point will continue to run. However if you created a thread on boot that did something insane like read in a gig of data to the thread context and then discard the thread, this would accidentally retain a reference to the thread and accidentally retain that data. It's an edge case for sure.
To fix we could make a new method
def self.setup_traps(master)
and we could pass in only the main object, though we would need to expose@options[:workers]
or pass it in.It's not critical, but I think we should close this gap to be safe. What do you think?
The text was updated successfully, but these errors were encountered: