]> Cypherpunks repositories - gostls13.git/commitdiff
runtime/cgo: use frame address to set g0 stack bound
authorIan Lance Taylor <iant@golang.org>
Tue, 8 Aug 2023 19:49:48 +0000 (12:49 -0700)
committerGopher Robot <gobot@golang.org>
Wed, 9 Aug 2023 03:13:11 +0000 (03:13 +0000)
This extends CL 419434 to all Unix targets. Rather than repeating
the code, pull all the similar code into a single function.

CL 419434 description:

For a cgo binary, at startup we set g0's stack bounds using the
address of a local variable (&size) in a C function x_cgo_init and
the stack size from pthread_attr_getstacksize. Normally, &size is
an address within the current stack frame. However, when  it is
compiled with ASAN, it may be instrumented to __asan_stack_malloc_0
and the address may not live in the current stack frame, causing
the stack bound to be set incorrectly, e.g. lo > hi.

Using __builtin_frame_address(0) to get the stack address instead.

Change-Id: I914a09d32c66a79515b6f700be18c690f3c0c77b
Reviewed-on: https://go-review.googlesource.com/c/go/+/517335
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Auto-Submit: Ian Lance Taylor <iant@google.com>

30 files changed:
src/runtime/cgo/gcc_darwin_amd64.c
src/runtime/cgo/gcc_darwin_arm64.c
src/runtime/cgo/gcc_dragonfly_amd64.c
src/runtime/cgo/gcc_freebsd_386.c
src/runtime/cgo/gcc_freebsd_amd64.c
src/runtime/cgo/gcc_freebsd_arm.c
src/runtime/cgo/gcc_freebsd_arm64.c
src/runtime/cgo/gcc_freebsd_riscv64.c
src/runtime/cgo/gcc_libinit.c
src/runtime/cgo/gcc_linux_386.c
src/runtime/cgo/gcc_linux_amd64.c
src/runtime/cgo/gcc_linux_arm.c
src/runtime/cgo/gcc_linux_arm64.c
src/runtime/cgo/gcc_linux_loong64.c
src/runtime/cgo/gcc_linux_mips64x.c
src/runtime/cgo/gcc_linux_mipsx.c
src/runtime/cgo/gcc_linux_riscv64.c
src/runtime/cgo/gcc_linux_s390x.c
src/runtime/cgo/gcc_netbsd_386.c
src/runtime/cgo/gcc_netbsd_amd64.c
src/runtime/cgo/gcc_netbsd_arm.c
src/runtime/cgo/gcc_netbsd_arm64.c
src/runtime/cgo/gcc_openbsd_386.c
src/runtime/cgo/gcc_openbsd_amd64.c
src/runtime/cgo/gcc_openbsd_arm.c
src/runtime/cgo/gcc_openbsd_arm64.c
src/runtime/cgo/gcc_openbsd_mips64.c
src/runtime/cgo/gcc_ppc64x.c
src/runtime/cgo/gcc_solaris_amd64.c
src/runtime/cgo/libcgo_unix.h

index 955b81da0be9dd74360cb5e5ee7c4287773940cf..dda9a1e2d8e08c2ad4cec909c0226d4d3bcb4498 100644 (file)
@@ -14,12 +14,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
 {
-       size_t size;
-
        setg_gcc = setg;
-
-       size = pthread_get_stacksize_np(pthread_self());
-       g->stacklo = (uintptr)&size - size + 4096;
+       _cgo_set_stacklo(g, NULL);
 }
 
 
index 5b77a4294a415ac77a35ebb34e3399c3e9d687f7..f1344de8e19be3f7b85a38abcc2814f22781b317 100644 (file)
@@ -127,12 +127,9 @@ init_working_dir()
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
-       size_t size;
-
        //fprintf(stderr, "x_cgo_init = %p\n", &x_cgo_init); // aid debugging in presence of ASLR
        setg_gcc = setg;
