Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Zend/Zend.m4
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ AC_CHECK_FUNCS(m4_normalize([
pthread_attr_getstack
pthread_get_stackaddr_np
pthread_getattr_np
pthread_getthrds_np
pthread_stackseg_np
strnlen
]))
Expand Down
68 changes: 67 additions & 1 deletion Zend/zend_call_stack.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
#endif /* ZEND_WIN32 */
#if (defined(HAVE_PTHREAD_GETATTR_NP) && defined(HAVE_PTHREAD_ATTR_GETSTACK)) || \
defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || \
defined(__NetBSD__) || defined(__DragonFly__) || defined(__sun)
defined(__NetBSD__) || defined(__DragonFly__) || defined(__sun) || \
defined(_AIX)
# include <pthread.h>
#endif
#if defined(__FreeBSD__) || defined(__DragonFly__)
Expand Down Expand Up @@ -788,6 +789,67 @@ static bool zend_call_stack_get_solaris(zend_call_stack *stack)
}
#endif /* defined(__sun) */

#if defined(_AIX)
static bool zend_call_stack_get_aix_pthread(zend_call_stack *stack)
{
#ifdef HAVE_PTHREAD_GETTHRDS_NP
pthread_t pt = pthread_self();
struct __pthrdsinfo thread_info;
Comment thread
NattyNarwhal marked this conversation as resolved.
Outdated
/*
* We don't need the register buffer since we only call the function
* on our own thread, and since the register buffer is only used for
* suspended threads...
*/
int regsz = 0;

if (pthread_getthrds_np(&pt, PTHRDSINFO_QUERY_ALL, &thread_info,
sizeof(thread_info), NULL, &regsz)) {
return false;
}

/*
* The top of the stack (stackend) is not page aligned, there's some
* internal stuff above it. Thankfully, we don't need page alignment.
*
* The size is a little weird. The stacksize field is smaller than
* subtracting the bottom (stackaddr) from the top; it's about 0x888
* to 0x1888 above stackaddr.
*
* A somewhat crude diagram is available here:
* https://www.ibm.com/docs/en/aix/7.2.0?topic=tuning-thread-environment-variables
*
* pthread->pt_stk.st_limit is __pi_stackend,
* above that is internal pthread junk close to the end of page
* pthread->pt_stk.st_base is __pi_stackaddr,
* below that is the red zone
*/
Comment thread
NattyNarwhal marked this conversation as resolved.
stack->base = thread_info.__pi_stackend;
Comment thread
NattyNarwhal marked this conversation as resolved.
stack->max_size = thread_info.__pi_stackend - thread_info.__pi_stackaddr;
return true;
#else
/* pthread likely not linked in; default NTS build behaviour */
return false;
#endif
}

static bool zend_call_stack_get_aix(zend_call_stack *stack)
{
/*
* While we could use /proc on AIX (and the implementation basically
* like the Solaris one, as the procfs is similar), it doesn't work on
* PASE. The pthread API works even on the main thread, so we should
* use it when we have pthread linked (always with ZTS, maybe not with
* NTS builds).
*/
return zend_call_stack_get_aix_pthread(stack);
}
#else
static bool zend_call_stack_get_aix(zend_call_stack *stack)
{
return false;
}
#endif /* defined(_AIX) */

/** Get the stack information for the calling thread */
ZEND_API bool zend_call_stack_get(zend_call_stack *stack)
{
Expand Down Expand Up @@ -823,6 +885,10 @@ ZEND_API bool zend_call_stack_get(zend_call_stack *stack)
return true;
}

if (zend_call_stack_get_aix(stack)) {
return true;
}

return false;
}

Expand Down
Loading