Loading toolkit/crashreporter/breakpad-client/windows/crash_generation/crash_generation_server.cc +11 −3 Original line number Diff line number Diff line Loading @@ -839,9 +839,17 @@ void CALLBACK CrashGenerationServer::OnDumpRequest(void* context, BOOLEAN) { ResetEvent(client_info->dump_requested_handle()); }; // Run this function on a separate stack, to hopefully handle an observed // high frequency of stack overflows here. (See bug 1758654 for details.) RunOnTemporaryStack(impl, context, 16 * 1024 * 1024); // Attempt to run this function on a separate stack, to hopefully handle an // observed high frequency of stack overflows here. (See bug 1758654 for // details.) HRESULT const ret = RunOnTemporaryStack(impl, context, 16 * 1024 * 1024); if (FAILED(ret)) { // This means either that there wasn't enough available memory to allocate // the start of a new stack, or there wasn't enough address space to reserve // for the entirety of a new stack. Either way, this probably won't work -- // but it's worth a shot: impl(context); } } // static Loading toolkit/crashreporter/breakpad-client/windows/crash_generation/temporary_stack.cc +6 −3 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ struct Fiberizer { // N.B.: This function takes shameless advantage of the fact that its only // caller is running a void(*)(void *) already, and so it doesn't need to do any // marshalling of multiple arguments, nor of a return value. void RunOnTemporaryStack(void (*func)(void*), void* param, HRESULT RunOnTemporaryStack(void (*func)(void*), void* param, size_t reserved_stack_size) { Fiberizer fiberizer_; Loading Loading @@ -69,7 +69,10 @@ void RunOnTemporaryStack(void (*func)(void*), void* param, // https://docs.microsoft.com/en-us/windows/win32/procthread/thread-stack-size LPVOID const alt_fiber = ::CreateFiberEx( 0, reserved_stack_size, FIBER_FLAG_FLOAT_SWITCH, &_::adaptor, &args); assert(alt_fiber); if (!alt_fiber) { return HRESULT_FROM_WIN32(::GetLastError()); } ::SwitchToFiber(alt_fiber); ::DeleteFiber(alt_fiber); return S_OK; } toolkit/crashreporter/breakpad-client/windows/crash_generation/temporary_stack.h +6 −2 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include <winerror.h> #include <cstdint> // Run `func`, called with `param`, on a separate and possibly larger stack. Loading @@ -12,6 +13,9 @@ // will be allocated only if it's needed, and even then only a page at a time, // so it's probably better to overestimate than underestimate.) // // Returns S_OK on success. Otherwise, returns some FAILED HRESULT, and `func` // is not executed. // // https://docs.microsoft.com/en-us/windows/win32/procthread/thread-stack-size void RunOnTemporaryStack(void (*func)(void*), void* param, HRESULT RunOnTemporaryStack(void (*func)(void*), void* param, size_t reserved_stack_size); toolkit/crashreporter/breakpad-client/windows/unittests/TestRunOnTemporaryStack.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -164,6 +164,23 @@ void test_large() { assert_compare_mem_stats(after_once, after_many); } void test_too_large() { bool callback_has_run = false; auto const callback = [](void* arg) { *((bool*)arg) = true; }; const size_t too_large = (size_t(-1)); auto const ret = ::RunOnTemporaryStack(callback, &callback_has_run, too_large); if (SUCCEEDED(ret)) { ::fprintf(stderr, "Unexpectedly reported success in test_too_large"); failed = true; } if (callback_has_run) { ::fprintf(stderr, "Unexpectedly ran callback in test_too_large"); failed = true; } } // Test that the program exits correctly (rather than by falling off the end of // a fiber procedure). struct confirm_normal_exit { Loading Loading @@ -269,6 +286,7 @@ int main(int, char**) { test_small(); test_large(); test_too_large(); if (failed) { ::printf("%s\n", "failed (see above)"); Loading Loading
toolkit/crashreporter/breakpad-client/windows/crash_generation/crash_generation_server.cc +11 −3 Original line number Diff line number Diff line Loading @@ -839,9 +839,17 @@ void CALLBACK CrashGenerationServer::OnDumpRequest(void* context, BOOLEAN) { ResetEvent(client_info->dump_requested_handle()); }; // Run this function on a separate stack, to hopefully handle an observed // high frequency of stack overflows here. (See bug 1758654 for details.) RunOnTemporaryStack(impl, context, 16 * 1024 * 1024); // Attempt to run this function on a separate stack, to hopefully handle an // observed high frequency of stack overflows here. (See bug 1758654 for // details.) HRESULT const ret = RunOnTemporaryStack(impl, context, 16 * 1024 * 1024); if (FAILED(ret)) { // This means either that there wasn't enough available memory to allocate // the start of a new stack, or there wasn't enough address space to reserve // for the entirety of a new stack. Either way, this probably won't work -- // but it's worth a shot: impl(context); } } // static Loading
toolkit/crashreporter/breakpad-client/windows/crash_generation/temporary_stack.cc +6 −3 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ struct Fiberizer { // N.B.: This function takes shameless advantage of the fact that its only // caller is running a void(*)(void *) already, and so it doesn't need to do any // marshalling of multiple arguments, nor of a return value. void RunOnTemporaryStack(void (*func)(void*), void* param, HRESULT RunOnTemporaryStack(void (*func)(void*), void* param, size_t reserved_stack_size) { Fiberizer fiberizer_; Loading Loading @@ -69,7 +69,10 @@ void RunOnTemporaryStack(void (*func)(void*), void* param, // https://docs.microsoft.com/en-us/windows/win32/procthread/thread-stack-size LPVOID const alt_fiber = ::CreateFiberEx( 0, reserved_stack_size, FIBER_FLAG_FLOAT_SWITCH, &_::adaptor, &args); assert(alt_fiber); if (!alt_fiber) { return HRESULT_FROM_WIN32(::GetLastError()); } ::SwitchToFiber(alt_fiber); ::DeleteFiber(alt_fiber); return S_OK; }
toolkit/crashreporter/breakpad-client/windows/crash_generation/temporary_stack.h +6 −2 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include <winerror.h> #include <cstdint> // Run `func`, called with `param`, on a separate and possibly larger stack. Loading @@ -12,6 +13,9 @@ // will be allocated only if it's needed, and even then only a page at a time, // so it's probably better to overestimate than underestimate.) // // Returns S_OK on success. Otherwise, returns some FAILED HRESULT, and `func` // is not executed. // // https://docs.microsoft.com/en-us/windows/win32/procthread/thread-stack-size void RunOnTemporaryStack(void (*func)(void*), void* param, HRESULT RunOnTemporaryStack(void (*func)(void*), void* param, size_t reserved_stack_size);
toolkit/crashreporter/breakpad-client/windows/unittests/TestRunOnTemporaryStack.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -164,6 +164,23 @@ void test_large() { assert_compare_mem_stats(after_once, after_many); } void test_too_large() { bool callback_has_run = false; auto const callback = [](void* arg) { *((bool*)arg) = true; }; const size_t too_large = (size_t(-1)); auto const ret = ::RunOnTemporaryStack(callback, &callback_has_run, too_large); if (SUCCEEDED(ret)) { ::fprintf(stderr, "Unexpectedly reported success in test_too_large"); failed = true; } if (callback_has_run) { ::fprintf(stderr, "Unexpectedly ran callback in test_too_large"); failed = true; } } // Test that the program exits correctly (rather than by falling off the end of // a fiber procedure). struct confirm_normal_exit { Loading Loading @@ -269,6 +286,7 @@ int main(int, char**) { test_small(); test_large(); test_too_large(); if (failed) { ::printf("%s\n", "failed (see above)"); Loading