[newlib-cygwin] Fix values returned by getrlimit(RLIMIT_STACK)

Corinna Vinschen corinna@sourceware.org
Fri Jun 26 18:42:00 GMT 2015


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=2ecaa3c1769ce1bf2e42d30304903ac8c9a5fbc8

commit 2ecaa3c1769ce1bf2e42d30304903ac8c9a5fbc8
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Fri Jun 26 20:41:54 2015 +0200

    Fix values returned by getrlimit(RLIMIT_STACK)
    
    	* resource.cc (getrlimit): Fix values returned by RLIMIT_STACK.
    	Explain why this had to be changed.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/ChangeLog   |  5 +++++
 winsup/cygwin/resource.cc | 36 ++++++++++++++++++++++++++----------
 2 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 3b492e4..060eb80 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,8 @@
+2015-06-26  Corinna Vinschen  <corinna@vinschen.de>
+
+	* resource.cc (getrlimit): Fix values returned by RLIMIT_STACK.
+	Explain why this had to be changed.
+
 2015-06-23  Ken Brown  <kbrown@cornell.edu>
 
 	* include/cygwin/signal.h (SIGEV_*): Add macros.
diff --git a/winsup/cygwin/resource.cc b/winsup/cygwin/resource.cc
index 27ba4d4..895ba7f 100644
--- a/winsup/cygwin/resource.cc
+++ b/winsup/cygwin/resource.cc
@@ -114,8 +114,6 @@ getrusage (int intwho, struct rusage *rusage_in)
 extern "C" int
 getrlimit (int resource, struct rlimit *rlp)
 {
-  MEMORY_BASIC_INFORMATION m;
-
   __try
     {
       rlp->rlim_cur = RLIM_INFINITY;
@@ -129,14 +127,32 @@ getrlimit (int resource, struct rlimit *rlp)
 	case RLIMIT_AS:
 	  break;
 	case RLIMIT_STACK:
-	  if (!VirtualQuery ((LPCVOID) &m, &m, sizeof m))
-	    debug_printf ("couldn't get stack info, returning def.values. %E");
-	  else
-	    {
-	      rlp->rlim_cur = (rlim_t) &m - (rlim_t) m.AllocationBase;
-	      rlp->rlim_max = (rlim_t) m.BaseAddress + m.RegionSize
-			      - (rlim_t) m.AllocationBase;
-	    }
+	  PTEB teb;
+	  /* 2015-06-26: Originally rlim_cur returned the size of the still
+	     available stack area on the current stack, rlim_max the total size
+	     of the current stack.  Two problems:
+
+	     - Per POSIX, RLIMIT_STACK returns "the maximum size of the initial
+	       thread's stack, in bytes. The implementation does not
+	       automatically grow the stack beyond this limit".
+
+	     - With the implementation of sigaltstack, the current stack is not
+	       necessarily the "initial thread's stack" anymore.  Rather, when
+	       called from a signal handler running on the alternate stack,
+	       RLIMIT_STACK should return the size of the original stack.
+
+	     rlim_cur is now the size of the stack.  For system-provided stacks
+	     it's the size between DeallocationStack and StackBase.  For
+	     application-provided stacks (via pthread_attr_setstack),
+	     DeallocationStack is NULL, but StackLimit points to the bottom
+	     of the stack.
+
+	     rlim_max is set to RLIM_INFINITY since there's no hard limit
+	     for stack sizes on Windows. */
+	  teb = NtCurrentTeb ();
+	  rlp->rlim_cur = (rlim_t) teb->Tib.StackBase
+			  - (rlim_t) (teb->DeallocationStack
+				      ?: teb->Tib.StackLimit);
 	  break;
 	case RLIMIT_NOFILE:
 	  rlp->rlim_cur = getdtablesize ();



More information about the Cygwin-cvs mailing list