Webrick gets stuck with certain exceptions?

T

Tom Counsell

I've written a servlet using webrick. I've written it badly. Some
exceptions (particularly those relating to missing methods or missing
variables) causes the servlet thread to consume ever larger amounts of
memory and not return anything. Turning on tracer shows me that after
the exception is thrown the webrick thread gets stuck, performing this
for ever:

....
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Fixnum:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Fixnum:<:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Fixnum:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Fixnum:<:
"#{arg.class}: #{arg.message}\n\t" <<
.....

I can fix the underlying error. But does anyone have any thoughts as
to what I might have done wrong to cause these exceptions to jam
webrick up? (I've put the bit leading up to the error below)

Many thanks

Tom

(running ruby 1.8.1 (2003-12-25) [powerpc-darwin])

#2:soks2.rb:516:NameError:>: @wiki.revise( pagename,
upload( "attachment/#{request.query['file'].filename}",
request.query['file'] ) , author, @wiki.content_type( pagename ) )
#2:soks2.rb:516:NameError:<: @wiki.revise( pagename,
upload( "attachment/#{request.query['file'].filename}",
request.query['file'] ) , author, @wiki.content_type( pagename ) )
#2:soks2.rb:516:Exception:>: @wiki.revise( pagename,
upload( "attachment/#{request.query['file'].filename}",
request.query['file'] ) , author, @wiki.content_type( pagename ) )
#2:soks2.rb:516:Exception:<: @wiki.revise( pagename,
upload( "attachment/#{request.query['file'].filename}",
request.query['file'] ) , author, @wiki.content_type( pagename ) )
#2:soks2.rb:516:Exception:>: @wiki.revise( pagename,
upload( "attachment/#{request.query['file'].filename}",
request.query['file'] ) , author, @wiki.content_type( pagename ) )
#2:soks2.rb:516:Exception:<: @wiki.revise( pagename,
upload( "attachment/#{request.query['file'].filename}",
request.query['file'] ) , author, @wiki.content_type( pagename ) )
#2:soks2.rb:516:WikiServlet:: @wiki.revise( pagename,
upload( "attachment/#{request.query['file'].filename}",
request.query['file'] ) , author, @wiki.content_type( pagename ) )
#2:soks2.rb:516:Kernel:<: @wiki.revise( pagename,
upload( "attachment/#{request.query['file'].filename}",
request.query['file'] ) , author, @wiki.content_type( pagename ) )
#2:soks2.rb:488:WikiServlet:<: self.send( verb , request,
response, pagename, request.user)
#2:soks2.rb:488:Kernel:<: self.send( verb , request,
response, pagename, request.user)
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:54:WikiServlet:<:
service(req, res)
#2:/opt/local/lib/ruby/1.8/webrick/server.rb:150:WEBrick::HTTPServer:<:
block ? block.call(sock) : run(sock)
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:55:Module:>:
rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:55:Module:<:
rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:55:Module:>:
rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:55:Module:<:
rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:57:Module:>:
rescue HTTPStatus::Error => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:57:Module:<:
rescue HTTPStatus::Error => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:59:Module:>:
rescue HTTPStatus::Status => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:59:Module:<:
rescue HTTPStatus::Status => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:61:Module:>:
rescue StandardError => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:61:Module:<:
rescue StandardError => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:62:WEBrick::HTTPServer:-:
@logger.error(ex)
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:49:WEBrick::BasicLog:>:
def error(msg) log(ERROR, "ERROR " << format(msg)); end
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:49:WEBrick::BasicLog:-:
def error(msg) log(ERROR, "ERROR " << format(msg)); end
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:62:WEBrick::BasicLog:>:
def format(arg)
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:63:WEBrick::BasicLog:-:
str = if arg.is_a?(Exception)
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:63:WEBrick::BasicLog:-:
str = if arg.is_a?(Exception)
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:63:Kernel:>: str = if
arg.is_a?(Exception)
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:63:Kernel:<: str = if
arg.is_a?(Exception)
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:65:WEBrick::BasicLog:-:
arg.backtrace.join("\n\t") << "\n"
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Kernel:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Kernel:<:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Module:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Module:<:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Exception:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:NameError:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Kernel:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Kernel:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Fixnum:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Fixnum:<:
"#{arg.class}: #{arg.message}\n\t" <<
 
M

Markus

I'm not sure at all if this is it, but there was a bug in ruby 1.8
(fixed, I think, in 1.8.1 or 1.8.2) that caused very deep recursion in
some exceptions. Some suggestions:

* If you can, try it under 1.8.2; I wouldn't recommend blindly
upgrading as there are some semantics changes between 1.8 and
1.8.1 that (at least for me) broke things. But it is definitely
worth testing
* Search the change logs for the bug. If you compiled ruby from
source (or can) you may be able to back port the patch.

Let us know what you find out; I'll let you know if I think of anything
further. If you can't try either of the things I've suggested, give a
bit more background information about the environment & I'll take a look
at it this evening.

-- Markus


