X7ROOT File Manager
Current Path:
/opt/golang/1.22.0/src/runtime/testdata/testprogcgo
opt
/
golang
/
1.22.0
/
src
/
runtime
/
testdata
/
testprogcgo
/
📁
..
📄
aprof.go
(1.14 KB)
📄
aprof_c.c
(217 B)
📄
bigstack1_windows.c
(379 B)
📄
bigstack_windows.c
(1.2 KB)
📄
bigstack_windows.go
(586 B)
📄
bindm.c
(692 B)
📄
bindm.go
(1.2 KB)
📄
callback.go
(1.86 KB)
📄
catchpanic.go
(993 B)
📄
cgo.go
(1.82 KB)
📄
cgonocallback.c
(236 B)
📄
cgonocallback.go
(629 B)
📄
cgonoescape.go
(1.84 KB)
📄
crash.go
(743 B)
📄
deadlock.go
(509 B)
📄
destructor.c
(459 B)
📄
destructor.go
(442 B)
📄
dll_windows.go
(459 B)
📄
dropm.go
(1.05 KB)
📄
dropm_stub.go
(336 B)
📄
eintr.go
(5.17 KB)
📄
exec.go
(2.1 KB)
📄
gprof.go
(868 B)
📄
gprof_c.c
(700 B)
📄
issue29707.go
(1.15 KB)
📄
lockosthread.c
(301 B)
📄
lockosthread.go
(2.52 KB)
📄
main.go
(651 B)
📄
needmdeadlock.go
(1.83 KB)
📄
numgoroutine.go
(1.91 KB)
📄
panic.c
(239 B)
📄
panic.go
(312 B)
📄
pprof.go
(1.67 KB)
📄
pprof_callback.go
(1.82 KB)
📄
raceprof.go
(1.67 KB)
📄
racesig.go
(1.67 KB)
📄
segv.go
(525 B)
📄
segv_linux.go
(546 B)
📄
sigfwd.go
(1.58 KB)
📄
sigpanic.go
(484 B)
📄
sigstack.go
(2.09 KB)
📄
sigthrow.go
(312 B)
📄
stack_windows.go
(1.1 KB)
📄
stackswitch.c
(3.88 KB)
📄
stackswitch.go
(1.07 KB)
📄
threadpanic.go
(428 B)
📄
threadpanic_unix.c
(435 B)
📄
threadpanic_windows.c
(435 B)
📄
threadpprof.go
(2.54 KB)
📄
threadprof.go
(2.41 KB)
📄
trace.go
(1.15 KB)
📄
trace_unix.c
(688 B)
📄
trace_windows.c
(777 B)
📄
traceback.go
(949 B)
📄
traceback_c.c
(1.21 KB)
📄
tracebackctxt.go
(2.85 KB)
📄
tracebackctxt_c.c
(2.33 KB)
📁
windows
Editing: stackswitch.c
// Copyright 2023 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 unix && !android && !openbsd // Required for darwin ucontext. #define _XOPEN_SOURCE // Required for netbsd stack_t if _XOPEN_SOURCE is set. #define _XOPEN_SOURCE_EXTENDED 1 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #include <assert.h> #include <pthread.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <ucontext.h> // musl libc does not provide getcontext, etc. Skip the test there. // // musl libc doesn't provide any direct detection mechanism. So assume any // non-glibc linux is using musl. // // Note that bionic does not provide getcontext either, but that is skipped via // the android build tag. #if defined(__linux__) && !defined(__GLIBC__) #define MUSL 1 #endif #if defined(MUSL) void callStackSwitchCallbackFromThread(void) { printf("SKIP\n"); exit(0); } #else // Use a stack size larger than the 32kb estimate in // runtime.callbackUpdateSystemStack. This ensures that a second stack // allocation won't accidentally count as in bounds of the first stack #define STACK_SIZE (64ull << 10) static ucontext_t uctx_save, uctx_switch; extern void stackSwitchCallback(void); char *stack2; static void *stackSwitchThread(void *arg) { // Simple test: callback works from the normal system stack. stackSwitchCallback(); // Next, verify that switching stacks doesn't break callbacks. char *stack1 = malloc(STACK_SIZE); if (stack1 == NULL) { perror("malloc"); exit(1); } // Allocate the second stack before freeing the first to ensure we don't get // the same address from malloc. // // Will be freed in stackSwitchThread2. stack2 = malloc(STACK_SIZE); if (stack1 == NULL) { perror("malloc"); exit(1); } if (getcontext(&uctx_switch) == -1) { perror("getcontext"); exit(1); } uctx_switch.uc_stack.ss_sp = stack1; uctx_switch.uc_stack.ss_size = STACK_SIZE; uctx_switch.uc_link = &uctx_save; makecontext(&uctx_switch, stackSwitchCallback, 0); if (swapcontext(&uctx_save, &uctx_switch) == -1) { perror("swapcontext"); exit(1); } if (getcontext(&uctx_switch) == -1) { perror("getcontext"); exit(1); } uctx_switch.uc_stack.ss_sp = stack2; uctx_switch.uc_stack.ss_size = STACK_SIZE; uctx_switch.uc_link = &uctx_save; makecontext(&uctx_switch, stackSwitchCallback, 0); if (swapcontext(&uctx_save, &uctx_switch) == -1) { perror("swapcontext"); exit(1); } free(stack1); return NULL; } static void *stackSwitchThread2(void *arg) { // New thread. Use stack bounds that partially overlap the previous // bounds. needm should refresh the stack bounds anyway since this is a // new thread. // N.B. since we used a custom stack with makecontext, // callbackUpdateSystemStack had to guess the bounds. Its guess assumes // a 32KiB stack. char *prev_stack_lo = stack2 + STACK_SIZE - (32*1024); // New SP is just barely in bounds, but if we don't update the bounds // we'll almost certainly overflow. The SP that // callbackUpdateSystemStack sees already has some data pushed, so it // will be a bit below what we set here. Thus we include some slack. char *new_stack_hi = prev_stack_lo + 128; if (getcontext(&uctx_switch) == -1) { perror("getcontext"); exit(1); } uctx_switch.uc_stack.ss_sp = new_stack_hi - (STACK_SIZE / 2); uctx_switch.uc_stack.ss_size = STACK_SIZE / 2; uctx_switch.uc_link = &uctx_save; makecontext(&uctx_switch, stackSwitchCallback, 0); if (swapcontext(&uctx_save, &uctx_switch) == -1) { perror("swapcontext"); exit(1); } free(stack2); return NULL; } void callStackSwitchCallbackFromThread(void) { pthread_t thread; assert(pthread_create(&thread, NULL, stackSwitchThread, NULL) == 0); assert(pthread_join(thread, NULL) == 0); assert(pthread_create(&thread, NULL, stackSwitchThread2, NULL) == 0); assert(pthread_join(thread, NULL) == 0); } #endif
Upload File
Create Folder