Ben Gribaudo
2006-Oct-17  19:23 UTC
Debugging a Hanging Rails App -- Suspect blocking due to file locking
Hello,
I am debugging a Rails app which hangs every one to three days. The 
process doesn''t crash; it just stops responding. I have been unable to 
predictably reproduce this failure in a testing environment.
The hang occurs after a call to Authentication controller''s access 
method (code below). This action is called many times each day but only 
once in a while does the call cause a hang.
Right now, my hypothesis is that the hang is file system blocking caused 
by a file lock. Tmpreaper runs every minute or two to remove old session 
files. My limited knowledge of Linux file systems makes me think that if 
it were, lsof would show it holding a lock.
The fact that lsof shows ruby holding two locks on the session file 
makes me wonder if both Rail''s default session handling functionality 
and the call to "CGI::Session.new(CGI.new, options)" are both trying
to
keep the same file open, thus causing blocking.
Any clues on what might be causing this locking or how to resolve it?
Thank you,
Ben
Chicago 2006 Alumni
===================System Specs:
Ruby 1.8.5 built from stable source
Ubuntu 6.06
Rails 1.1.6 using Webrick behind an Apache 2 reverse proxy
Here''s relevant output from lsof from when the system hung this
morning:
ruby        748        dailysuccess    6uW     REG      104,1        
0     167704 
/tmp/sessions/dailysuccess/service/ruby_sess.e223f7c38046356c (deleted)
ruby        748        dailysuccess    7uW     REG      104,1        
0     167704 
/tmp/sessions/dailysuccess/service/ruby_sess.e223f7c38046356c (deleted)
Using gdb to examine the process (thanks to Jamis Buck''s recent blog 
postings) and execute a backtrace reveals:
0x89c1750:       
"/var/iblp/dailysuccess/ruby/lib/ruby/1.8/pstore.rb:292:in
`flock''"
0x89c1798:       
"/var/iblp/dailysuccess/ruby/lib/ruby/1.8/pstore.rb:292:in
`transaction''"
0x89c17e8:       
"/var/iblp/dailysuccess/ruby/lib/ruby/1.8/cgi/session/pstore.rb:81:in 
`update''"
0x87d2438:       
"/var/iblp/dailysuccess/ruby/lib/ruby/1.8/cgi/session/pstore.rb:88:in 
`close''"
0x87d2490:       
"/var/iblp/dailysuccess/ruby/lib/ruby/1.8/cgi/session.rb:166:in
`callback''"
0x87d24e0:       
"/var/iblp/dailysuccess/ruby/lib/ruby/1.8/pstore.rb:368:in
`call''"
0x87d2528:       
"/var/iblp/dailysuccess/ruby/lib/ruby/1.8/pstore.rb:368:in
`commit_new''"
0x87d2578:       
"/var/iblp/dailysuccess/ruby/lib/ruby/1.8/pstore.rb:334:in
`transaction''"
0x87d25c8:       
"/var/iblp/dailysuccess/ruby/lib/ruby/1.8/cgi/session/pstore.rb:62:in 
`initialize''"
0x87d2620:       
"/var/iblp/dailysuccess/ruby/lib/ruby/1.8/cgi/session.rb:273:in
`new''"
0x87d2670:       
"/var/iblp/dailysuccess/ruby/lib/ruby/1.8/cgi/session.rb:273:in 
`initialize''"
0x87d26c0:       
"/var/iblp/dailysuccess/service/current-version/script/../config/../app/controllers/authentication_controller.rb:5:in
`new''"
0x87d2740:       
"/var/iblp/dailysuccess/service/current-version/script/../config/../app/controllers/authentication_controller.rb:5:in
`access''"
And here are a few lines from the process backtrace:
#0  0xffffe410 in __kernel_vsyscall ()
#1  0xb7f0508d in select () from /lib/tls/i686/cmov/libc.so.6
#2  0x0806842e in rb_thread_schedule () at ../ruby-1.8.5/eval.c:10638
#3  0x080697e3 in rb_thread_polling () at ../ruby-1.8.5/eval.c:11349
#4  0x0806f1ab in rb_thread_flock (fd=7, op=6, fptr=0x8251c48) at 
../ruby-1.8.5/file.c:3156
#5  0x0806f299 in rb_file_flock (obj=3080224540, operation=5) at 
../ruby-1.8.5/file.c:3216
#6  0x0805f1a4 in call_cfunc (func=0x806f1e3 <rb_file_flock>, 
recv=3080224540, len=1, argc=1, argv=0xbfbc2290) at 
../ruby-1.8.5/eval.c:5660
#7  0x0805e6c8 in rb_call0 (klass=3085134580, recv=3080224540, id=8281, 
oid=8281, argc=1, argv=0xbfbc2290, body=0xb7e35a28, flags=0)
   at ../ruby-1.8.5/eval.c:5810
#8  0x0805fc86 in rb_call (klass=3085134580, recv=3080224540, mid=8281, 
argc=1, argv=0xbfbc2290, scope=0) at ../ruby-1.8.5/eval.c:6048
#9  0x08058b53 in rb_eval (self=3079764800, n=0xb7bad184) at 
../ruby-1.8.5/eval.c:3443
class AuthenticationController < ApplicationController
# Called by an external template system to determine if Web visitor is 
allowed access.
# Template system retrieves cookie from client and passes session ID 
into this action
# which loads the session into memory in the Rails application.
 def access
   options =
default_session_options.stringify_keys.update(''session_id''
=> @params[:id])
   session = CGI::Session.new(CGI.new, options)
   render(:text => logged_in?(session) ? ''true'' :
''false'')
 end
 
 private
   def default_session_options
     ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS
   end
  
   def logged_in?(session)
       session[:user].kind_of?(User)
   end
end
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk
-~----------~----~----~----~------~----~------~--~---