I've written a servlet using webrick. I've written it badly. Some
exceptions (particularly those relating to missing methods or missing
variables) causes the servlet thread to consume ever larger amounts of
memory and not return anything. Turning on tracer shows me that after
the exception is thrown the webrick thread gets stuck, performing this
for ever:

....
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Fixnum:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Fixnum:<:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Fixnum:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Fixnum:<:
"#{arg.class}: #{arg.message}\n\t" <<
.....

I can fix the underlying error. But does anyone have any thoughts as
to what I might have done wrong to cause these exceptions to jam
webrick up? (I've put the bit leading up to the error below)

Many thanks

Tom

(running ruby 1.8.1 (2003-12-25) [powerpc-darwin])

#2:soks2.rb:516:NameError:>: @wiki.revise( pagename,
upload( "attachment/#{request.query['file'].filename}",
request.query['file'] ) , author, @wiki.content_type( pagename ) )
#2:soks2.rb:516:NameError:<: @wiki.revise( pagename,
upload( "attachment/#{request.query['file'].filename}",
request.query['file'] ) , author, @wiki.content_type( pagename ) )
#2:soks2.rb:516:Exception:>: @wiki.revise( pagename,
upload( "attachment/#{request.query['file'].filename}",
request.query['file'] ) , author, @wiki.content_type( pagename ) )
#2:soks2.rb:516:Exception:<: @wiki.revise( pagename,
upload( "attachment/#{request.query['file'].filename}",
request.query['file'] ) , author, @wiki.content_type( pagename ) )
#2:soks2.rb:516:Exception:>: @wiki.revise( pagename,
upload( "attachment/#{request.query['file'].filename}",
request.query['file'] ) , author, @wiki.content_type( pagename ) )
#2:soks2.rb:516:Exception:<: @wiki.revise( pagename,
upload( "attachment/#{request.query['file'].filename}",
request.query['file'] ) , author, @wiki.content_type( pagename ) )
#2:soks2.rb:516:WikiServlet:: @wiki.revise( pagename,
upload( "attachment/#{request.query['file'].filename}",
request.query['file'] ) , author, @wiki.content_type( pagename ) )
#2:soks2.rb:516:Kernel:<: @wiki.revise( pagename,
upload( "attachment/#{request.query['file'].filename}",
request.query['file'] ) , author, @wiki.content_type( pagename ) )
#2:soks2.rb:488:WikiServlet:<: self.send( verb , request,
response, pagename, request.user)
#2:soks2.rb:488:Kernel:<: self.send( verb , request,
response, pagename, request.user)
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:54:WikiServlet:<:
service(req, res)
#2:/opt/local/lib/ruby/1.8/webrick/server.rb:150:WEBrick::HTTPServer:<:
block ? block.call(sock) : run(sock)
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:55:Module:>:
rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:55:Module:<:
rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:55:Module:>:
rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:55:Module:<:
rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:57:Module:>:
rescue HTTPStatus::Error => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:57:Module:<:
rescue HTTPStatus::Error => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:59:Module:>:
rescue HTTPStatus::Status => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:59:Module:<:
rescue HTTPStatus::Status => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:61:Module:>:
rescue StandardError => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:61:Module:<:
rescue StandardError => ex
#2:/opt/local/lib/ruby/1.8/webrick/httpserver.rb:62:WEBrick::HTTPServer:-:
@logger.error(ex)
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:49:WEBrick::BasicLog:>:
def error(msg) log(ERROR, "ERROR " << format(msg)); end
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:49:WEBrick::BasicLog:-:
def error(msg) log(ERROR, "ERROR " << format(msg)); end
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:62:WEBrick::BasicLog:>:
def format(arg)
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:63:WEBrick::BasicLog:-:
str = if arg.is_a?(Exception)
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:63:WEBrick::BasicLog:-:
str = if arg.is_a?(Exception)
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:63:Kernel:>: str = if
arg.is_a?(Exception)
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:63:Kernel:<: str = if
arg.is_a?(Exception)
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:65:WEBrick::BasicLog:-:
arg.backtrace.join("\n\t") << "\n"
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Kernel:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Kernel:<:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Module:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Module:<:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Exception:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:NameError:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Kernel:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Kernel:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Fixnum:>:
"#{arg.class}: #{arg.message}\n\t" <<
#2:/opt/local/lib/ruby/1.8/webrick/log.rb:64:Fixnum:<:
"#{arg.class}: #{arg.message}\n\t" <<
 
M

Markus

I'm going on very vague memory here (and Google isn't helpful when
my blood caffeine levels fall too low), but I think the change was:

ruby-1.8.2/ChangeLog

Sat Oct 25 09:18:04 2003 Yukihiro Matsumoto ruby-1.8.2/ChangeLog-
* eval.c (rb_method_missing): protect exception from within
"inspect". (ruby-bugs:pR#1204)

and the problem was something to do with missing methods / inspect / and
an exception getting locked in a death spiral recursion. I'd link to
the bug report, but for some reason I'm only finding the Japanese.

-- MarkusQ
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,968
Messages
2,570,154
Members
46,702
Latest member
LukasConde

Latest Threads

Top