From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS4713 221.184.0.0/13 X-Spam-Status: No, score=-3.8 required=3.0 tests=AWL,BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from neon.ruby-lang.org (neon.ruby-lang.org [221.186.184.75]) by dcvr.yhbt.net (Postfix) with ESMTP id E85F61F462 for ; Tue, 11 Jun 2019 20:27:25 +0000 (UTC) Received: from neon.ruby-lang.org (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id A28AE120A55; Wed, 12 Jun 2019 05:27:20 +0900 (JST) Received: from o1678948x4.outbound-mail.sendgrid.net (o1678948x4.outbound-mail.sendgrid.net [167.89.48.4]) by neon.ruby-lang.org (Postfix) with ESMTPS id C78B6120A40 for ; Wed, 12 Jun 2019 05:27:18 +0900 (JST) Received: by filter0092p3las1.sendgrid.net with SMTP id filter0092p3las1-23273-5D000EA7-7 2019-06-11 20:27:19.240111704 +0000 UTC m=+615458.171470336 Received: from herokuapp.com (unknown [107.20.11.70]) by ismtpd0036p1mdw1.sendgrid.net (SG) with ESMTP id zMIAWOwGSVaxAfy1d7iGPQ for ; Tue, 11 Jun 2019 20:27:19.130 +0000 (UTC) Date: Tue, 11 Jun 2019 20:27:19 +0000 (UTC) From: merch-redmine@jeremyevans.net Message-ID: References: Mime-Version: 1.0 X-Redmine-MailingListIntegration-Message-Ids: 68532 X-Redmine-Project: ruby-trunk X-Redmine-Issue-Id: 15645 X-Redmine-Issue-Author: jneen X-Redmine-Sender: jeremyevans0 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: =?us-ascii?Q?RVE3t853K5scBhbmJHUzZTFFeVC=2FZSUmHZ0Dc+26wcEi2CTgsF1oz0wTSSxGGN?= =?us-ascii?Q?BI9Ptai=2FnNzkeD46LoEVapqLsUU8Jmy66WD77vc?= =?us-ascii?Q?3IExfvZn7G+rhwqNrHmyodvEY5BmcpNi7fGDSsu?= =?us-ascii?Q?YgQqPmgD2xuIljG67Qqny9nv7IqQnnkeJ5FAWRO?= =?us-ascii?Q?s=2FKc2kn0Ly9JGpJvTGOaJ7KW3V1e76mYZKg=3D=3D?= To: ruby-core@ruby-lang.org X-ML-Name: ruby-core X-Mail-Count: 93054 Subject: [ruby-core:93054] [Ruby trunk Bug#15645] It is possible to escape `Mutex#synchronize` without releasing the mutex 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: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ruby-core-bounces@ruby-lang.org Sender: "ruby-core" Issue #15645 has been updated by jeremyevans0 (Jeremy Evans). Eregon (Benoit Daloze) wrote: > @jeremyevans0 The patch looks wrong, `rb_mutex_lock` should be changed, not `rb_mutex_unlock`. Correct, apologies for that. It turns out there is a pull request for this that should may the issue (https://github.com/ruby/ruby/pull/2131). ---------------------------------------- Bug #15645: It is possible to escape `Mutex#synchronize` without releasing the mutex https://bugs.ruby-lang.org/issues/15645#change-78454 * Author: jneen (Jeanine Adkisson) * Status: Open * Priority: Normal * Assignee: * Target version: * ruby -v: ruby 2.6.1p33 (2019-01-30 revision 66950) [x86_64-linux] * Backport: 2.4: UNKNOWN, 2.5: UNKNOWN, 2.6: UNKNOWN ---------------------------------------- Hello, I hope this finds you well. I have a persistent deadlocking issue in a project that relies both on `Mutex#synchronize` and `Thread#raise`, and I believe I have reduced the problem to the following example, in which it is possible to exit a `synchronize` block without releasing the mutex. ``` ruby mutex = Mutex.new class E < StandardError; end t1 = Thread.new do 10000.times do begin mutex.synchronize do puts 'acquired' # sleep 0.01 raise E if rand < 0.5 puts 'releasing' end rescue E puts "interrupted" end puts "UNRELEASED MUTEX" if mutex.owned? end end t2 = Thread.new do 1000.times do mutex.synchronize { sleep 0.01 } sleep 0.01 t1.raise(E) end end t3 = Thread.new do 1000.times do mutex.synchronize { sleep 0.01 } sleep 0.01 t1.raise(E) end end t2.join t3.join ``` I would expect `mutex.owned?` to always return `false` outside of the `synchronize { ... }` block, but when I run the above script, I see the following output: ``` ; ruby tmp/testy.rb acquired interrupted interrupted UNRELEASED MUTEX # terminated with exception (report_on_ exception is true): Traceback (most recent call last): 3: from tmp/testy.rb:5:in `block in
' 2: from tmp/testy.rb:5:in `times' 1: from tmp/testy.rb:7:in `block (2 levels) in
' tmp/testy.rb:7:in `synchronize': deadlock; recursive locking (ThreadError) ``` I do not fully understand why this is possible, and it is possible there is a simpler example that would reproduce the issue. But it seems at least that it is necessary for two different threads to be running `Thread#raise` simultaneously. Occasionally, especially if the timing of the `sleep` calls are tuned, the thread `t1` will display an stack trace for an error `E` - which I believe is the expected behavior in the case that the error is raised during its rescue block. Thank you for your time! -- https://bugs.ruby-lang.org/