-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
wrap x_cgo_getstackbound for go1.21 and above
Signed-off-by: lifubang <lifubang@acmcoder.com>
- Loading branch information
Showing
1 changed file
with
73 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
//go:build linux && !gccgo && go1.21 | ||
// +build linux,!gccgo,go1.21 | ||
|
||
package nsenter | ||
|
||
// Since Go 1.21 </~https://github.com/golang/go/commit/c426c87012b5e>, the Go | ||
// runtime will try to call pthread_getattr_np(pthread_self()). This causes | ||
// issues with nsexec and requires backward compatibility with older versions | ||
// of the glibc. | ||
|
||
/* | ||
#cgo LDFLAGS: -Wl,--wrap=x_cgo_getstackbound | ||
#ifndef _GNU_SOURCE | ||
# define _GNU_SOURCE | ||
#endif | ||
#include <stdint.h> | ||
#include <stdbool.h> | ||
#include <pthread.h> | ||
typedef uintptr_t uintptr; | ||
void | ||
__wrap_x_cgo_getstackbound(uintptr bounds[2]) | ||
{ | ||
pthread_attr_t attr; | ||
void *addr; | ||
size_t size; | ||
bool noinit; | ||
int err; | ||
#if defined(__GLIBC__) || (defined(__sun) && !defined(__illumos__)) | ||
// pthread_getattr_np is a GNU extension supported in glibc. | ||
// Solaris is not glibc but does support pthread_getattr_np | ||
// (and the fallback doesn't work...). Illumos does not. | ||
err = pthread_getattr_np(pthread_self(), &attr); // GNU extension | ||
if (err != 0) { | ||
noinit = true; | ||
goto failback; | ||
} | ||
err = pthread_attr_getstack(&attr, &addr, &size); // low address | ||
if (err != 0) { | ||
goto failback; | ||
} | ||
goto ret; | ||
#elif defined(__illumos__) | ||
pthread_attr_init(&attr); | ||
err = pthread_attr_get_np(pthread_self(), &attr); | ||
if (err != 0) { | ||
goto failback; | ||
} | ||
err = pthread_attr_getstack(&attr, &addr, &size); // low address | ||
if (err != 0) { | ||
goto failback; | ||
} | ||
goto ret; | ||
#endif | ||
failback: | ||
// We don't know how to get the current stacks, so assume they are the | ||
// same as the default stack bounds. | ||
if (!noinit) { | ||
pthread_attr_destroy(&attr); | ||
} | ||
pthread_attr_init(&attr); | ||
pthread_attr_getstacksize(&attr, &size); | ||
addr = __builtin_frame_address(0) + 4096 - size; | ||
ret: | ||
pthread_attr_destroy(&attr); | ||
bounds[0] = (uintptr)addr; | ||
bounds[1] = (uintptr)addr + size; | ||
} | ||
*/ | ||
import "C" |