Project

General

Profile

Actions

Bug #12927

closed

SIGSEGV during GC marking of sym procs

Added by eritiro (Emiliano Ritiro) almost 8 years ago. Updated almost 8 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:78100]

Description

After we migrated from Ruby 2.2.4 to Ruby 2.3.1 we started seeing a Segmentation Fault. This happens when the GC calls proc_mark() during the marking phase.
The proc tries to mark the block.ep[1] which contains an invalid VALUE.

I attached a script to reproduce the issue and the output of that script. (You have to run it a couple of times, it sigsevs 20% of the time)

Follow are the conclusion of my analysis:
The attached script duplicates a sym proc in memory (&:to_h)
sym procs in Ruby 2.3 uses a cfunc_proc_t which puts its environment data at the end of the rb_proc_t struct.
block->ep points to that environment.

When you copy a proc (with dup_proc()), the new proc will have a block->ep pointing to the original cfunc_proc_t
The sym_proc_cache prevents the corruption in most of the cases, but if we have a cache collision that replaces the original proc, and there are no other references to the original proc, the GC will collect the original proc, including its 64 bits of cfunc_proc_t, making them available for future use.
The duplicated proc will still be pointing to the original env, which now is freed data that GC can assign to whatever it wants.
If after that, this particular position of memory is filled with a VALUE that points outside of our memory, ruby aborts with a core dump.


Files

segfault.rb (1.76 KB) segfault.rb Script that reproduce the issue eritiro (Emiliano Ritiro), 11/12/2016 09:54 PM
output.txt (22 KB) output.txt eritiro (Emiliano Ritiro), 11/12/2016 09:57 PM

Related issues 1 (0 open1 closed)

Related to Ruby master - Feature #12628: change block/env structsClosedko1 (Koichi Sasada)Actions

Updated by eritiro (Emiliano Ritiro) almost 8 years ago

I created a PR with a proposed solution:
https://github.com/ruby/ruby/pull/1479

Actions #2

Updated by nobu (Nobuyoshi Nakada) almost 8 years ago

Updated by nobu (Nobuyoshi Nakada) almost 8 years ago

  • Status changed from Open to Closed
  • Backport set to 2.1: UNKNOWN, 2.2: REQUIRED, 2.3: REQUIRED

Seems already fixed in the trunk in a different way.

Updated by eritiro (Emiliano Ritiro) almost 8 years ago

  • Backport changed from 2.1: UNKNOWN, 2.2: REQUIRED, 2.3: REQUIRED to 2.3: REQUIRED

Hello Nobuyoshi Nakada,

I see you changed the backport:
But the only affected version is 2.3
Are we going to patch 2.3 or we have to wait for 2.4?
Thanks.

Updated by eritiro (Emiliano Ritiro) almost 8 years ago

  • Backport changed from 2.3: REQUIRED to 2.1: DONTNEED, 2.2: DONTNEED, 2.3: REQUIRED

Updated by nagachika (Tomoyuki Chikanaga) almost 8 years ago

I think r55766 introduces too big changes and I cannot backport it to the stable branches.
https://github.com/ruby/ruby/pull/1479/files seems reasonable to me. ko1 san, nakada san, What do you think of the patch?

Updated by nagachika (Tomoyuki Chikanaga) almost 8 years ago

  • Backport changed from 2.1: DONTNEED, 2.2: DONTNEED, 2.3: REQUIRED to 2.1: DONTNEED, 2.2: DONTNEED, 2.3: DONE

I ask ko1 and nobu to review the pull request and there's no objection.
I've merged it into ruby_2_3 branch at r56841.

Emiliano, thank you for your report and investigations in detail.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0