Commit 7baded92 authored by Ray Kraesig's avatar Ray Kraesig
Browse files

Bug 1763093 - fall back to running on the existing thread r=gsvelto

parent 6821627f
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -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
+6 −3
Original line number Diff line number Diff line
@@ -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_;

@@ -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;
}
+6 −2
Original line number Diff line number Diff line
@@ -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.
@@ -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);
+18 −0
Original line number Diff line number Diff line
@@ -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 {
@@ -269,6 +286,7 @@ int main(int, char**) {

  test_small();
  test_large();
  test_too_large();

  if (failed) {
    ::printf("%s\n", "failed (see above)");