Bug #3351
closedstack overflow on super
Added by serge_balyuk (Serge Balyuk) over 15 years ago. Updated over 10 years ago.
Description
It looks like super behavior is a bit different in 1.8 and 1.9. Please find the example below:
 class Base
   def foo
     puts "bar"
   end
 end
 
 module Override
   def foo
     puts "override"
     super
   end
 end
 
 
 class A < Base
 end
 
 class B < A
 end
 
 B.send(:include, Override)
 A.send(:include, Override)
 
 B.new.foo
 
 ruby 1.8.7 (2009-06-12 patchlevel 174) [i486-linux] output:
 
 
 override
 override
 bar
and ruby 1.9.3dev (2010-05-26 trunk 28028) [i686-linux] output:
 ....
 override
 override
 override
 override
 override
 super.rb:9: stack level too deep (SystemStackError)
Hope that helps.
Files
        
           Updated by marcandre (Marc-Andre Lafortune) over 15 years ago
          
          
        
        
          
            Actions
          
          #1
          Updated by marcandre (Marc-Andre Lafortune) over 15 years ago
          
          
        
        
          
            Actions
          
          #1
        
      
      - Category set to core
- Priority changed from Normal to 3
I thought I had submitted that bug, actually, but seems I forgot!
Just to clarify: this happens when a module appears twice in the list of ancestors. Ruby typically forbids this, but if the module is included in just the right order, it is possible. In the example given, invert the two includes and Override is included only once.
        
           Updated by serge_balyuk (Serge Balyuk) over 15 years ago
          
          
        
        
          
            Actions
          
          #2
          Updated by serge_balyuk (Serge Balyuk) over 15 years ago
          
          
        
        
          
            Actions
          
          #2
        
      
      Hi Marc-Andre,
Yes, exactly. Very rare situation. This is the simplified version of include sequence that I observed in one specific rails/rspec use case. And with inverted includes everything works like charm.
Thanks
        
           Updated by naruse (Yui NARUSE) over 14 years ago
          
          
        
        
          
            Actions
          
          #3
            [ruby-core:37387]
          Updated by naruse (Yui NARUSE) over 14 years ago
          
          
        
        
          
            Actions
          
          #3
            [ruby-core:37387]
        
      
      - Status changed from Open to Assigned
- Assignee set to ko1 (Koichi Sasada)
- Target version changed from 2.0.0 to 1.9.3
        
           Updated by funny_falcon (Yura Sokolov) over 14 years ago
          
          
        
        
          
            Actions
          
          #4
            [ruby-core:37634]
          Updated by funny_falcon (Yura Sokolov) over 14 years ago
          
          
        
        
          
            Actions
          
          #4
            [ruby-core:37634]
        
      
      I had catched by this with rails/sequel/custom backend for delayed_jobs.
After figuring, I ought to do some manipulations with requiring my initializators, and that looks ugly a bit.
        
           Updated by ko1 (Koichi Sasada) over 14 years ago
          
          
        
        
          
            Actions
          
          #5
            [ruby-core:37953]
          Updated by ko1 (Koichi Sasada) over 14 years ago
          
          
        
        
          
            Actions
          
          #5
            [ruby-core:37953]
        
      
      - Target version changed from 1.9.3 to 2.0.0
I'll challenge this issue on 1.9.4. Sorry.
        
           Updated by shugo (Shugo Maeda) about 13 years ago
          
          
        
        
          
            Actions
          
          #6
          Updated by shugo (Shugo Maeda) about 13 years ago
          
          
        
        
          
            Actions
          
          #6
        
      
      - Status changed from Assigned to Closed
