summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2015-06-26 20:41:54 +0200
committerCorinna Vinschen <corinna@vinschen.de>2015-06-26 20:41:54 +0200
commit2ecaa3c1769ce1bf2e42d30304903ac8c9a5fbc8 (patch)
tree6d378b5ff66e5aeb8baa0804218281396a351d61
parent153385d847b991e042bf2ae7252f9c35a3d45516 (diff)
downloadcygnal-2ecaa3c1769ce1bf2e42d30304903ac8c9a5fbc8.tar.gz
cygnal-2ecaa3c1769ce1bf2e42d30304903ac8c9a5fbc8.tar.bz2
cygnal-2ecaa3c1769ce1bf2e42d30304903ac8c9a5fbc8.zip
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>
-rw-r--r--winsup/cygwin/ChangeLog5
-rw-r--r--winsup/cygwin/resource.cc36
2 files changed, 31 insertions, 10 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 3b492e4a7..060eb8015 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 27ba4d4be..895ba7f33 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 ();