35
35
# include <sys/types.h>
36
36
# endif
37
37
#endif /* ZEND_WIN32 */
38
- #if defined(__linux__ ) || defined(__FreeBSD__ ) || defined(__APPLE__ ) || defined(__OpenBSD__ ) || defined(__NetBSD__ ) || defined(__DragonFly__ )
38
+ #if defined(__linux__ ) || defined(__FreeBSD__ ) || defined(__APPLE__ ) || \
39
+ defined(__OpenBSD__ ) || defined(__NetBSD__ ) || defined(__DragonFly__ ) || \
40
+ defined(__sun )
39
41
# include <pthread.h>
40
42
#endif
41
43
#if defined(__FreeBSD__ ) || defined(__DragonFly__ )
@@ -61,6 +63,12 @@ typedef int boolean_t;
61
63
#ifdef __linux__
62
64
#include <sys/syscall.h>
63
65
#endif
66
+ #ifdef __sun
67
+ #define _STRUCTURED_PROC 1
68
+ #include <sys/lwp.h>
69
+ #include <sys/procfs.h>
70
+ #include <libproc.h>
71
+ #endif
64
72
65
73
#ifdef ZEND_CHECK_STACK_LIMIT
66
74
@@ -650,6 +658,125 @@ static bool zend_call_stack_get_netbsd(zend_call_stack *stack)
650
658
}
651
659
#endif /* defined(__NetBSD__) */
652
660
661
+ #if defined(__sun )
662
+ static bool zend_call_stack_get_solaris_pthread (zend_call_stack * stack )
663
+ {
664
+ pthread_attr_t attr ;
665
+ int error ;
666
+ void * addr ;
667
+ size_t max_size , guard_size ;
668
+
669
+ error = pthread_attr_get_np (pthread_self (), & attr );
670
+ if (error ) {
671
+ return false;
672
+ }
673
+
674
+ error = pthread_attr_getstack (& attr , & addr , & max_size );
675
+ if (error ) {
676
+ return false;
677
+ }
678
+
679
+ error = pthread_attr_getguardsize (& attr , & guard_size );
680
+ if (error ) {
681
+ return false;
682
+ }
683
+
684
+ addr = (char * )addr + guard_size ;
685
+ max_size -= guard_size ;
686
+
687
+ stack -> base = (char * )addr + max_size ;
688
+ stack -> max_size = max_size ;
689
+
690
+ return true;
691
+ }
692
+
693
+ static bool zend_call_stack_get_solaris_proc_maps (zend_call_stack * stack )
694
+ {
695
+ char buffer [4096 ];
696
+ uintptr_t addr_on_stack = (uintptr_t )& buffer ;
697
+ bool found = false, r = false;
698
+ struct ps_prochandle * proc ;
699
+ prmap_t * map , * orig ;
700
+ struct rlimit rlim ;
701
+ char path [PATH_MAX ];
702
+ size_t size ;
703
+ ssize_t len ;
704
+ pid_t pid ;
705
+ int error , fd ;
706
+
707
+ pid = getpid ();
708
+ proc = Pgrab (pid , PGRAB_RDONLY , & error );
709
+ if (!proc ) {
710
+ return false;
711
+ }
712
+
713
+ size = (1 << 20 );
714
+ snprintf (path , sizeof (path ), "/proc/%d/map" , pid );
715
+
716
+ if ((fd = open (path , O_RDONLY )) == -1 ) {
717
+ Prelease (proc , 0 );
718
+ return false;
719
+ }
720
+
721
+ orig = malloc (size );
722
+ if (!orig ) {
723
+ Prelease (proc , 0 );
724
+ close (fd );
725
+ return false;
726
+ }
727
+
728
+ while (size > 0 && (len = pread (fd , orig , size , 0 )) == size ) {
729
+ prmap_t * tmp ;
730
+ size <<= 1 ;
731
+ tmp = realloc (orig , size );
732
+ if (!tmp ) {
733
+ goto end ;
734
+ }
735
+ orig = tmp ;
736
+ }
737
+
738
+ for (map = orig ; len > 0 ; ++ map ) {
739
+ if ((uintptr_t )map -> pr_vaddr <= addr_on_stack && (uintptr_t )map -> pr_vaddr + map -> pr_size >= addr_on_stack ) {
740
+ found = true;
741
+ break ;
742
+ }
743
+ len -= sizeof (* map );
744
+ }
745
+
746
+ if (!found ) {
747
+ goto end ;
748
+ }
749
+
750
+ error = getrlimit (RLIMIT_STACK , & rlim );
751
+ if (error || rlim .rlim_cur == RLIM_INFINITY ) {
752
+ goto end ;
753
+ }
754
+
755
+ stack -> base = (void * )map -> pr_vaddr + map -> pr_size ;
756
+ stack -> max_size = rlim .rlim_cur ;
757
+ r = true;
758
+
759
+ end :
760
+ free (orig );
761
+ Prelease (proc , 0 );
762
+ close (fd );
763
+ return r ;
764
+ }
765
+
766
+ static bool zend_call_stack_get_solaris (zend_call_stack * stack )
767
+ {
768
+ if (_lwp_self () == 1 ) {
769
+ return zend_call_stack_get_solaris_proc_maps (stack );
770
+ }
771
+ return zend_call_stack_get_solaris_pthread (stack );
772
+ }
773
+ #else
774
+ static bool zend_call_stack_get_solaris (zend_call_stack * stack )
775
+ {
776
+ return false;
777
+ }
778
+ #endif /* defined(__sun) */
779
+
653
780
/** Get the stack information for the calling thread */
654
781
ZEND_API bool zend_call_stack_get (zend_call_stack * stack )
655
782
{
@@ -681,6 +808,10 @@ ZEND_API bool zend_call_stack_get(zend_call_stack *stack)
681
808
return true;
682
809
}
683
810
811
+ if (zend_call_stack_get_solaris (stack )) {
812
+ return true;
813
+ }
814
+
684
815
return false;
685
816
}
686
817
0 commit comments