- % Done changed from 0 to 100
This issue was solved with changeset r36612.
Serge, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
- insns.def (invokesuper): don't skip the same class.  instead, use
 rb_method_entry_get_with_omod() to avoid infinite loop when
 super is used with refinements. [ruby-core:30450] [Bug #3351]
        
           Updated by shugo (Shugo Maeda) about 13 years ago
          
          
        
        
          
            Actions
          
          #7
            [ruby-core:46968]
          Updated by shugo (Shugo Maeda) about 13 years ago
          
          
        
        
          
            Actions
          
          #7
            [ruby-core:46968]
        
      
      - Status changed from Closed to Open
In HEAD of trunk, stack overflow doesn't occur, but Override#foo is called only once.
So I reopen this ticket.
        
           Updated by ko1 (Koichi Sasada) almost 13 years ago
          
          
        
        
          
            Actions
          
          #8
            [ruby-core:50257]
          Updated by ko1 (Koichi Sasada) almost 13 years ago
          
          
        
        
          
            Actions
          
          #8
            [ruby-core:50257]
        
      
      shugo-san, do you know why Override#foo called only once?
        
           Updated by mame (Yusuke Endoh) almost 13 years ago
          
          
        
        
          
            Actions
          
          #9
            [ruby-core:50716]
          Updated by mame (Yusuke Endoh) almost 13 years ago
          
          
        
        
          
            Actions
          
          #9
            [ruby-core:50716]
        
      
      - Status changed from Open to Assigned
- Assignee changed from ko1 (Koichi Sasada) to shugo (Shugo Maeda)
Shugo-san, ko1, what's the status?
Do you think this issue important?
--
Yusuke Endoh mame@tsg.ne.jp
        
           Updated by shugo (Shugo Maeda) almost 13 years ago
          
          
        
        
          
            Actions
          
          #10
            [ruby-core:50857]
          Updated by shugo (Shugo Maeda) almost 13 years ago
          
          
        
        
          
            Actions
          
          #10
            [ruby-core:50857]
        
      
      - Assignee changed from shugo (Shugo Maeda) to matz (Yukihiro Matsumoto)
mame (Yusuke Endoh) wrote:
Shugo-san, ko1, what's the status?
Override#foo is called only once, because in the SVN trunk, if a method found by super is the current method, it's skipped to avoid an infinite loop. The check was introduced for super in a refinement. Without it, super in a refinement causes an infinite loop.
Do you think this issue important?
I don't think so. Can I leave it as is, Matz?
        
           Updated by Anonymous almost 13 years ago
          
          
        
        
          
            Actions
          
          #11
            [ruby-core:50860]
          Updated by Anonymous almost 13 years ago
          
          
        
        
          
            Actions
          
          #11
            [ruby-core:50860]
        
      
      Hi,
In message "Re: [ruby-core:50857] [ruby-trunk - Bug #3351] stack overflow on super"
on Thu, 13 Dec 2012 14:24:21 +0900, "shugo (Shugo Maeda)" redmine@ruby-lang.org writes:
Do you think this issue important?
I don't think so. Can I leave it as is, Matz?
OK.
						matz.
        
           Updated by shugo (Shugo Maeda) almost 13 years ago
          
          
        
        
          
            Actions
          
          #12
            [ruby-core:51189]
          Updated by shugo (Shugo Maeda) almost 13 years ago
          
          
        
        
          
            Actions
          
          #12
            [ruby-core:51189]
        
      
      - Status changed from Assigned to Open
- Assignee deleted (matz (Yukihiro Matsumoto))
- Target version changed from 2.0.0 to 2.6
        
           Updated by ko1 (Koichi Sasada) over 12 years ago
          
          
        
        
          
            Actions
          
          #13
            [ruby-core:52406]
          Updated by ko1 (Koichi Sasada) over 12 years ago
          
          
        
        
          
            Actions
          
          #13
            [ruby-core:52406]
        
      
      - Assignee set to ko1 (Koichi Sasada)
        
           Updated by ko1 (Koichi Sasada) over 10 years ago
          
          
        
        
          
            Actions
          
          #14
            [ruby-core:69825]
          Updated by ko1 (Koichi Sasada) over 10 years ago
          
          
        
        
          
            Actions
          
          #14
            [ruby-core:69825]
        
      
      - Description updated (diff)
        
           Updated by ko1 (Koichi Sasada) over 10 years ago
          
          
        
        
          
            Actions
          
          #15
            [ruby-core:69826]
          Updated by ko1 (Koichi Sasada) over 10 years ago
          
          
        
        
          
            Actions
          
          #15
            [ruby-core:69826]
        
      
      Just now, we avoid this issue by putting klass into each frame.
However, the workaround is remaining.
Now, ancestors is here:
[B, Override, A, Override, Base, Object, Kernel, BasicObject]
and now MRI calls Override#foo only once. It skips second Override#foo.
override
bar
However, if there is a A#foo, then call Override#foo twice.
override
A
override
bar
It is ugly workaround. So I want to remove such skipping.
Matz: Can I call Override#foo twice even if it is duplicated with last call?
        
           Updated by matz (Yukihiro Matsumoto) over 10 years ago
          
          
        
        
          
            Actions
          
          #16
            [ruby-core:69881]
          Updated by matz (Yukihiro Matsumoto) over 10 years ago
          
          
        
        
          
            Actions
          
          #16
            [ruby-core:69881]
        
      
      Agreed.
Matz.
        
           Updated by ko1 (Koichi Sasada) over 10 years ago
          
          
        
        
          
            Actions
          
          #17
          Updated by ko1 (Koichi Sasada) over 10 years ago
          
          
        
        
          
            Actions
          
          #17
        
      
      - Status changed from Open to Closed
Applied in changeset r51161.
- vm_insnhelper.c (vm_search_super_method): do not skip calling
 same methods in super.
 [Bug #3351]
- test/ruby/test_super.rb: fix a test.