Project

General

Profile

Bug #10847

SystemStackError after NameError prepends a module

Added by yuki24 (Yuki Nishijima) over 5 years ago. Updated over 5 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-linux]
[ruby-core:68093]

Description

The following code causes SystemStackError.

module Foo
end

NameError.prepend Foo
foo rescue $!

And here is the full backtrace:

system_stack_error_from_name_error.rb:3:in `initialize': stack level too deep (SystemStackError)
    from system_stack_error_from_name_error.rb:3:in `initialize'
    from system_stack_error_from_name_error.rb:3:in `initialize'
    from system_stack_error_from_name_error.rb:3:in `initialize'
    from system_stack_error_from_name_error.rb:3:in `initialize'
    from system_stack_error_from_name_error.rb:3:in `initialize'
    from system_stack_error_from_name_error.rb:3:in `initialize'
    from system_stack_error_from_name_error.rb:3:in `initialize'
    from system_stack_error_from_name_error.rb:3:in `initialize'
     ... 10907 levels...
    from system_stack_error_from_name_error.rb:3:in `initialize'
    from system_stack_error_from_name_error.rb:3:in `initialize'
    from system_stack_error_from_name_error.rb:3:in `method_missing'
    from system_stack_error_from_name_error.rb:3:in `<main>'

This happens on Ruby 2.0.0, 2,1,5, 2.2.0 and ruby-trunk(rev 49451).


Related issues

Has duplicate Ruby master - Bug #10970: Backport r49867Closed03/13/2015Actions

Updated by hanachin (Seiei Miyagi) over 5 years ago

How to reproduce:

  1. prepend Module to the class
  2. call the method that calls cfunc rb_call_super

The following code causes SystemStackError too, because Float#numerator calls rb_call_super.

module M; end
Float.prepend M

0.3.numerator

I wrote a patch for this issue.

diff --git vm_eval.c vm_eval.c
index 6eeee5f..4039b6c 100644
--- vm_eval.c
+++ vm_eval.c
@@ -273,7 +273,8 @@ vm_call_super(rb_thread_t *th, int argc, const VALUE *argv)
        rb_bug("vm_call_super: should not be reached");
     }

-    klass = RCLASS_SUPER(cfp->klass);
+    klass = RCLASS_ORIGIN(cfp->klass);
+    klass = RCLASS_SUPER(klass);
     id = cfp->me->def->original_id;
     me = rb_method_entry(klass, id, &klass);
     if (!me) {
#2

Updated by nobu (Nobuyoshi Nakada) over 5 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

Applied in changeset r49867.


vm_eval.c: next super class from the original

  • vm_eval.c (vm_call_super): search next super class from the original class, to get rid of infinite recursion with prepending. a patch by Seiei Higa at [ruby-core:68434]. [ruby-core:68093] [Bug #10847]
#3

Updated by usa (Usaku NAKAMURA) over 5 years ago

#4

Updated by usa (Usaku NAKAMURA) over 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
#5

Updated by nagachika (Tomoyuki Chikanaga) over 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

Backported into ruby_2_2 branch at r50275.

#6

Updated by usa (Usaku NAKAMURA) over 5 years ago

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

ruby_2_1 r50284 merged revision(s) 49867.

Also available in: Atom PDF