4545# include <sys/user.h>
4646#endif
4747#ifdef __OpenBSD__
48+ typedef int boolean_t ;
49+ # include <tib.h>
4850# include <pthread_np.h>
51+ # include <sys/sysctl.h>
52+ # include <sys/user.h>
4953#endif
5054#ifdef __linux__
5155#include <sys/syscall.h>
@@ -435,8 +439,9 @@ static bool zend_call_stack_get_macos(zend_call_stack *stack)
435439}
436440#endif /* defined(__APPLE__) && defined(HAVE_PTHREAD_GET_STACKADDR_NP) */
437441
442+ #if defined(__OpenBSD__ )
438443#if defined(HAVE_PTHREAD_STACKSEG_NP )
439- static bool zend_call_stack_get_openbsd (zend_call_stack * stack )
444+ static bool zend_call_stack_get_openbsd_pthread (zend_call_stack * stack )
440445{
441446 stack_t ss ;
442447
@@ -450,12 +455,56 @@ static bool zend_call_stack_get_openbsd(zend_call_stack *stack)
450455 return true;
451456}
452457#else
453- static bool zend_call_stack_get_openbsd (zend_call_stack * stack )
458+ static bool zend_call_stack_get_openbsd_pthread (zend_call_stack * stack )
454459{
455460 return false;
456461}
457462#endif /* defined(HAVE_PTHREAD_STACKSEG_NP) */
458463
464+ static bool zend_call_stack_get_openbsd_vm (zend_call_stack * stack )
465+ {
466+ struct _ps_strings ps ;
467+ struct rlimit rlim ;
468+ int mib [2 ] = {CTL_VM , VM_PSSTRINGS };
469+ size_t len = sizeof (ps ), pagesize ;
470+
471+ if (sysctl (mib , 2 , & ps , & len , NULL , 0 ) != 0 ) {
472+ return false;
473+ }
474+
475+ if (getrlimit (RLIMIT_STACK , & rlim ) != 0 ) {
476+ return false;
477+ }
478+
479+ if (rlim .rlim_cur == RLIM_INFINITY ) {
480+ return false;
481+ }
482+
483+ pagesize = sysconf (_SC_PAGE_SIZE );
484+
485+ stack -> base = (void * )((uintptr_t )ps .val + (pagesize - 1 ) & ~(pagesize - 1 ));
486+ stack -> max_size = rlim .rlim_cur - pagesize ;
487+
488+ return true;
489+ }
490+
491+ static bool zend_call_stack_get_openbsd (zend_call_stack * stack )
492+ {
493+ // TIB_THREAD_INITIAL_STACK is private and here we avoid using pthread's api (ie pthread_main_np)
494+ if (!TIB_GET ()-> tib_thread || (TIB_GET ()-> tib_thread_flags & 0x002 ) != 0 ) {
495+ return zend_call_stack_get_openbsd_vm (stack );
496+ }
497+
498+ return zend_call_stack_get_openbsd_pthread (stack );
499+ }
500+
501+ #else
502+ static bool zend_call_stack_get_openbsd (zend_call_stack * stack )
503+ {
504+ return false;
505+ }
506+ #endif /* defined(__OpenBSD__) */
507+
459508/** Get the stack information for the calling thread */
460509ZEND_API bool zend_call_stack_get (zend_call_stack * stack )
461510{
0 commit comments