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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user