Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix stack overflow protection mechanism #553

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/tbb/global_control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,16 @@ class alignas(max_nfs_size) allowed_parallelism_control : public control_storage

class alignas(max_nfs_size) stack_size_control : public control_storage {
std::size_t default_value() const override {
#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
static auto ThreadStackSizeDefault = [] {
ULONG_PTR hi, lo;
GetCurrentThreadStackLimits(&lo, &hi);
return hi - lo;
}();
return ThreadStackSizeDefault;
#else
return ThreadStackSize;
#endif
}
void apply_active(std::size_t new_active) override {
control_storage::apply_active(new_active);
Expand Down
8 changes: 4 additions & 4 deletions src/tbb/governor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,12 @@ void governor::one_time_init() {
static std::uintptr_t get_stack_base(std::size_t stack_size) {
// Stacks are growing top-down. Highest address is called "stack base",
// and the lowest is "stack limit".
#if USE_WINTHREAD
alexey-katranov marked this conversation as resolved.
Show resolved Hide resolved
#if __TBB_USE_WINAPI
suppress_unused_warning(stack_size);
NT_TIB* pteb = (NT_TIB*)NtCurrentTeb();
__TBB_ASSERT(&pteb < pteb->StackBase && &pteb > pteb->StackLimit, "invalid stack info in TEB");
return pteb->StackBase;
#else /* USE_PTHREAD */
return reinterpret_cast<std::uintptr_t>(pteb->StackBase);
#else
// There is no portable way to get stack base address in Posix, so we use
// non-portable method (on all modern Linux) or the simplified approach
// based on the common sense assumptions. The most important assumption
Expand All @@ -164,7 +164,7 @@ static std::uintptr_t get_stack_base(std::size_t stack_size) {
stack_base = reinterpret_cast<std::uintptr_t>(&anchor);
}
return stack_base;
#endif /* USE_PTHREAD */
#endif /* __TBB_USE_WINAPI */
}

#if (_WIN32||_WIN64) && !__TBB_DYNAMIC_LOAD_ENABLED
Expand Down
8 changes: 3 additions & 5 deletions src/tbb/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,9 @@ class task_scheduler_observer;

const std::size_t MByte = 1024*1024;

#if __TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00)
// In Win8UI mode (Windows 8 Store* applications), TBB uses a thread creation API
// that does not allow to specify the stack size.
// Still, the thread stack size value, either explicit or default, is used by the scheduler.
// So here we set the default value to match the platform's default of 1MB.
#if __TBB_USE_WINAPI
// The Microsoft Documentation about Thread Stack Size states that
// "The default stack reservation size used by the linker is 1 MB"
const std::size_t ThreadStackSize = 1*MByte;
#else
const std::size_t ThreadStackSize = (sizeof(uintptr_t) <= 4 ? 2 : 4 )*MByte;
Expand Down
1 change: 1 addition & 0 deletions src/tbb/scheduler_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ class alignas (max_nfs_size) task_dispatcher {
#endif

inline std::uintptr_t calculate_stealing_threshold(std::uintptr_t base, std::size_t stack_size) {
__TBB_ASSERT(base > stack_size / 2, "Stack anchor calculation overflow");
return base - stack_size / 2;
}

Expand Down