Project

General

Profile

Bug #11404

Segfault when 'throw' occurs while loading a Ruby source file [PATCH]

Added by alexdowad (Alex Dowad) about 5 years ago. Updated almost 5 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.3.0dev (2015-07-23 trunk 51355) [x86_64-linux]
[ruby-core:70169]

Description

Dear Ruby people,

Here is a fix for a segfault which can occur when requiring a Ruby source file inside a Timeout.timeout {} block. This may seem like a strange thing
to do, but it can easily happen unintentionally if you use libraries which 'autoload' their source files (like RSpec, Rails, etc).

I have observed this segfault in MRI 2.1.2 and 2.3.0.

Thanks,
Alex Dowad


Files

0001-load.c-avoid-segfault-when-throw-occurs-in-the-middl.patch (1.33 KB) 0001-load.c-avoid-segfault-when-throw-occurs-in-the-middl.patch Here is the fix! alexdowad (Alex Dowad), 07/29/2015 08:25 AM
test.rb (1.2 KB) test.rb Here is code for minimal repro alexdowad (Alex Dowad), 07/29/2015 08:25 AM
blah.rb (14 Bytes) blah.rb Also needed for repro alexdowad (Alex Dowad), 07/29/2015 08:25 AM
crash-dump.txt (13.2 KB) crash-dump.txt Debug output from segfault alexdowad (Alex Dowad), 07/29/2015 08:26 AM

Related issues

Related to Ruby master - Bug #11481: Segmentation fault when thread is killed during `require`.ClosedActions
#1

Updated by nobu (Nobuyoshi Nakada) about 5 years ago

  • Status changed from Open to Closed

Applied in changeset r51439.


load.c: avoid segfault when 'throw' occurs in the middle of rb_load_file_str

How can a 'throw' happen while the current thread is reading a Ruby source file
from disk and parsing it? It can happen if another thread calls Thread#raise,
and passes an Exception object which responds to #exception, and the custom #exception
method calls Kernel#throw.

In practice, this is most likely to happen if you combine the use of autoload and
Timeout.timeout.

An extra check is required to avoid a segfault in this case.

  • load.c (rb_load_internal0): extra check before returning TAG_RAISE when a non-local transfer of control happens while loading and parsing a Ruby source file. [ruby-core:70169] [Bug #11404]

Updated by nobu (Nobuyoshi Nakada) about 5 years ago

  • Backport changed from 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN to 2.0.0: REQUIRED, 2.1: REQUIRED, 2.2: REQUIRED
#3

Updated by nagachika (Tomoyuki Chikanaga) about 5 years ago

  • Related to Bug #11481: Segmentation fault when thread is killed during `require`. added

Updated by nagachika (Tomoyuki Chikanaga) almost 5 years ago

  • Backport changed from 2.0.0: REQUIRED, 2.1: REQUIRED, 2.2: REQUIRED to 2.0.0: REQUIRED, 2.1: REQUIRED, 2.2: DONE

r51292, r51439 and r51440 were backported into ruby_2_2 branch at r52655.
r51292 seems required to r51440 works well.

Updated by nagachika (Tomoyuki Chikanaga) almost 5 years ago

Backport r51445 into ruby_2_2 branch at r52661 to suppress warning in CI.

Also available in: Atom PDF