-       size = pthread_get_stacksize_np(pthread_self());
-       g->stacklo = (uintptr)&size - size + 4096;
+       _cgo_set_stacklo(g, NULL);
 
 #if TARGET_OS_IPHONE
        darwin_arm_init_mach_exception_handler();
index 0003414bf8665aba986a510192f2e7918fc62a55..b5ae411d3d2c85fbad1fedba801987b29a30a8df 100644 (file)
@@ -16,14 +16,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 }
 
 void
index 9097a2af9028467f5479c6d0508aa6049c1b6a6b..e56fad6a5b9f2d733f31f1bb295cf8073f5a1c9c 100644 (file)
@@ -16,14 +16,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 }
 
 
index 6071ec39093783c469b99079dc770b0f19f896d7..d3c133fc76aaa497b4cc55354b485724af14655a 100644 (file)
@@ -18,7 +18,6 @@ void
 x_cgo_init(G *g, void (*setg)(void*))
 {
        pthread_attr_t *attr;
-       size_t size;
 
        // Deal with memory sanitizer/clang interaction.
        // See gcc_linux_amd64.c for details.
@@ -27,10 +26,7 @@ x_cgo_init(G *g, void (*setg)(void*))
        if (attr == NULL) {
                fatalf("malloc failed: %s", strerror(errno));
        }
-       pthread_attr_init(attr);
-       pthread_attr_getstacksize(attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(attr);
+       _cgo_set_stacklo(g, attr);
        free(attr);
 }
 
index 5f8997837990617cdbdf509f03e0a3ff56bb0789..af398f83209716796a998a0de31e51289997c1c8 100644 (file)
@@ -27,14 +27,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 }
 
 void
index dd8f888290551a104637f4c4d31307fe05ed17e8..01f6a31c3273b8f1eb2545bbff93165ff56231d7 100644 (file)
@@ -17,14 +17,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 }
 
 void
index 6ce5e656abad959eaf422ecb9910be4961bc44cb..7fe7972d2dcf3140ba4a86b05f68bcf6d52a1142 100644 (file)
@@ -17,14 +17,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 }
 
 void
index 0b2cc25277ccaf50030711b1438ee218bfb3dc48..f6c930209e1d526c73f8bb1615f0a533b3272223 100644 (file)
@@ -82,6 +82,34 @@ _cgo_wait_runtime_init_done(void) {
        return 0;
 }
 
