[#35446] [Ruby 1.9 - Bug #4477][Open] Kernel:exec and backtick (`) don't work for certain system commands — Joachim Wuttke <j.wuttke@...>

10 messages 2011/03/07

[#35476] [Ruby 1.9 - Bug #4489][Open] [PATCH] Encodings with /-(unix|dos|mac)\Z/ — "James M. Lawrence" <quixoticsycophant@...>

20 messages 2011/03/10

[#35552] [Ruby 1.9 - Feature #4523][Open] Kernel#require to return the path of the loaded file — Alex Young <alex@...>

14 messages 2011/03/24

[#35565] [Ruby 1.9 - Feature #4531][Open] [PATCH 0/7] use poll() instead of select() in certain cases — Eric Wong <normalperson@...>

33 messages 2011/03/28

[#35566] [Ruby 1.9 - Feature #4532][Open] [PATCH] add IO#pread and IO#pwrite methods — Eric Wong <normalperson@...>

12 messages 2011/03/28

[#35586] [Ruby 1.9 - Feature #4538][Open] [PATCH (cleanup)] avoid unnecessary select() calls before doing I/O — Eric Wong <normalperson@...>

9 messages 2011/03/29

[ruby-core:35544] Re: NoMethodError#message may take very long to execute

From: David Yip <yipdw@...>
Date: 2011-03-23 16:34:19 UTC
List: ruby-core #35544
Hi Adiel,

Your report might get more attention in Ruby's issue tracker:
http://redmine.ruby-lang.org/

- David

On Wed, Mar 23, 2011 at 10:17 AM, Adiel Mittmann <adiel@inf.ufsc.br> wrote:
> Hi,
>
> Should I report the bug I described a few days ago somewhere else? Or
> is it considered a non-issue that should be left behind?
>
> On Fri, Mar 18, 2011 at 07:53:14AM +0900, Adiel Mittmann wrote:
>> Hello,
>>
>> When a non-existing method is called on an object, NoMethodError is risen. If
>> you call #message, however, your code may use up all CPU for a very long time
>> (in my case, up to a few minutes).
>>
>> I narrowed the problem down to this code in error.c (SVN snapshot) in the function
>> name_err_mesg_to_str():
>>
>>             d = rb_protect(rb_inspect, obj, 0);
>>             if (NIL_P(d) || RSTRING_LEN(d) > 65) {
>>                 d = rb_any_to_s(obj);
>>             }
>>
>> The problem is that, for a complex object, #inspect may take very long to
>> execute, only to have its results thrown away because they will be larger than
>> 65 characters.
>>
>> Of course I can write a #to_s for all my objects, but the point is that I didn't
>> call #to_s or #inspect, I called #message on an exception object, which then
>> takes a few minutes just to return a short string.
>>
>> Needless to say, this might be easy to spot in a simple example, but once you're
>> writing a web application that suddenly freezes for one minute with no apparent
>> reason, you're all but clueless as to what's going on. (The first time this
>> happened, I didn't even know that something would eventually show up on the
>> screen -- I thought it was an infinite loop).
>>
>> Here's an example code that shows this behavior:
>>
>> <snip>
>> require 'nokogiri'
>> class A
>>   def x
>>     @xml = Nokogiri::XML(File.new('baz.xml', 'rb').read())
>>     foo()
>>   end
>> end
>> A.new().x()
>> a.x
>> </snip>
>>
>> Here, the time it takes for Ruby to print out the message that #foo doesn't
>> exist is proportional to the size of baz.xml.
>>
>> As a comparison, Python doesn't seem to do this. Take the following code:
>>
>> <snip>
>> class Test:
>>     def __str__(self):
>>         return "hello"
>> a = Test()
>> print a
>> print a.x()
>> </snip>
>>
>> If you execute it, this is the result:
>>
>> <output>
>> hello
>> Traceback (most recent call last):
>>   File "test.py", line 6, in <module>
>>     print a.x()
>> AttributeError: Test instance has no attribute 'x'
>> </output>
>>
>> It uses the method __str__ to convert the object to a string when necessary, but
>> doesn't use it when printing out the message stating that the attribute doesn't
>> exist.
>>
>> One obvious way to fix this would be to always print out the simpler
>> representation given by rb_any_to_s.
>>
>> --
>> Adiel Mittmann
>
>

In This Thread