[ruby-dev:47917] Re: [ruby-changes:32633] nobu:r44712 (trunk): thread_pthread.c: get current main thread stack size

From: KOSAKI Motohiro <kosaki.motohiro@...>
Date: 2014-01-28 01:06:33 UTC
List: ruby-dev #47917
Ruby-devに河岸をうつしました。

On Mon, Jan 27, 2014 at 7:53 AM, nobu <ko1@atdot.net> wrote:
> nobu    2014-01-27 21:53:48 +0900 (Mon, 27 Jan 2014)
>
>   New Revision: 44712
>
>   http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=44712
>
>   Log:
>     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().
>       [ruby-core:60113] [Bug #9454]
>
>   Modified files:
>     trunk/ChangeLog
>     trunk/test/ruby/test_exception.rb
>     trunk/thread_pthread.c
> Index: ChangeLog
> ===================================================================
> --- ChangeLog   (revision 44711)
> +++ ChangeLog   (revision 44712)
> @@ -1,3 +1,15 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
> +Mon Jan 27 21:53:45 2014  Nobuyoshi Nakada  <nobu@ruby-lang.org>
> +
> +       * thread_pthread.c: get current main thread stack size, which may
> +         be expanded than allocated size at initialization, by rlimit().
> +         [ruby-core:60113] [Bug #9454]
> +
> +Mon Jan 27 21:52:55 2014  Nobuyoshi Nakada  <nobu@ruby-lang.org>
> +
> +       * thread_pthread.c: get current main thread stack size, which may
> +         be expanded than allocated size at initialization, by rlimit().
> +         [ruby-core:60113] [Bug #9454]
> +
>  Sat Jan 25 22:17:02 2014  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>
>
>         * README.ja.md, README.md: update the controller address of
> Index: thread_pthread.c
> ===================================================================
> --- thread_pthread.c    (revision 44711)
> +++ thread_pthread.c    (revision 44712)
> @@ -1562,6 +1562,14 @@ ruby_stack_overflowed_p(const rb_thread_ https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L1562
>
>      if (th) {
>         size = th->machine_stack_maxsize;
> +#if defined(HAVE_GETRLIMIT) && MAINSTACKADDR_AVAILABLE
> +       if (pthread_equal(th->thread_id, native_main_thread.id)) {
> +           struct rlimit rlim;
> +           if (getrlimit(RLIMIT_STACK, &rlim) == 0 && rlim.rlim_cur > size) {
> +               size = rlim.rlim_cur;
> +           }
> +       }
> +#endif

これが間違ってることは分かるが、どうしたいのかが分からない。
チケットに一切情報がないのはいつものこととはいえ・・・・・

まず、単純にifdefにRLIMIT_STACKの有無が抜けているというのもあるが、
メインスレッドならRLIM_STACKで取れるというのがLinux固有なので、
それはHAVE_GETRLIMITとかの機能有無じゃなく、ifdef linux でないと
おかしいように思える。

Linuxだとrlim_curがulongでinfinityが-1だからつまりULONG_MAX扱いになって
常にオーバーフロー扱いにならない。
というか RLIM_INFINITY の値はOS依存だから大小比較するまえに
if (rlim.rlim_cur == RLIM_INFINITY) とかないとおかしくないですか?

次に、get_stack()で使っているpthread_getattr_np()はもうちょっと賢いことをやっていて、
/proc/self/mapsみてVMAのサイズを超えないように調整してる。これを避けたのは
たぶん、シグナルコンテキストというのを意識したのだと思うし、それは正しいと
思うのだけど、ちょっとラフすぎる印象。

どうせ current threadとれないときは、get_stack呼んじゃってるんだから、これだったら
メインスレッドのケースも get_stack呼んでしまったほうが誤判定減るように思えます。

チケットに書いてない、OSのバグ情報などありましたら教えて下さい。

In This Thread

Prev Next