Project

General

Profile

Actions

Bug #5139

closed

sigsegv のスタックオーバフロー

Added by nagachika (Tomoyuki Chikanaga) over 12 years ago. Updated over 12 years ago.

Status:
Closed
Target version:
ruby -v:
-
Backport:
[ruby-dev:44315]

Description

現在の trunk が Linux で test_segv_test(TestRubyOptions) が Failure になります。

$ ruby -e 'Process.kill :SEGV, $$'

のように実行すると表示されるはずのバックトレースや LOADED FEATURES の情報が表示されないためです。

おそらく r32751 からだと思うのですが、手元の環境(Ubuntu 10.4, Kernel 2.6.32-33-generic, gcc 4.4.3) では
どうやら sigsegv() から呼ばれている rb_vm_bugreport() で sigaltstack で設定したシグナルハンドラ用スタックを
オーバフローして、シグナルハンドラ内で再度 SEGV していると思います。

以下 gdb での実行の抜粋
(gdb) run -e 'Process.kill 11, $$'
Program received signal SIGSEGV, Segmentation fault.
0x0012d422 in __kernel_vsyscall ()
(gdb) c
Continuing.
-e:1: [BUG] Segmentation fault
ruby 1.9.4dev (2011-08-01 trunk 32793) [i686-linux]
------------ snip -----------

  • Loaded features:

Program received signal SIGSEGV, Segmentation fault.
0x08150864 in rb_vm_bugreport () at ../ruby/vm_dump.c:834
834 for (i=0; i<RARRAY_LEN(vm->loaded_features); i++) {
(gdb) p ruby_current_thread->altstack
$5 = (void *) 0x8221ab8
(gdb) p $esp
$6 = (void *) 0x8220560
(gdb) p $esp - ruby_current_thread->altstack
$7 = -5464
(gdb) up
#1 0x08187095 in report_bug (file=0x82480b0 "-e", line=1,
fmt=0x81c3bcb "Segmentation fault", args=0x8222714 "\263\063")
at ../ruby/error.c:265
265 rb_vm_bugreport();
(gdb) p (char *)$esp - (char *)ruby_current_thread->altstack
$15 = -5144
(gdb) up
#2 0x08187121 in rb_bug (fmt=0x81c3bcb "Segmentation fault")
at ../ruby/error.c:284
284 report_bug(file, line, fmt, args);
(gdb) p (char *)$esp - (char *)ruby_current_thread->altstack
$16 = 3112

$esp と ruby_current_thread->altstack の関係をみてオーバフローではないかと思ったのですがどうでしょう。
なお sigaltstack に渡しているスタックサイズは 4096 です。


Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #7141: ALT_STACK_SIZE is not enoughClosedkosaki (Motohiro KOSAKI)10/11/2012Actions

Updated by nobu (Nobuyoshi Nakada) over 12 years ago

  • Status changed from Open to Assigned
  • Assignee set to nagachika (Tomoyuki Chikanaga)

こちらの環境(debian, 2.6.39-2-amd64, gcc-4.6.1)では再現しないのですが、gdbの結果を見る限りではそのようですね。

Updated by kosaki (Motohiro KOSAKI) over 12 years ago

  • Assignee changed from nagachika (Tomoyuki Chikanaga) to kosaki (Motohiro KOSAKI)
  • Target version changed from 1.9.3 to 1.9.4

えっと、問題のコミットを入れたのはわたしなので、わたしが確認するべきと思います。
担当者を変更します。
また、問題のコミットは193ブランチには入れてないのでターゲットバージョンも変更します。
お手数をおかけして申し訳ありません。

Updated by nagachika (Tomoyuki Chikanaga) over 12 years ago

すみませんターゲットバージョンは 1.9.3 にも入ったと勘違いしてました。

それから ALT_STACK_SIZE を (SIGSTKSZ*2) (手元だと 16KB)に戻してやりなおしてみましたところ、
チケットの説明文に書いたような $esp のオーバフローはしていないのに vm_backtrace_each() で SEGV していたので
ちょっと別の問題が(も?)あるようです。

Updated by Anonymous over 12 years ago

すみませんターゲットバージョンは 1.9.3 にも入ったと勘違いしてました。

それから ALT_STACK_SIZE を (SIGSTKSZ*2) (手元だと 16KB)に戻してやりなおしてみましたところ、
チケットの説明文に書いたような $esp のオーバフローはしていないのに vm_backtrace_each() で SEGV していたので
ちょっと別の問題が(も?)あるようです。

中田さんの報告だとディストリ依存があるようなので、テストしたディストリとkernel, glibcのバージョンを
教えてもらえますでしょうか。
最近ちょっと忙しいので遅くなるかもしれませんが見てみます。

Updated by nagachika (Tomoyuki Chikanaga) over 12 years ago

  • Target version changed from 1.9.4 to 1.9.3

試した環境は 2つあります。

A) Ubuntu 10.04.03
$ uname -srvm
Linux 2.6.32-33-generic #70-Ubuntu SMP Thu Jul 7 21:09:46 UTC 2011 i686
$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ /lib/libc.so.6 --version
GNU C Library (Ubuntu EGLIBC 2.11.1-0ubuntu7.8) stable release version 2.11.1, by Roland McGrath et al.
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.4.3.
Compiled on a Linux >>2.6.24-27-server<< system on 2011-01-21.
Available extensions:
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
For bug reporting instructions, please see:
http://www.debian.org/Bugs/.

B) Red Hat Enterprise Linux ES release 4 (Nahant Update 8)
$ uname -srvmp
Linux 2.6.9-89.ELlargesmp #1 SMP Mon Apr 20 10:43:12 EDT 2009 x86_64 x86_64
$ gcc-4.5 --version # configure --with-gcc で gcc-4.5 を指定
gcc-4.5 (GCC) 4.5.1
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ /lib/libc.so.6 --version
GNU C Library stable release version 2.3.4, by Roland McGrath et al.
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 3.4.6 20060404 (Red Hat 3.4.6-10).
Compiled on a Linux 2.4.20 system on 2009-01-09.
Available extensions:
GNU libio by Per Bothner
crypt add-on version 2.1 by Michael Glad and others
linuxthreads-0.10 by Xavier Leroy
The C stubs add-on version 2.1.2.
BIND-8.2.3-T5B
NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk
Glibc-2.0 compatibility add-on by Cristian Gafton
GNU Libidn by Simon Josefsson
libthread_db work sponsored by Alpha Processor Inc
Thread-local storage support included.
For bug reporting instructions, please see:
http://www.gnu.org/software/libc/bugs.html.

それぞれについて -O0 と -O3 でビルドしたもので -e 'Process.kill :SEGV, $$' を実行すると

(A)/-O0 => "[BUG]" まで表示して SEGV
(A)/-O3 => "[BUG]" まで表示して SEGV
(B)/-O0 => 再現せず(最後まで表示して abort で終了)
(B)/-O3 => "C level backtrace information" のバナーまで表示して SEGV

また (B) で ruby_1_9_3 のブランチの HEAD を -O3 でビルドしてみたところ
(B)/-O3, 1.9.3 => "C level backtrace information" のバナーまで表示して SEGV
でした。
やはりスタックサイズだけが原因ではないみたいで 1.9.3 でも発生するのでバージョン 1.9.3 にしておきます。

手が空いたらもうちょっと条件を整理したいですが、とりあえず以上です。

Actions #6

Updated by naruse (Yui NARUSE) over 12 years ago

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

This issue was solved with changeset r32815.
Tomoyuki, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • gc.c (init_heap): allocate sigaltstack after heaps are allocated.
    [ruby-dev:44315] [Bug #5139]

  • vm.c (thread_free): use free because objspace is not ready.

  • vm.c (th_init): use malloc because objspace is not ready.

Updated by naruse (Yui NARUSE) over 12 years ago

  • Status changed from Closed to Assigned

Updated by naruse (Yui NARUSE) over 12 years ago

とりあえず r32815, r32821 にて boron では直ったんですが、chikanagaさんの環境ではどうですかね。
http://www.rubyist.net/~akr/chkbuild/debian/ruby-trunk/recent.html

Updated by akr (Akira Tanaka) over 12 years ago

  • ruby -v changed from ruby 1.9.4dev (2011-08-01 trunk 32793) [i686-linux] to -

2011年8月3日9:00 Yui NARUSE :

とりあえず r32815, r32821 にて boron では直ったんですが、chikanagaさんの環境ではどうですかね。
http://www.rubyist.net/~akr/chkbuild/debian/ruby-trunk/recent.html

この issue 自体とは関係なくてなんですが、recent.html は内容がどんどん変わっていくページなので、
http://www.rubyist.net/~akr/chkbuild/debian/ruby-trunk/log/20110802T231900Z.diff.html.gz
みたいな、変化したところを直接参照しておいた方が、
もし将来調べる羽目になった時に面倒がないんではないかと思います。

[田中 哲][たなか あきら][Tanaka Akira]

Updated by nagachika (Tomoyuki Chikanaga) over 12 years ago

(A) の 32bit マシンでは最新版の trunk で直っていました。
しかし (B) の x86_64 -O3 つきではやはり "C level backtrace information" まで表示して SEGV しています。

Updated by naruse (Yui NARUSE) over 12 years ago

Tomoyuki Chikanaga wrote:

(A) の 32bit マシンでは最新版の trunk で直っていました。
しかし (B) の x86_64 -O3 つきではやはり "C level backtrace information" まで表示して SEGV しています。

B) Red Hat Enterprise Linux ES release 4 (Nahant Update 8) って、r32751 より前ではきちんと動いてました?

Updated by nagachika (Tomoyuki Chikanaga) over 12 years ago

(B) の -O3 では確かに r32749 でも、その前の r32748 でも同じエラーが出ていました。
すみません、(B) の -O3 はしばらく test-all を流していなかったので気がついてませんでしたが、
2011/05/01 の r31399 まで遡ってもまだ発生するので、この環境ではだいぶ前からこの問題があったみたいです。

Updated by kosaki (Motohiro KOSAKI) over 12 years ago

  • Status changed from Assigned to Closed

RHEL4はもうplatform のほうがEOLなので深追いするだけ無駄だと思います。closeしましょう。

Updated by nagachika (Tomoyuki Chikanaga) over 12 years ago

最新 trunk で RHEL4 で2度目の SEGV しているのは backtrace() の中とかなので glibc 古すぎとかかもしれません。

(gdb) where
#0 0x0000003feff07f2c in _Unwind_FindEnclosingFunction ()
from /lib64/libgcc_s.so.1
#1 0x0000003feff08e37 in _Unwind_Backtrace () from /lib64/libgcc_s.so.1
#2 0x0000003fed8db3df in backtrace () from /lib64/tls/libc.so.6
#3 0x0000000000531556 in rb_vm_bugreport () at ../ruby/vm_dump.c:40
#4 0x000000000057b866 in report_bug (file=Variable "file" is not available.
) at ../ruby/error.c:245
#5 0x0000203a313a652d in ?? ()
#6 0x0000000000000000 in ?? ()

ところで r32815 はメインスレッドの altstack を init_head() 後に確保しなおしているようですが、
なぜこれで直るのかというのがわかりません。もうしわけないのですが解説して頂けませんか。

Updated by naruse (Yui NARUSE) over 12 years ago

Tomoyuki Chikanaga wrote:

ところで r32815 はメインスレッドの altstack を init_head() 後に確保しなおしているようですが、
なぜこれで直るのかというのがわかりません。もうしわけないのですが解説して頂けませんか。

なんででしょうねぇ。
力尽くで探索して求めた位置なので、よくわからんです。

結局heapとaltstackの位置関係が変わっているのがキモだとは思うんですが。
なお、メインスレッドしかない場合th_initの方のaltstack確保は必要ないので、
むしろメインスレッドはinit_heap以降じゃないとダメだってのがこれの結論です。

Updated by nagachika (Tomoyuki Chikanaga) over 12 years ago

結局heapとaltstackの位置関係が変わっているのがキモだとは思うんですが。
うーん、ということは altstack の位置が変わったためにスタックオーバフローしてもたまたま実害がなくなって現象が収まったということではないでしょうか。

なぜこんなにスタック使うのかというのを調べてみると、rb_bug() から呼ばれる report_bug() で
char buf[BUFSIZ];
とバッファをスタック上に確保しているためのようでした。
ためしに
static char buf[BUFSIZ];
に変更して r32815 と r32821 を revert したバージョンでやってみても現象は収まりました。(buf を static に宣言していいかちゃんと考察していないので、とりあえず、ですが)

report_bug のスタック消費量を抑えるか、altstack のサイズを拡張するかするのがいいのではないかと思います。

Updated by nagachika (Tomoyuki Chikanaga) over 12 years ago

  • Target version changed from 1.9.3 to 1.9.4

あと 1.9.3 で起きてたのは RHEL4 だけだったのでターゲットバージョンは再度 1.9.4 に戻します。お騒がせしてすみませんでした。

Updated by kosaki (Motohiro KOSAKI) over 12 years ago

  • Status changed from Closed to Assigned

BUFSIZを使ってるのが根本的に間違っているという認識なので、もっと小さくしようと思います。メッセージサイズとなんの関係もない定数じゃないかっ。
ちなみにBUFSIZはMacでは1024, Linuxでは8096のようです。

Actions #19

Updated by kosaki (Motohiro KOSAKI) over 12 years ago

  • Status changed from Assigned to Closed

This issue was solved with changeset r32844.
Tomoyuki, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • error.c (report_bug): use a small message buffer instead of BUFSIZ.
    It is needed for avoiding nested SIGSEGV on Linux.
    Note: BUFSIZ is not proper buffer size. It's unrelated with maximum
    filename length. :-/
    [Bug #5139] [ruby-dev:44315]
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0