1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

zend_call_stack support proposal for solaris/illumos. (#12862)

This commit is contained in:
David CARLIER
2023-12-09 14:19:07 +00:00
committed by GitHub
parent 2ffd040ffd
commit 09838f17cb
3 changed files with 138 additions and 1 deletions

View File

@@ -35,7 +35,9 @@
# include <sys/types.h>
# endif
#endif /* ZEND_WIN32 */
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \
defined(__sun)
# include <pthread.h>
#endif
#if defined(__FreeBSD__) || defined(__DragonFly__)
@@ -61,6 +63,12 @@ typedef int boolean_t;
#ifdef __linux__
#include <sys/syscall.h>
#endif
#ifdef __sun
#define _STRUCTURED_PROC 1
#include <sys/lwp.h>
#include <sys/procfs.h>
#include <libproc.h>
#endif
#ifdef ZEND_CHECK_STACK_LIMIT
@@ -650,6 +658,125 @@ static bool zend_call_stack_get_netbsd(zend_call_stack *stack)
}
#endif /* defined(__NetBSD__) */
#if defined(__sun)
static bool zend_call_stack_get_solaris_pthread(zend_call_stack *stack)
{
pthread_attr_t attr;
int error;
void *addr;
size_t max_size, guard_size;
error = pthread_attr_get_np(pthread_self(), &attr);
if (error) {
return false;
}
error = pthread_attr_getstack(&attr, &addr, &max_size);
if (error) {
return false;
}
error = pthread_attr_getguardsize(&attr, &guard_size);
if (error) {
return false;
}
addr = (char *)addr + guard_size;
max_size -= guard_size;
stack->base = (char *)addr + max_size;
stack->max_size = max_size;
return true;
}
static bool zend_call_stack_get_solaris_proc_maps(zend_call_stack *stack)
{
char buffer[4096];
uintptr_t addr_on_stack = (uintptr_t)&buffer;
bool found = false, r = false;
struct ps_prochandle *proc;
prmap_t *map, *orig;
struct rlimit rlim;
char path[PATH_MAX];
size_t size;
ssize_t len;
pid_t pid;
int error, fd;
pid = getpid();
proc = Pgrab(pid, PGRAB_RDONLY, &error);
if (!proc) {
return false;
}
size = (1 << 20);
snprintf(path, sizeof(path), "/proc/%d/map", pid);
if ((fd = open(path, O_RDONLY)) == -1) {
Prelease(proc, 0);
return false;
}
orig = malloc(size);
if (!orig) {
Prelease(proc, 0);
close(fd);
return false;
}
while (size > 0 && (len = pread(fd, orig, size, 0)) == size) {
prmap_t *tmp;
size <<= 1;
tmp = realloc(orig, size);
if (!tmp) {
goto end;
}
orig = tmp;
}
for (map = orig; len > 0; ++map) {
if ((uintptr_t)map->pr_vaddr <= addr_on_stack && (uintptr_t)map->pr_vaddr + map->pr_size >= addr_on_stack) {
found = true;
break;
}
len -= sizeof(*map);
}
if (!found) {
goto end;
}
error = getrlimit(RLIMIT_STACK, &rlim);
if (error || rlim.rlim_cur == RLIM_INFINITY) {
goto end;
}
stack->base = (void *)map->pr_vaddr + map->pr_size;
stack->max_size = rlim.rlim_cur;
r = true;
end:
free(orig);
Prelease(proc, 0);
close(fd);
return r;
}
static bool zend_call_stack_get_solaris(zend_call_stack *stack)
{
if (_lwp_self() == 1) {
return zend_call_stack_get_solaris_proc_maps(stack);
}
return zend_call_stack_get_solaris_pthread(stack);
}
#else
static bool zend_call_stack_get_solaris(zend_call_stack *stack)
{
return false;
}
#endif /* defined(__sun) */
/** Get the stack information for the calling thread */
ZEND_API bool zend_call_stack_get(zend_call_stack *stack)
{
@@ -681,6 +808,10 @@ ZEND_API bool zend_call_stack_get(zend_call_stack *stack)
return true;
}
if (zend_call_stack_get_solaris(stack)) {
return true;
}
return false;
}

View File

@@ -92,6 +92,9 @@ static inline size_t zend_call_stack_default_size(void)
#ifdef __HAIKU__
return 64 * 4096;
#endif
#ifdef __sun
return 8 * 4096;
#endif
return 2 * 1024 * 1024;
}

View File

@@ -656,6 +656,9 @@ PHP_CHECK_FUNC_LIB(nanosleep, rt)
dnl Haiku does not have network api in libc.
PHP_CHECK_FUNC_LIB(setsockopt, network)
dnl Solaris/Illumos for process mapping.
PHP_CHECK_FUNC_LIB(Pgrab, proc)
dnl Check for getaddrinfo, should be a better way, but... Also check for working
dnl getaddrinfo.
AC_CACHE_CHECK([for getaddrinfo], ac_cv_func_getaddrinfo,