mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1181411 - Test some expected aborts in PLDHashTable. r=glandium.
This commit is contained in:
parent
c174ab0c41
commit
047ce23ad8
@ -38,7 +38,9 @@
|
||||
#endif
|
||||
|
||||
static char _progname[1024] = "huh?";
|
||||
static unsigned int _gdb_sleep_duration = 300;
|
||||
|
||||
// Note: some tests manipulate this value.
|
||||
unsigned int _gdb_sleep_duration = 300;
|
||||
|
||||
#if defined(LINUX) && defined(DEBUG) && \
|
||||
(defined(__i386) || defined(__x86_64) || defined(PPC))
|
||||
|
@ -10,23 +10,109 @@
|
||||
// This test mostly focuses on edge cases. But more coverage of normal
|
||||
// operations wouldn't be a bad thing.
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
// This global variable is defined in toolkit/xre/nsSigHandlers.cpp.
|
||||
extern unsigned int _gdb_sleep_duration;
|
||||
#endif
|
||||
|
||||
// We can test that certain operations cause expected aborts by forking
|
||||
// and then checking that the child aborted in the expected way (i.e. via
|
||||
// MOZ_CRASH). We skip this for the following configurations.
|
||||
// - On Windows, because it doesn't have fork().
|
||||
// - On non-DEBUG builds, because the crashes cause the crash reporter to pop
|
||||
// up when running this test locally, which is surprising and annoying.
|
||||
// - On ASAN builds, because ASAN alters the way a MOZ_CRASHing process
|
||||
// terminates, which makes it harder to test if the right thing has occurred.
|
||||
void
|
||||
TestCrashyOperation(void (*aCrashyOperation)())
|
||||
{
|
||||
#if defined(XP_UNIX) && defined(DEBUG) && !defined(MOZ_ASAN)
|
||||
// We're about to trigger a crash. When it happens don't pause to allow GDB
|
||||
// to be attached.
|
||||
unsigned int old_gdb_sleep_duration = _gdb_sleep_duration;
|
||||
_gdb_sleep_duration = 0;
|
||||
|
||||
int pid = fork();
|
||||
ASSERT_NE(pid, -1);
|
||||
|
||||
if (pid == 0) {
|
||||
// Child: perform the crashy operation.
|
||||
aCrashyOperation();
|
||||
fprintf(stderr, "TestCrashyOperation: didn't crash?!\n");
|
||||
ASSERT_TRUE(false); // shouldn't reach here
|
||||
}
|
||||
|
||||
// Parent: check that child crashed as expected.
|
||||
int status;
|
||||
ASSERT_NE(waitpid(pid, &status, 0), -1);
|
||||
|
||||
// The path taken here depends on the platform and configuration.
|
||||
ASSERT_TRUE(WIFEXITED(status) || WTERMSIG(status));
|
||||
if (WIFEXITED(status)) {
|
||||
// This occurs if the ah_crap_handler() is run, i.e. we caught the crash.
|
||||
// It returns the number of the caught signal.
|
||||
int signum = WEXITSTATUS(status);
|
||||
if (signum != SIGSEGV && signum != SIGBUS) {
|
||||
fprintf(stderr, "TestCrashyOperation 'exited' failure: %d\n", signum);
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
// This one occurs if we didn't catch the crash. The exit code is the
|
||||
// number of the terminating signal.
|
||||
int signum = WTERMSIG(status);
|
||||
if (signum != SIGSEGV && signum != SIGBUS) {
|
||||
fprintf(stderr, "TestCrashyOperation 'signaled' failure: %d\n", signum);
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
}
|
||||
|
||||
_gdb_sleep_duration = old_gdb_sleep_duration;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
InitCapacityOk_InitialLengthTooBig()
|
||||
{
|
||||
PLDHashTable t(PL_DHashGetStubOps(), sizeof(PLDHashEntryStub),
|
||||
PL_DHASH_MAX_INITIAL_LENGTH + 1);
|
||||
}
|
||||
|
||||
void
|
||||
InitCapacityOk_InitialEntryStoreTooBig()
|
||||
{
|
||||
// Try the smallest disallowed power-of-two entry store size, which is 2^32
|
||||
// bytes (which overflows to 0). (Note that the 2^23 *length* gets converted
|
||||
// to a 2^24 *capacity*.)
|
||||
PLDHashTable t(PL_DHashGetStubOps(), (uint32_t)1 << 23, (uint32_t)1 << 8);
|
||||
}
|
||||
|
||||
TEST(PLDHashTableTest, InitCapacityOk)
|
||||
{
|
||||
// Try the largest allowed capacity. With PL_DHASH_MAX_CAPACITY==1<<26, this
|
||||
// would allocate (if we added an element) 0.5GB of entry store on 32-bit
|
||||
// platforms and 1GB on 64-bit platforms.
|
||||
//
|
||||
// Ideally we'd also try (a) a too-large capacity, and (b) a large capacity
|
||||
// combined with a large entry size that when multipled overflow. But those
|
||||
// cases would cause the test to abort immediately.
|
||||
//
|
||||
// Furthermore, ideally we'd also try a large-but-ok capacity that almost but
|
||||
// doesn't quite overflow, but that would result in allocating just under 4GB
|
||||
// of entry storage. That's very likely to fail on 32-bit platforms, so such
|
||||
// a test wouldn't be reliable.
|
||||
//
|
||||
PLDHashTable t(PL_DHashGetStubOps(), sizeof(PLDHashEntryStub),
|
||||
PLDHashTable t1(PL_DHashGetStubOps(), sizeof(PLDHashEntryStub),
|
||||
PL_DHASH_MAX_INITIAL_LENGTH);
|
||||
|
||||
// Try the largest allowed power-of-two entry store size, which is 2^31 bytes
|
||||
// (Note that the 2^23 *length* gets converted to a 2^24 *capacity*.)
|
||||
PLDHashTable t2(PL_DHashGetStubOps(), (uint32_t)1 << 23, (uint32_t)1 << 7);
|
||||
|
||||
// Try a too-large capacity (which aborts).
|
||||
TestCrashyOperation(InitCapacityOk_InitialLengthTooBig);
|
||||
|
||||
// Try a large capacity combined with a large entry size that when multiplied
|
||||
// overflow (causing abort).
|
||||
TestCrashyOperation(InitCapacityOk_InitialEntryStoreTooBig);
|
||||
|
||||
// Ideally we'd also try a large-but-ok capacity that almost but doesn't
|
||||
// quite overflow, but that would result in allocating slightly less than 4
|
||||
// GiB of entry storage. That would be very likely to fail on 32-bit
|
||||
// platforms, so such a test wouldn't be reliable.
|
||||
}
|
||||
|
||||
TEST(PLDHashTableTest, LazyStorage)
|
||||
@ -141,7 +227,7 @@ TEST(PLDHashTableTest, Clear)
|
||||
ASSERT_EQ(t1.EntryCount(), 0u);
|
||||
}
|
||||
|
||||
TEST(PLDHashTableIterator, Iterator)
|
||||
TEST(PLDHashTableTest, Iterator)
|
||||
{
|
||||
PLDHashTable t(&trivialOps, sizeof(PLDHashEntryStub));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user