From 5beddb7d642524ecb6655ab2823caf2add679917 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Thu, 4 Sep 2014 16:09:25 -0700 Subject: [PATCH] Fix pthread_attr_getstack__main_thread. There were two problems here: * This would fail when run with unlimited stack, because it didn't know that bionic reports unlimited stacks as 8MiB. * This would leave RLIMIT_STACK small, causing failures to exec (so the popen and system tests would fail). (cherry-pick of 27a9aed81978af792cb06035a1619c8141a5fb5b plus the new ScopeGuard.h from a3ad450a2e3fb6b3fe359683b247eba20896f646.) Bug: 17394276 Change-Id: I5b92dc64ca089400223b2d9a3743e9b9d57c1bc2 --- libc/private/ScopeGuard.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++ tests/pthread_test.cpp | 12 +++++++++++ 2 files changed, 65 insertions(+) create mode 100644 libc/private/ScopeGuard.h diff --git a/libc/private/ScopeGuard.h b/libc/private/ScopeGuard.h new file mode 100644 index 000000000..183e322f7 --- /dev/null +++ b/libc/private/ScopeGuard.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCOPE_GUARD_H +#define SCOPE_GUARD_H + +// TODO: include explicit std::move when it becomes available +template +class ScopeGuard { + public: + ScopeGuard(F f) : f_(f), active_(true) {} + + ScopeGuard(ScopeGuard&& that) : f_(that.f_), active_(that.active_) { + that.active_ = false; + } + + ~ScopeGuard() { + if (active_) { + f_(); + } + } + + void disable() { + active_ = false; + } + private: + F f_; + bool active_; + + ScopeGuard() = delete; + ScopeGuard(const ScopeGuard&) = delete; + ScopeGuard& operator=(const ScopeGuard&) = delete; +}; + +template +ScopeGuard create_scope_guard(T f) { + return ScopeGuard(f); +} + +#endif // SCOPE_GUARD_H diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp index 65577385d..4a7c6bd88 100644 --- a/tests/pthread_test.cpp +++ b/tests/pthread_test.cpp @@ -27,6 +27,7 @@ #include #include +#include "private/ScopeGuard.h" #include "ScopedSignalHandler.h" TEST(pthread, pthread_key_create) { @@ -860,8 +861,19 @@ TEST(pthread, pthread_attr_getstack__main_thread) { // The stack size should correspond to RLIMIT_STACK. rlimit rl; ASSERT_EQ(0, getrlimit(RLIMIT_STACK, &rl)); + uint64_t original_rlim_cur = rl.rlim_cur; +#if defined(__BIONIC__) + if (rl.rlim_cur == RLIM_INFINITY) { + rl.rlim_cur = 8 * 1024 * 1024; // Bionic reports unlimited stacks as 8MiB. + } +#endif EXPECT_EQ(rl.rlim_cur, stack_size); + auto guard = create_scope_guard([&rl, original_rlim_cur]() { + rl.rlim_cur = original_rlim_cur; + ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl)); + }); + // The high address of the /proc/self/maps [stack] region should equal stack_base + stack_size. // Remember that the stack grows down (and is mapped in on demand), so the low address of the // region isn't very interesting. -- 2.11.0