aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorqmuntal <quimmuntal@gmail.com>2026-03-19 10:44:39 +0100
committerQuim Muntal <quimmuntal@gmail.com>2026-03-31 12:52:46 -0700
commitfdd485c5f1701dfadb3a74d95c606329ec6463aa (patch)
tree13ee000266f676cbfa0b148cbf24f737f1d67442 /src/runtime
parent14a6bf0e90c0e22dcbf6dcf367604ac1ec627121 (diff)
downloadgo-fdd485c5f1701dfadb3a74d95c606329ec6463aa.tar.xz
runtime/cgo: remove SIGSEGV emulation on iOS
The misc/ios exec wrapper doesn't support lldb since https://go.dev/cl/573175. This means that the SIGSEGV emulation code in the cgo signal handling on iOS is no longer needed, and can be removed. Cq-Include-Trybots: luci.golang.try:gotip-darwin-arm64_26 Change-Id: I39827cb20756e4730352d87cb3514bb6a3f1cee8 Reviewed-on: https://go-review.googlesource.com/c/go/+/756800 Reviewed-by: Junyang Shao <shaojunyang@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/cgo/gcc_ios_arm64.c21
-rw-r--r--src/runtime/cgo/gcc_signal2_ios_arm64.c11
-rw-r--r--src/runtime/cgo/gcc_signal_ios_arm64.c213
-rw-r--r--src/runtime/cgo/gcc_signal_ios_nolldb.c10
-rw-r--r--src/runtime/cgo/libcgo.h10
-rw-r--r--src/runtime/cgo/signal_ios_arm64.go10
-rw-r--r--src/runtime/cgo/signal_ios_arm64.s56
7 files changed, 0 insertions, 331 deletions
diff --git a/src/runtime/cgo/gcc_ios_arm64.c b/src/runtime/cgo/gcc_ios_arm64.c
index 32f517d464..bef2750cd1 100644
--- a/src/runtime/cgo/gcc_ios_arm64.c
+++ b/src/runtime/cgo/gcc_ios_arm64.c
@@ -10,22 +10,8 @@
#include "libcgo.h"
-#include <TargetConditionals.h>
-
-#if TARGET_OS_IPHONE
#include <CoreFoundation/CFBundle.h>
#include <CoreFoundation/CFString.h>
-#endif
-
-#if TARGET_OS_IPHONE
-
-static void
-threadentry_platform(void)
-{
-#if TARGET_OS_IPHONE
- darwin_arm_init_thread_exception_port();
-#endif
-}
// init_working_dir sets the current working directory to the app root.
// By default ios/arm64 processes start in "/".
@@ -87,17 +73,10 @@ init_working_dir()
}
}
-#endif // TARGET_OS_IPHONE
-
static void
init_platform()
{
-#if TARGET_OS_IPHONE
- darwin_arm_init_mach_exception_handler();
- darwin_arm_init_thread_exception_port();
init_working_dir();
-#endif
}
void (*x_cgo_init_platform)(void) = init_platform;
-void (*x_cgo_threadentry_platform)(void) = threadentry_platform;
diff --git a/src/runtime/cgo/gcc_signal2_ios_arm64.c b/src/runtime/cgo/gcc_signal2_ios_arm64.c
deleted file mode 100644
index f8cef54f6a..0000000000
--- a/src/runtime/cgo/gcc_signal2_ios_arm64.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build lldb
-
-// Used by gcc_signal_darwin_arm64.c when doing the test build during cgo.
-// We hope that for real binaries the definition provided by Go will take precedence
-// and the linker will drop this .o file altogether, which is why this definition
-// is all by itself in its own file.
-void __attribute__((weak)) xx_cgo_panicmem(void) {}
diff --git a/src/runtime/cgo/gcc_signal_ios_arm64.c b/src/runtime/cgo/gcc_signal_ios_arm64.c
deleted file mode 100644
index 3872f62de1..0000000000
--- a/src/runtime/cgo/gcc_signal_ios_arm64.c
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Emulation of the Unix signal SIGSEGV.
-//
-// On iOS, Go tests and apps under development are run by lldb.
-// The debugger uses a task-level exception handler to intercept signals.
-// Despite having a 'handle' mechanism like gdb, lldb will not allow a
-// SIGSEGV to pass to the running program. For Go, this means we cannot
-// generate a panic, which cannot be recovered, and so tests fail.
-//
-// We work around this by registering a thread-level mach exception handler
-// and intercepting EXC_BAD_ACCESS. The kernel offers thread handlers a
-// chance to resolve exceptions before the task handler, so we can generate
-// the panic and avoid lldb's SIGSEGV handler.
-//
-// The dist tool enables this by build flag when testing.
-
-//go:build lldb
-
-#include <limits.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <mach/arm/thread_status.h>
-#include <mach/exception_types.h>
-#include <mach/mach.h>
-#include <mach/mach_init.h>
-#include <mach/mach_port.h>
-#include <mach/thread_act.h>
-#include <mach/thread_status.h>
-
-#include "libcgo.h"
-#include "libcgo_unix.h"
-
-void xx_cgo_panicmem(void);
-uintptr_t x_cgo_panicmem = (uintptr_t)xx_cgo_panicmem;
-
-static pthread_mutex_t mach_exception_handler_port_set_mu;
-static mach_port_t mach_exception_handler_port_set = MACH_PORT_NULL;
-
-kern_return_t
-catch_exception_raise(
- mach_port_t exception_port,
- mach_port_t thread,
- mach_port_t task,
- exception_type_t exception,
- exception_data_t code_vector,
- mach_msg_type_number_t code_count)
-{
- kern_return_t ret;
- arm_unified_thread_state_t thread_state;
- mach_msg_type_number_t state_count = ARM_UNIFIED_THREAD_STATE_COUNT;
-
- // Returning KERN_SUCCESS intercepts the exception.
- //
- // Returning KERN_FAILURE lets the exception fall through to the
- // next handler, which is the standard signal emulation code
- // registered on the task port.
-
- if (exception != EXC_BAD_ACCESS) {
- return KERN_FAILURE;
- }
-
- ret = thread_get_state(thread, ARM_UNIFIED_THREAD_STATE, (thread_state_t)&thread_state, &state_count);
- if (ret) {
- fprintf(stderr, "runtime/cgo: thread_get_state failed: %d\n", ret);
- abort();
- }
-
- // Bounce call to sigpanic through asm that makes it look like
- // we call sigpanic directly from the faulting code.
-#ifdef __arm64__
- thread_state.ts_64.__x[1] = thread_state.ts_64.__lr;
- thread_state.ts_64.__x[2] = thread_state.ts_64.__pc;
- thread_state.ts_64.__pc = x_cgo_panicmem;
-#else
- thread_state.ts_32.__r[1] = thread_state.ts_32.__lr;
- thread_state.ts_32.__r[2] = thread_state.ts_32.__pc;
- thread_state.ts_32.__pc = x_cgo_panicmem;
-#endif
-
- if (0) {
- // Useful debugging logic when panicmem is broken.
- //
- // Sends the first SIGSEGV and lets lldb catch the
- // second one, avoiding a loop that locks up iOS
- // devices requiring a hard reboot.
- fprintf(stderr, "runtime/cgo: caught exc_bad_access\n");
- fprintf(stderr, "__lr = %llx\n", thread_state.ts_64.__lr);
- fprintf(stderr, "__pc = %llx\n", thread_state.ts_64.__pc);
- static int pass1 = 0;
- if (pass1) {
- return KERN_FAILURE;
- }
- pass1 = 1;
- }
-
- ret = thread_set_state(thread, ARM_UNIFIED_THREAD_STATE, (thread_state_t)&thread_state, state_count);
- if (ret) {
- fprintf(stderr, "runtime/cgo: thread_set_state failed: %d\n", ret);
- abort();
- }
-
- return KERN_SUCCESS;
-}
-
-void
-darwin_arm_init_thread_exception_port()
-{
- // Called by each new OS thread to bind its EXC_BAD_ACCESS exception
- // to mach_exception_handler_port_set.
- int ret;
- mach_port_t port = MACH_PORT_NULL;
-
- ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
- if (ret) {
- fprintf(stderr, "runtime/cgo: mach_port_allocate failed: %d\n", ret);
- abort();
- }
- ret = mach_port_insert_right(
- mach_task_self(),
- port,
- port,
- MACH_MSG_TYPE_MAKE_SEND);
- if (ret) {
- fprintf(stderr, "runtime/cgo: mach_port_insert_right failed: %d\n", ret);
- abort();
- }
-
- ret = thread_set_exception_ports(
- mach_thread_self(),
- EXC_MASK_BAD_ACCESS,
- port,
- EXCEPTION_DEFAULT,
- THREAD_STATE_NONE);
- if (ret) {
- fprintf(stderr, "runtime/cgo: thread_set_exception_ports failed: %d\n", ret);
- abort();
- }
-
- ret = pthread_mutex_lock(&mach_exception_handler_port_set_mu);
- if (ret) {
- fprintf(stderr, "runtime/cgo: pthread_mutex_lock failed: %d\n", ret);
- abort();
- }
- ret = mach_port_move_member(
- mach_task_self(),
- port,
- mach_exception_handler_port_set);
- if (ret) {
- fprintf(stderr, "runtime/cgo: mach_port_move_member failed: %d\n", ret);
- abort();
- }
- ret = pthread_mutex_unlock(&mach_exception_handler_port_set_mu);
- if (ret) {
- fprintf(stderr, "runtime/cgo: pthread_mutex_unlock failed: %d\n", ret);
- abort();
- }
-}
-
-static void*
-mach_exception_handler(void *port)
-{
- // Calls catch_exception_raise.
- extern boolean_t exc_server();
- mach_msg_server(exc_server, 2048, (mach_port_t)(uintptr_t)port, 0);
- abort(); // never returns
-}
-
-void
-darwin_arm_init_mach_exception_handler()
-{
- pthread_mutex_init(&mach_exception_handler_port_set_mu, NULL);
-
- // Called once per process to initialize a mach port server, listening
- // for EXC_BAD_ACCESS thread exceptions.
- int ret;
- pthread_t thr = NULL;
- pthread_attr_t attr;
- sigset_t ign, oset;
-
- ret = mach_port_allocate(
- mach_task_self(),
- MACH_PORT_RIGHT_PORT_SET,
- &mach_exception_handler_port_set);
- if (ret) {
- fprintf(stderr, "runtime/cgo: mach_port_allocate failed for port_set: %d\n", ret);
- abort();
- }
-
- // Block all signals to the exception handler thread
- sigfillset(&ign);
- pthread_sigmask(SIG_SETMASK, &ign, &oset);
-
- // Start a thread to handle exceptions.
- uintptr_t port_set = (uintptr_t)mach_exception_handler_port_set;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- ret = _cgo_try_pthread_create(&thr, &attr, mach_exception_handler, (void*)port_set);
-
- pthread_sigmask(SIG_SETMASK, &oset, nil);
-
- if (ret) {
- fprintf(stderr, "runtime/cgo: pthread_create failed: %d\n", ret);
- abort();
- }
- pthread_attr_destroy(&attr);
-}
diff --git a/src/runtime/cgo/gcc_signal_ios_nolldb.c b/src/runtime/cgo/gcc_signal_ios_nolldb.c
deleted file mode 100644
index 9ddc37a013..0000000000
--- a/src/runtime/cgo/gcc_signal_ios_nolldb.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !lldb && ios && arm64
-
-#include <stdint.h>
-
-void darwin_arm_init_thread_exception_port() {}
-void darwin_arm_init_mach_exception_handler() {}
diff --git a/src/runtime/cgo/libcgo.h b/src/runtime/cgo/libcgo.h
index ae0542df36..24475b7c43 100644
--- a/src/runtime/cgo/libcgo.h
+++ b/src/runtime/cgo/libcgo.h
@@ -86,16 +86,6 @@ void crosscall1(void (*fn)(void), void (*setg_gcc)(void*), void *g);
void fatalf(const char* format, ...) __attribute__ ((noreturn));
/*
- * Registers the current mach thread port for EXC_BAD_ACCESS processing.
- */
-void darwin_arm_init_thread_exception_port(void);
-
-/*
- * Starts a mach message server processing EXC_BAD_ACCESS.
- */
-void darwin_arm_init_mach_exception_handler(void);
-
-/*
* The cgo traceback callback. See runtime.SetCgoTraceback.
*/
struct cgoTracebackArg {
diff --git a/src/runtime/cgo/signal_ios_arm64.go b/src/runtime/cgo/signal_ios_arm64.go
deleted file mode 100644
index 3425c448c4..0000000000
--- a/src/runtime/cgo/signal_ios_arm64.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package cgo
-
-import _ "unsafe"
-
-//go:cgo_export_static xx_cgo_panicmem xx_cgo_panicmem
-func xx_cgo_panicmem()
diff --git a/src/runtime/cgo/signal_ios_arm64.s b/src/runtime/cgo/signal_ios_arm64.s
deleted file mode 100644
index 1ae00d13f3..0000000000
--- a/src/runtime/cgo/signal_ios_arm64.s
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// xx_cgo_panicmem is the entrypoint for SIGSEGV as intercepted via a
-// mach thread port as EXC_BAD_ACCESS. As the segfault may have happened
-// in C code, we first need to load_g then call xx_cgo_panicmem.
-//
-// R1 - LR at moment of fault
-// R2 - PC at moment of fault
-TEXT xx_cgo_panicmem(SB),NOSPLIT|NOFRAME,$0
- // If in external C code, we need to load the g register.
- BL runtime·load_g(SB)
- CMP $0, g
- BNE ongothread
-
- // On a foreign thread.
- // TODO(crawshaw): call badsignal
- MOVD.W $0, -16(RSP)
- MOVW $139, R1
- MOVW R1, 8(RSP)
- B runtime·exit(SB)
-
-ongothread:
- // Trigger a SIGSEGV panic.
- //
- // The goal is to arrange the stack so it looks like the runtime
- // function sigpanic was called from the PC that faulted. It has
- // to be sigpanic, as the stack unwinding code in traceback.go
- // looks explicitly for it.
- //
- // To do this we call into runtime·setsigsegv, which sets the
- // appropriate state inside the g object. We give it the faulting
- // PC on the stack, then put it in the LR before calling sigpanic.
-
- // Build a 32-byte stack frame for us for this call.
- // Saved LR (none available) is at the bottom,
- // then the PC argument for setsigsegv,
- // then a copy of the LR for us to restore.
- MOVD.W $0, -32(RSP)
- MOVD R1, 8(RSP)
- MOVD R2, 16(RSP)
- BL runtime·setsigsegv(SB)
- MOVD 8(RSP), R1
- MOVD 16(RSP), R2
-
- // Build a 16-byte stack frame for the simulated
- // call to sigpanic, by taking 16 bytes away from the
- // 32-byte stack frame above.
- // The saved LR in this frame is the LR at time of fault,
- // and the LR on entry to sigpanic is the PC at time of fault.
- MOVD.W R1, 16(RSP)
- MOVD R2, R30
- B runtime·sigpanic(SB)