Bug #9454

The define_method(:class) segfault

Added by Kyrylo Silin over 1 year ago. Updated about 1 year ago.

[ruby-core:60113]
Status:Closed
Priority:Normal
Assignee:-
ruby -v:ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-linux] Backport:1.9.3: UNKNOWN, 2.0.0: REQUIRED, 2.1: DONE

Description

Ruby 2.1.0p0 segfaults when I invoke the following code.

define_method(:class) { self.class }
self.class #=> segfault :(

It affects exclusively Ruby 2.1.0p0 (I also tested on the most recent 2.0.0, 1.9.3 and 1.8.7).

By the way, on the contrary, the following code does not segfault.

def self.class; self.class end
self.class #=> SystemStackError

Viva la Ucraino revolución!

bug9454.txt Magnifier (625 KB) Kyrylo Silin, 01/26/2014 07:25 PM


Related issues

Duplicated by Backport21 - Backport #9828: Segfault instead of stack overflow Closed 05/11/2014
Duplicated by Ruby trunk - Bug #9945: Segmentation fault when defining recursive method Closed 06/14/2014
Duplicated by Ruby trunk - Bug #10218: 手続きを再帰するとSegmentation faultが発生する Closed 09/09/2014
Duplicated by Ruby trunk - Bug #10955: invoke_block_from_c segfault Open 03/09/2015

Associated revisions

Revision 44712
Added by Nobuyoshi Nakada over 1 year ago

