Issue #12118 has been updated by Yui NARUSE.

Backport changed from 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN to 2.1: REQUIRED, 2.2: REQUIRED, 2.3: REQUIRED

As far as I understand, the fix should be following:

```diff
diff --git a/thread_pthread.c b/thread_pthread.c
index ef43b36..1fdf3f5 100644
--- a/thread_pthread.c
+++ b/thread_pthread.c
@@ -693,17 +693,31 @@ reserve_stack(volatile char *limit, size_t size)
        const volatile char *end = buf + sizeof(buf);
        limit += size;
        if (limit > end) {
-           size = limit - end;
-           limit = alloca(size);
-           limit[stack_check_margin+size-1] = 0;
+           /* |<-bottom (=limit(a))                                     top->|
+            * | .. |<-buf 256B |<-end                          | stack check |
+            * |  256B  |              =size=                   | margin (4KB)|
+            * |              =size=         limit(b)->|  256B  |             |
+            * |                |       alloca(sz)     |        |             |
+            * | .. |<-buf      |<-limit(c)    [sz-1]->0>       |             |
+            */
+           size_t sz = limit - end;
+           limit = alloca(sz);
+           limit[sz-1] = 0;
        }
     }
     else {
        limit -= size;
        if (buf > limit) {
-           limit = alloca(buf - limit);
-           limit[0] = 0; /* ensure alloca is called */
-           limit -= stack_check_margin;
+           /* |<-top (=limit(a))                                     bottom->|
+            * | .. | 256B buf->|                               | stack check |
+            * |  256B  |              =size=                   | margin (4KB)|
+            * |              =size=         limit(b)->|  256B  |             |
+            * |                |       alloca(sz)     |        |             |
+            * | .. |      buf->|           limit(c)-><0>       |             |
+            */
+           size_t sz = buf - limit;
+           limit = alloca(sz);
+           limit[0] = 0;
        }
     }
 }
```

----------------------------------------
Bug #12118: ruby2.3: Segfaults on m68k due to improper stack allocation
https://bugs.ruby-lang.org/issues/12118#change-57662

* Author: John Paul Adrian Glaubitz
* Status: Open
* Priority: Normal
* Assignee: 
* ruby -v: 
* Backport: 2.1: REQUIRED, 2.2: REQUIRED, 2.3: REQUIRED
----------------------------------------
Hello!

On Motorola 680x0, ruby2.2 and ruby2.3 segfault when running the Ruby interpretor:

./miniruby -I./lib -I. -I.ext/common  ./tool/runruby.rb --extout=.ext  -- --disable-gems -r./m68k-linux-gnu-fake ./tool/rbinstall.rb --make="/usr/bin/make" --dest-dir="/<<PKGBUILDDIR>>/debian/tmp" --extout=".ext" --mflags="-w" --make-flags="w -- DESTDIR=/<<PKGBUILDDIR>>/debian/tmp" --data-mode=0644 --prog-mode=0755 --installed-list .installed.list --mantype="doc"
installing binary commands:   /usr/bin
/<<PKGBUILDDIR>>/lib/fileutils.rb:250: [BUG] Segmentation fault at 0x5f583332
ruby 2.3.0p0 (2015-12-25) [m68k-linux-gnu]

This happens while building ruby2.3 on Debian, for example [1].

Andreas Schwab has already investigated into this issue and he came up with the following patch for ruby2.2 [2]:

```diff
Index: ruby-2.2.3/thread_pthread.c
===================================================================
--- ruby-2.2.3.orig/thread_pthread.c
+++ ruby-2.2.3/thread_pthread.c
@@ -678,15 +678,14 @@ reserve_stack(volatile char *limit, size
 	limit += size;
 	if (limit > end) {
 	    size = limit - end;
-	    limit = alloca(size);
+	    limit = alloca(stack_check_margin+size);
 	    limit[stack_check_margin+size-1] = 0;
 	}
     }
     else {
 	limit -= size;
 	if (buf > limit) {
-	    limit = alloca(buf - limit);
-	    limit -= stack_check_margin;
+	    limit = alloca(buf - limit + stack_check_margin);
 	    limit[0] = 0;
 	}
     }
```

The same patch works fine on ruby2.3, I although I had to modify it so it still applies the same way in ruby2.3.
The bug can be reproduced in a qemu-m68k chroot environment which can be set up quite easily [3].

It would be very important for Debian's Motorola 680x0 port to get this issue fixed.

Thanks,
Adrian

> [1] https://buildd.debian.org/status/fetch.php?pkg=ruby2.3&arch=m68k&ver=2.3.0-2&stamp=1455092994
> [2] https://lists.debian.org/debian-68k/2015/11/msg00057.html
> [3] https://wiki.debian.org/M68k/sbuildQEMU



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>