From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: poffice@blade.nagaokaut.ac.jp Delivered-To: poffice@blade.nagaokaut.ac.jp Received: from kankan.nagaokaut.ac.jp (kankan.nagaokaut.ac.jp [133.44.2.24]) by blade.nagaokaut.ac.jp (Postfix) with ESMTP id D35FE17D62AD for ; Sun, 10 May 2015 11:31:09 +0900 (JST) Received: from funfun.nagaokaut.ac.jp (funfun.nagaokaut.ac.jp [133.44.2.201]) by kankan.nagaokaut.ac.jp (Postfix) with ESMTP id C578EB5D8C6 for ; Sun, 10 May 2015 11:45:59 +0900 (JST) Received: from funfun.nagaokaut.ac.jp (localhost.nagaokaut.ac.jp [127.0.0.1]) by funfun.nagaokaut.ac.jp (Postfix) with ESMTP id 1A46397A826 for ; Sun, 10 May 2015 11:46:01 +0900 (JST) X-Virus-Scanned: amavisd-new at nagaokaut.ac.jp Authentication-Results: funfun.nagaokaut.ac.jp (amavisd-new); dkim=fail (1024-bit key) reason="fail (message has been altered)" header.d=sendgrid.me Received: from funfun.nagaokaut.ac.jp ([127.0.0.1]) by funfun.nagaokaut.ac.jp (funfun.nagaokaut.ac.jp [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DdCpSW4a1DD7 for ; Sun, 10 May 2015 11:46:00 +0900 (JST) Received: from voscc.nagaokaut.ac.jp (voscc.nagaokaut.ac.jp [133.44.1.100]) by funfun.nagaokaut.ac.jp (Postfix) with ESMTP id C0BE897A820 for ; Sun, 10 May 2015 11:46:00 +0900 (JST) Received: from neon.ruby-lang.org (neon.ruby-lang.org [221.186.184.75]) by voscc.nagaokaut.ac.jp (Postfix) with ESMTP id 69F1795243A for ; Sun, 10 May 2015 11:45:59 +0900 (JST) Received: from [221.186.184.76] (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id 869C01204DA; Sun, 10 May 2015 11:45:56 +0900 (JST) X-Original-To: ruby-core@ruby-lang.org Delivered-To: ruby-core@ruby-lang.org Received: from o10.shared.sendgrid.net (o10.shared.sendgrid.net [173.193.132.135]) by neon.ruby-lang.org (Postfix) with ESMTPS id 67E01120479 for ; Sun, 10 May 2015 11:45:52 +0900 (JST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sendgrid.me; h=from:to:references:subject:mime-version:content-type:content-transfer-encoding:list-id; s=smtpapi; bh=BvTHQ50EMY7rP7bGakxtGdTVttk=; b=mv17jbfS8OI3mexixx mfunk2AuYvJQZdVtTDFJtGZLt8QhQwlPjoeK4NW3aO5dc6ZyUIEHq8PhSXz7+Dew EDtJrcCK/ywmwJn2MzO1dsbkXF17JtLdtOD3iC/uvLAkRdB5vwVZxCnDldKLSf4u 0BvMACg9RWKNQgjIip2KeJD80= Received: by filter0352p1mdw1.sendgrid.net with SMTP id filter0352p1mdw1.8700.554EC65B3 2015-05-10 02:45:47.9674258 +0000 UTC Received: from herokuapp.com (ec2-54-146-60-42.compute-1.amazonaws.com [54.146.60.42]) by ismtpd-030 (SG) with ESMTP id 14d3bb6d6f8.2a7.61d4d for ; Sun, 10 May 2015 02:45:47 +0000 (UTC) Date: Sun, 10 May 2015 02:45:47 +0000 From: halostatue@gmail.com To: ruby-core@ruby-lang.org Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Redmine-MailingListIntegration-Message-Ids: 43519 X-Redmine-Project: ruby-trunk X-Redmine-Issue-Id: 11088 X-Redmine-Issue-Author: kaiserprogrammer X-Redmine-Sender: austin X-Mailer: Redmine X-Redmine-Host: bugs.ruby-lang.org X-Redmine-Site: Ruby Issue Tracking System X-Auto-Response-Suppress: All Auto-Submitted: auto-generated X-SG-EID: ync6xU2WACa70kv/Ymy4QrNMhiuLXJG8OTL2vJD1yS6Zs2Vw6ObyCE1ADyX2W4VpigpkQbCU+sRlvv 3yDpkXlD1hXqKCJBG2kBg06yt6K3tQ24uG/a5Xpu5dp1pNYnCi58fCwuKUxG/I90Pwz9Jx7WAFYfv/ 09m46W5N/hl8ffI= X-ML-Name: ruby-core X-Mail-Count: 69113 Subject: [ruby-core:69113] [Ruby trunk - Bug #11088] Infinite loop on calling missing/overwritten methods of restored marshaled objects X-BeenThere: ruby-core@ruby-lang.org X-Mailman-Version: 2.1.15 Precedence: list Reply-To: Ruby developers List-Id: Ruby developers List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: ruby-core-bounces@ruby-lang.org Sender: "ruby-core" Issue #11088 has been updated by Austin Ziegler. File simple-inspect.txt added File simple-inspect-stats.txt added File bug_hunt_benchmark.rb added File bug_hunt_simple.rb added The data structure in question is large and has some slightly pathological = recursiveness. There are 3,204 objects marshalled. Most of these (3,088) ar= e referenced exactly once. Of the remaining: * 52 appear between 2x and 9x. * 17 appear between 20x and 29x. * 13 appear between 30x and 39x. * 6 appear between 40x and 49x. * 16 appear between 50x and 59x. * 9 appear between 60x and 69x. * 1 appears 71x. * 1 appears 88x. * 1 appears 89x. I=E2=80=99m attaching `bug_hunt_simple.rb` (based on `SimpleInspect` below)= , `simple-inspect.txt` (the output of a simplified inspect), and `simple-in= spect-stats.txt` (the count of appearances). What=E2=80=99s interesting to me is that there=E2=80=99s an *observable* sl= owdown in the output of the `NoMethodError` result, so I benchmarked it (`b= ug_hunt_benchmark.rb`). There=E2=80=99s a consistent 0.1=E2=80=930.2 second= slowdown over 100,000 iterations, and the output of the exception message = differs between the two forms (at the bottom of the file). (The slowdown is= ~0.6s/100k on ruby 2.0 and 2.1, so there is that.) > Note: these are the values where the inspect strings are constructed. If = I remove the custom string construction and minimize the interaction with `= $__inspected__` and its helper methods, there is *still* a consistent 0.05= =E2=80=930.1s/100k slowdown. So there=E2=80=99s something about looking at an exception that triggers an= expensive `#inspect`=E2=80=94but then discards it for a cheap `#inspect` i= n some circumstances. Without the `SimpleInspect` module (which is mostly u= seless because it keeps program-wide state, but is useful for this investig= ation), somehow the recursion detection of `#inspect` has been blown to bit= s in some recent version of Ruby (the problem shows up for ruby 2.0.0p481, = ruby 2.1.6p336, ruby 2.2.2p95 and ruby 2.3.0dev (2015-04-11), which are the= only Rubies I have on my Mac right now). ```ruby module SimpleInspect def inspect result =3D if inspected? "#<%s (%d) ...>" % [ inspected_key, inspected_count ] else super end inspect! "\n" + result end private def inspected? inspected[inspected_key].nonzero? end def inspect! inspected[inspected_key] +=3D 1 end def inspected_count inspected[inspected_key] end def inspected $__inspected__ ||=3D Hash.new { |h, k| h[k] =3D 0 } end def inspected_key "%s:0x%014x" % [ self.class, "0x%014x" % (object_id * 2) ] end end class Object include SimpleInspect end ``` ---------------------------------------- Bug #11088: Infinite loop on calling missing/overwritten methods of restore= d marshaled objects https://bugs.ruby-lang.org/issues/11088#change-52359 * Author: J=C3=BCrgen Bickert * Status: Open * Priority: Normal * Assignee:=20 * ruby -v: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux] * Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN ---------------------------------------- I have Marshal.dump some objects and then I Marshal.load them and later I c= all non-existent methods on those objects and instead of raising an excepti= on (NoMethodError) it runs off in an infinite loop. I have tested with simple cases where the dumped structure is not recursive= and it works fine. So I attached a non-working dump which will when called= with inspect or a non-existing method run off in an infinite loop. When you run "ruby bug_hunt.rb" it will get stuck and you have to abort(CTR= L-C) and only then will it print an error message and finish. ---Files-------------------------------- bug_hunt.rb (336 Bytes) ruby_object.dump (561 KB) 11088_test.rb (305 Bytes) simple-inspect.txt (1.19 MB) simple-inspect-stats.txt (90.7 KB) bug_hunt_benchmark.rb (1.42 KB) bug_hunt_simple.rb (1.09 KB) --=20 https://bugs.ruby-lang.org/