thread_pthread.c: get current main thread stack size

  • thread_pthread.c: get current main thread stack size, which may be expanded than allocated size at initialization, by rlimit(). [Bug #9454]

Revision 44712
Added by Nobuyoshi Nakada over 1 year ago

thread_pthread.c: get current main thread stack size

  • thread_pthread.c: get current main thread stack size, which may be expanded than allocated size at initialization, by rlimit(). [Bug #9454]

Revision 44715
Added by Nobuyoshi Nakada over 1 year ago

thread_pthread.c: cast to size_t

  • thread_pthread.c (ruby_stack_overflowed_p): range of rlim_cur may be larger than size_t. [Bug #9454]

Revision 44715
Added by Nobuyoshi Nakada over 1 year ago

thread_pthread.c: cast to size_t

  • thread_pthread.c (ruby_stack_overflowed_p): range of rlim_cur may be larger than size_t. [Bug #9454]

Revision 44725
Added by Yui NARUSE over 1 year ago

  • thread_pthread.c: rlimit is only available on Linux. At least r44712 breaks FreeBSD. [Bug #9454]

Revision 44725
Added by Yui NARUSE over 1 year ago

  • thread_pthread.c: rlimit is only available on Linux. At least r44712 breaks FreeBSD. [Bug #9454]

Revision 44726
Added by Nobuyoshi Nakada over 1 year ago

thread_pthread.c: use get_stack

  • thread_pthread.c (ruby_init_stack, ruby_stack_overflowed_p): place get_stack above others to get stack boundary information. [Bug #9454]

Revision 44726
Added by Nobuyoshi Nakada over 1 year ago

thread_pthread.c: use get_stack

  • thread_pthread.c (ruby_init_stack, ruby_stack_overflowed_p): place get_stack above others to get stack boundary information. [Bug #9454]

Revision 46468
Added by Tomoyuki Chikanaga about 1 year ago

merge revision(s) r44712,r44715,r44716,r44722,r44725,r44726,r44753: [Backport #9454] [Backport #9828]

* thread_pthread.c: get current main thread stack size, which may
  be expanded than allocated size at initialization, by rlimit().
   [Bug #9454]

* thread_pthread.c: rlimit is only available on Linux.
  At least r44712 breaks FreeBSD.
   [Bug #9454]

* thread_pthread.c (ruby_init_stack, ruby_stack_overflowed_p):
  place get_stack above others to get stack boundary information.
   [Bug #9454]

Revision 46667
Added by Usaku NAKAMURA about 1 year ago

merge revision(s) 44712,44715,44716,44722,44725,44726,44753: [Backport #9454] [Backport #9945]

* thread_pthread.c: get current main thread stack size, which may
  be expanded than allocated size at initialization, by rlimit().
   [Bug #9454]

* thread_pthread.c: get current main thread stack size, which may
  be expanded than allocated size at initialization, by rlimit().
   [Bug #9454]

* thread_pthread.c: rlimit is only available on Linux.
  At least r44712 breaks FreeBSD.
   [Bug #9454]

* thread_pthread.c (ruby_init_stack, ruby_stack_overflowed_p):
  place get_stack above others to get stack boundary information.
   [Bug #9454]

* thread_pthread.c (ruby_init_stack, ruby_stack_overflowed_p):
  place get_stack above others to get stack boundary information.
   [Bug #9454]

Revision 46672
Added by Usaku NAKAMURA about 1 year ago

revert r46667 and r46669 because they introduced SEGV on CentOS.
see [Bug #9454] [Bug #9945]

History

#1 Updated by Kyrylo Silin over 1 year ago

Here's the log with the segfault.

#2 Updated by Nobuyoshi Nakada over 1 year ago

Seems an infinite recursion, obviously.

#3 Updated by Kyrylo Silin over 1 year ago

Sure. As far as I understand it should raise a SystemStackError instead of segfaulting (that's how it worked before v2.1.0p0). If you could give me a hint, which file is relevant, I would probably come up with a patch (I don't promise anything, because I'm not very good at C and Ruby internals).

#4 Updated by Nobuyoshi Nakada over 1 year ago

At first glan.ce, it occurred in INSNS_DISPATCH() macro.
Considering that the second case works fine, maybe recovery jump fails.

#5 Updated by Nobuyoshi Nakada over 1 year ago

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

Applied in changeset r44712.


thread_pthread.c: get current main thread stack size

  • thread_pthread.c: get current main thread stack size, which may be expanded than allocated size at initialization, by rlimit(). [Bug #9454]

#6 Updated by Eric Wong over 1 year ago

Btw, TestException#test_machine_stackoverflow_by_define_method fails
on an ancient glibc 2.5-42.el5_4.3 (CentOS 5.4 x86_64).

I think this is a bug in pthread_getattr_np when it is run on the main
thread. I'm not sure how many people care about a platform this old,
though; and I've been meaning to upgrade that anyways.

#7 Updated by Rei Odaira over 1 year ago

FYI, TestException#test_machine_stackoverflow_by_define_method fails on my environment, too: Linux 2.6.32-71.el6.x86_64 and glibc 2.12-1.7.el6.

$ ruby -v
ruby 2.2.0dev (2014-04-01 trunk 45498) [x86_64-linux]

The problem is that pthread_attr_getstack() and even getrlimit() return 0xa00000 (= 10 MB) as a max stack size, but the actual stack size at the time of the stack overflow seems bigger by about 2 MB, according to /proc/PID/maps.

7fe1f7664000-7fe1f7afe000 rw-p 00000000 00:00 0                          [heap]
7fffc0836000-7fffc1435000 rw-p 00000000 00:00 0                          [stack]
7fffc15d4000-7fffc15d5000 r-xp 00000000 00:00 0                          [vdso]

0x7fffc1435000 - 0x7fffc1435000 = 0xbff000 (= ~12 MB). As a result, the address causing SIGSEGV is not considered as part of the stack.

#8 Updated by Nobuyoshi Nakada about 1 year ago

  • Duplicated by Backport #9828: Segfault instead of stack overflow added

#9 Updated by Nobuyoshi Nakada about 1 year ago

  • Duplicated by Bug #9945: Segmentation fault when defining recursive method added

#10 Updated by Nobuyoshi Nakada about 1 year ago

  • Backport changed from 1.9.3: UNKNOWN, 2.0.0: UNKNOWN, 2.1: UNKNOWN to 1.9.3: UNKNOWN, 2.0.0: UNKNOWN, 2.1: REQUIRED

#11 Updated by Tomoyuki Chikanaga about 1 year ago

  • Backport changed from 1.9.3: UNKNOWN, 2.0.0: UNKNOWN, 2.1: REQUIRED to 1.9.3: UNKNOWN, 2.0.0: UNKNOWN, 2.1: DONE

r44712, r44715, r44716, r44722, r44725, r44726 and r44753 were backported into ruby_2_1 branch at r46468.

#12 Updated by Usaku NAKAMURA about 1 year ago

  • Backport changed from 1.9.3: UNKNOWN, 2.0.0: UNKNOWN, 2.1: DONE to 1.9.3: UNKNOWN, 2.0.0: DONE, 2.1: DONE

backported into ruby_2_0_0 at r46667 and r46669.

#13 Updated by Usaku NAKAMURA about 1 year ago

  • Backport changed from 1.9.3: UNKNOWN, 2.0.0: DONE, 2.1: DONE to 1.9.3: UNKNOWN, 2.0.0: REQUIRED, 2.1: DONE

... but reverted because it introduced SEGV on CentOS.
Maybe somthing is missed, but I wasn't able to find it.

#14 Updated by Tomoyuki Chikanaga 11 months ago

  • Duplicated by Bug #10218: 手続きを再帰するとSegmentation faultが発生する added

#15 Updated by Nobuyoshi Nakada 5 months ago

  • Duplicated by Bug #10955: invoke_block_from_c segfault added

Also available in: Atom PDF