+// _cgo_set_stacklo sets g->stacklo based on the stack size.
+// This is common code called from x_cgo_init, which is itself
+// called by rt0_go in the runtime package.
+void _cgo_set_stacklo(G *g, pthread_attr_t *pattr)
+{
+       pthread_attr_t attr;
+       size_t size;
+
+       // pattr can be passed in by the caller; see gcc_linux_amd64.c.
+       if (pattr == NULL) {
+               pattr = &attr;
+       }
+
+       pthread_attr_init(pattr);
+       pthread_attr_getstacksize(pattr, &size);
+
+       g->stacklo = (uintptr)(__builtin_frame_address(0)) - size + 4096;
+
+       // Sanity check the results now, rather than getting a
+       // morestack on g0 crash.
+       if (g->stacklo >= g->stackhi) {
+               fprintf(stderr, "runtime/cgo: bad stack bounds: lo=%p hi=%p\n", (void*)(g->stacklo), (void*)(g->stackhi));
+               abort();
+       }
+
+       pthread_attr_destroy(pattr);
+}
+
 // Store the g into a thread-specific value associated with the pthread key pthread_g.
 // And pthread_key_destructor will dropm when the thread is exiting.
 void x_cgo_bindm(void* g) {
index 0ce93596166961f41f2e3199472b2c9813320fe0..13a5aa90decfeea9861cc926d3f314a490ea8378 100644 (file)
@@ -17,14 +17,8 @@ void (*x_cgo_inittls)(void **tlsg, void **tlsbase) __attribute__((common));
 void
 x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 
        if (x_cgo_inittls) {
                x_cgo_inittls(tlsg, tlsbase);
index fb164c1a1df03ac1c98ed94affff1266c6b30549..34b70e77cac9750244f8a6cbcc6b408643564b4c 100644 (file)
@@ -20,7 +20,6 @@ void
 x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
 {
        pthread_attr_t *attr;
-       size_t size;
 
        /* The memory sanitizer distributed with versions of clang
           before 3.8 has a bug: if you call mmap before malloc, mmap
@@ -42,12 +41,7 @@ x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
        if (attr == NULL) {
                fatalf("malloc failed: %s", strerror(errno));
        }
-       pthread_attr_init(attr);
-       pthread_attr_getstacksize(attr, &size);
-       g->stacklo = (uintptr)__builtin_frame_address(0) - size + 4096;
-       if (g->stacklo >= g->stackhi)
-               fatalf("bad stack bounds: lo=%p hi=%p\n", g->stacklo, g->stackhi);
-       pthread_attr_destroy(attr);
+       _cgo_set_stacklo(g, attr);
        free(attr);
 
        if (x_cgo_inittls) {
index 5e97a9ed314b355ac28294f295abcc6f6e86b30e..6a7e3bea048c803c09f4ed8b772b5f285ee226c3 100644 (file)
@@ -54,14 +54,8 @@ threadentry(void *v)
 void
 x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 
        if (x_cgo_inittls) {
                x_cgo_inittls(tlsg, tlsbase);
index dac45e418be2951b25aa5304f151b978708ee2ca..8b822fe8a31129899c46d4cbe820ae39f8824abe 100644 (file)
@@ -57,7 +57,6 @@ void
 x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
 {
        pthread_attr_t *attr;
-       size_t size;
 
        /* The memory sanitizer distributed with versions of clang
           before 3.8 has a bug: if you call mmap before malloc, mmap
@@ -79,10 +78,7 @@ x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
        if (attr == NULL) {
                fatalf("malloc failed: %s", strerror(errno));
        }
-       pthread_attr_init(attr);
-       pthread_attr_getstacksize(attr, &size);
-       g->stacklo = (uintptr)&size - size + 4096;
-       pthread_attr_destroy(attr);
+       _cgo_set_stacklo(g, attr);
        free(attr);
 
        if (x_cgo_inittls) {
index 96a06eb96018be5ce5c0e7246620e5377b6d2eb1..b7363ccd96104937d7e116c536021c3620ff101a 100644 (file)
@@ -54,14 +54,8 @@ threadentry(void *v)
 void
 x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 
        if (x_cgo_inittls) {
                x_cgo_inittls(tlsg, tlsbase);
index c059fd1255aae3de38e7fbdc6048774c7e576c93..6f4b52e2b0a4014b5d7bffff2552a4f91138d3bb 100644 (file)
@@ -56,14 +56,8 @@ threadentry(void *v)
 void
 x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 
        if (x_cgo_inittls) {
                x_cgo_inittls(tlsg, tlsbase);
index 218b8fd6e1ea46dae0b594eb87221f54d822cdd7..f6470d66dce93c0e75046cb96cfee1e4a3c125f2 100644 (file)
@@ -56,15 +56,9 @@ threadentry(void *v)
 void
 x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
 
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 
        if (x_cgo_inittls) {
                x_cgo_inittls(tlsg, tlsbase);
index 99c2866de42c084d1c5955336412ceeb22dc8f2e..ee4981104a3d623b89e816b370cacbeb00fb42d1 100644 (file)
@@ -54,14 +54,8 @@ threadentry(void *v)
 void
 x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 
        if (x_cgo_inittls) {
                x_cgo_inittls(tlsg, tlsbase);
index bb600482e14d34faf1e1d9656dfb9d8a75252a84..4b9f76c39ef839098013fa4f3c4e661aaa6021d2 100644 (file)
@@ -16,14 +16,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*), void **tlsbase)
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 }
 
 void
index 5495f0fd720093f8761f99725dd362a4ea419d43..b8cb5d0bc95bb94852c84cf82c783c4663d1f4e6 100644 (file)
@@ -15,14 +15,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 }
 
 
index 9f4b031a08954de8cba3ef6b63e6cd6ff17b0600..94ff1f52bf64ea5b533bb6569f9cde24295c3a63 100644 (file)
@@ -15,14 +15,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 }
 
 
index b0c80ea7c444fffcf3e0820688df847b964f59ce..ca370f69c3eead1e609e36433acf6271cdf99c99 100644 (file)
@@ -16,14 +16,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 }
 
 
index 694116ce7098d64fb1e9e726ba4e899af1a3e81a..c6961f5cbe62f716a7f46cb7378f210816254641 100644 (file)
@@ -16,14 +16,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 }
 
 
index 127a1b683baec9e9241fc7cb92bbaaaebfa1f924..092da4a6d24d71e694fd0187d6c9d5dbfee688a2 100644 (file)
@@ -15,14 +15,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 }
 
 void
index 09d2750f3ad8f96c7b31d69262fed414381e4be9..3f0b771c74225b58e840136c6cf26a6c0149fcb3 100644 (file)
@@ -15,14 +15,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 }
 
 void
index 9a5757f0ad3690785ca62ad028288d1ca2e7ace0..2aec207e362ab59c6446db75ff8d958a7583b2eb 100644 (file)
@@ -15,14 +15,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 }
 
 void
index abf9f6660c10ec8b9643a5e708c998697b4304ea..a9af8a2d1fc5e48088102a15a199d73d85cf47d1 100644 (file)
@@ -15,14 +15,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 }
 
 void
index 79f039a373c139c6c4c08eef57adf7acaca18b39..fbf7ceb0c5db95a77ac275552b0a5c7637207f3e 100644 (file)
@@ -15,14 +15,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 }
 
 void
index bfdcf650143e8f5ec91649ee1e0b29a73a3dcd01..98a654957b189a903d6940c3dba1dcec3a5d2cb1 100644 (file)
@@ -18,14 +18,8 @@ static void (*setg_gcc)(void*);
 void
 x_cgo_init(G *g, void (*setg)(void*), void **tlsbase)
 {
-       pthread_attr_t attr;
-       size_t size;
-
        setg_gcc = setg;
-       pthread_attr_init(&attr);
-       pthread_attr_getstacksize(&attr, &size);
-       g->stacklo = (uintptr)&attr - size + 4096;
-       pthread_attr_destroy(&attr);
+       _cgo_set_stacklo(g, NULL);
 }
 
 void
index e89e844b1e0ad30ba76d3af59695391e7ceb0eff..ebd945b2e3b4402390c15a688e781e01933fbe32 100644 (file)
@@ -27,6 +27,13 @@ x_cgo_init(G *g, void (*setg)(void*))
        // See golang.org/issue/12210.
        if(ctx.uc_stack.ss_size < 1024*1024)
                g->stacklo -= 1024*1024 - ctx.uc_stack.ss_size;
+
+       // Sanity check the results now, rather than getting a
+       // morestack on g0 crash.
+       if (g->stacklo >= g->stackhi) {
+               fprintf(stderr, "runtime/cgo: bad stack bounds: lo=%p hi=%p\n", (void*)(g->stacklo), (void*)(g->stackhi));
+               abort();
+       }
 }
 
 void
index a56a366f23ccd97f44ab510559a4dc30ae5e26c6..6d30769542a17964ed4725417b6a5882d23b255a 100644 (file)
@@ -2,6 +2,11 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+/*
+ * Initialize g->stacklo.
+ */
+extern void _cgo_set_stacklo(G *, pthread_attr_t*);
+
 /*
  * Call pthread_create, retrying on EAGAIN.
  */