Commit 52286a8b authored by Christopher Dykes's avatar Christopher Dykes Committed by Facebook Github Bot 3

Add a utility for disabling some CRT assertions in debug mode

Summary:
See the comment on `msvcReturnInvalidParams` for more info on the issue.
This also adds a use of it to TestUtilTest.

Reviewed By: yfeldblum

Differential Revision: D3691526

fbshipit-source-id: f0f596e9b4c830e1d31de01926162636757329e8
parent 60136d87
......@@ -30,6 +30,10 @@
#include <folly/portability/Fcntl.h>
#include <folly/portability/Unistd.h>
#ifdef _WIN32
#include <crtdbg.h>
#endif
namespace folly {
namespace test {
......@@ -128,6 +132,32 @@ ChangeToTempDir::~ChangeToTempDir() {
namespace detail {
SavedState disableInvalidParameters() {
#ifdef _WIN32
SavedState ret;
ret.previousThreadLocalHandler = _set_thread_local_invalid_parameter_handler(
[](const wchar_t*,
const wchar_t*,
const wchar_t*,
unsigned int,
uintptr_t) {});
ret.previousCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
return ret;
#else
return SavedState();
#endif
}
#ifdef _WIN32
void enableInvalidParameters(SavedState state) {
_set_thread_local_invalid_parameter_handler(
(_invalid_parameter_handler)state.previousThreadLocalHandler);
_CrtSetReportMode(_CRT_ASSERT, state.previousCrtReportMode);
}
#else
void enableInvalidParameters(SavedState) {}
#endif
bool hasPCREPatternMatch(StringPiece pattern, StringPiece target) {
return boost::regex_match(
target.begin(),
......
......@@ -19,6 +19,7 @@
#include <map>
#include <string>
#include <folly/Range.h>
#include <folly/ScopeGuard.h>
#include <folly/experimental/io/FsUtil.h>
namespace folly {
......@@ -118,6 +119,33 @@ private:
TemporaryDirectory dir_;
};
namespace detail {
struct SavedState {
void* previousThreadLocalHandler;
int previousCrtReportMode;
};
SavedState disableInvalidParameters();
void enableInvalidParameters(SavedState state);
}
// Ok, so fun fact: The CRT on windows will actually abort
// on certain failed parameter validation checks in debug
// mode rather than simply returning -1 as it does in release
// mode. We can however, ensure consistent behavior by
// registering our own thread-local invalid parameter handler
// for the duration of the call, and just have that handler
// immediately return. We also have to disable CRT asertion
// alerts for the duration of the call, otherwise we get
// the abort-retry-ignore window.
template <typename Func>
auto msvcSuppressAbortOnInvalidParams(Func func) -> decltype(func()) {
auto savedState = detail::disableInvalidParameters();
SCOPE_EXIT {
detail::enableInvalidParameters(savedState);
};
return func();
}
/**
* Easy PCRE regex matching. Note that pattern must match the ENTIRE target,
* so use .* at the start and end of the pattern, as appropriate. See
......
......@@ -45,6 +45,7 @@ TEST(TemporaryFile, Simple) {
EXPECT_EQ(1, r);
}
msvcSuppressAbortOnInvalidParams([&] {
// The file must have been closed. This assumes that no other thread
// has opened another file in the meanwhile, which is a sane assumption
// to make in this test.
......@@ -52,6 +53,7 @@ TEST(TemporaryFile, Simple) {
int savedErrno = errno;
EXPECT_EQ(-1, r);
EXPECT_EQ(EBADF, savedErrno);
});
}
TEST(TemporaryFile, Prefix) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment