diff options
Diffstat (limited to 'net/disk_cache/stress_cache.cc')
-rw-r--r-- | net/disk_cache/stress_cache.cc | 89 |
1 files changed, 66 insertions, 23 deletions
diff --git a/net/disk_cache/stress_cache.cc b/net/disk_cache/stress_cache.cc index 7fad2ef..a18df2a 100644 --- a/net/disk_cache/stress_cache.cc +++ b/net/disk_cache/stress_cache.cc @@ -12,15 +12,7 @@ // A regular build should never crash. // To test that the disk cache doesn't generate critical errors with regular -// application level crashes, add the following code and re-compile: -// -// void BackendImpl::CriticalError(int error) { -// NOTREACHED(); -// -// void BackendImpl::ReportError(int error) { -// if (error && error != ERR_PREVIOUS_CRASH) { -// NOTREACHED(); -// } +// application level crashes, edit stress_support.h. #include <string> #include <vector> @@ -44,6 +36,12 @@ #include "net/disk_cache/backend_impl.h" #include "net/disk_cache/disk_cache.h" #include "net/disk_cache/disk_cache_test_util.h" +#include "net/disk_cache/stress_support.h" +#include "net/disk_cache/trace.h" + +#if defined(OS_WIN) +#include "base/logging_win.h" +#endif using base::Time; @@ -87,11 +85,21 @@ int MasterCode() { // ----------------------------------------------------------------------- +std::string GenerateStressKey() { + char key[20 * 1024]; + size_t size = 50 + rand() % 20000; + CacheTestFillBuffer(key, size, true); + + key[size - 1] = '\0'; + return std::string(key); +} + // This thread will loop forever, adding and removing entries from the cache. // iteration is the current crash cycle, so the entries on the cache are marked // to know which instance of the application wrote them. void StressTheCache(int iteration) { - int cache_size = 0x800000; // 8MB + int cache_size = 0x2000000; // 32MB. + uint32 mask = 0xfff; // 4096 entries. FilePath path = GetCacheFilePath().InsertBeforeExtensionASCII("_stress"); base::Thread cache_thread("CacheThread"); @@ -99,12 +107,14 @@ void StressTheCache(int iteration) { base::Thread::Options(MessageLoop::TYPE_IO, 0))) return; + disk_cache::BackendImpl* cache = + new disk_cache::BackendImpl(path, mask, cache_thread.message_loop_proxy(), + NULL); + cache->SetMaxSize(cache_size); + cache->SetFlags(disk_cache::kNoLoadProtection); + TestOldCompletionCallback cb; - disk_cache::Backend* cache; - int rv = disk_cache::BackendImpl::CreateBackend( - path, false, cache_size, net::DISK_CACHE, - disk_cache::kNoLoadProtection | disk_cache::kNoRandom, - cache_thread.message_loop_proxy(), NULL, &cache, &cb); + int rv = cache->Init(&cb); if (cb.GetResult(rv) != net::OK) { printf("Unable to initialize cache.\n"); @@ -116,20 +126,22 @@ void StressTheCache(int iteration) { int seed = static_cast<int>(Time::Now().ToInternalValue()); srand(seed); + // kNumKeys is meant to be enough to have about 3x or 4x iterations before + // the process crashes. #ifdef NDEBUG - const int kNumKeys = 5000; + const int kNumKeys = 4000; #else - const int kNumKeys = 1700; + const int kNumKeys = 1200; #endif const int kNumEntries = 30; std::string keys[kNumKeys]; disk_cache::Entry* entries[kNumEntries] = {0}; for (int i = 0; i < kNumKeys; i++) { - keys[i] = GenerateKey(true); + keys[i] = GenerateStressKey(); } - const int kSize = 4000; + const int kSize = 20000; scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); memset(buffer->data(), 'k', kSize); @@ -137,7 +149,7 @@ void StressTheCache(int iteration) { int slot = rand() % kNumEntries; int key = rand() % kNumKeys; bool truncate = rand() % 2 ? false : true; - int size = kSize - (rand() % 4) * kSize / 4; + int size = kSize - (rand() % 20) * kSize / 20; if (entries[slot]) entries[slot]->Close(); @@ -149,8 +161,8 @@ void StressTheCache(int iteration) { } base::snprintf(buffer->data(), kSize, - "i: %d iter: %d, size: %d, truncate: %d", i, iteration, size, - truncate ? 1 : 0); + "i: %d iter: %d, size: %d, truncate: %d ", i, iteration, + size, truncate ? 1 : 0); rv = entries[slot]->WriteData(0, 0, buffer, size, &cb, truncate); CHECK_EQ(size, cb.GetResult(rv)); @@ -181,7 +193,7 @@ class CrashTask : public Task { if (g_crashing) return; - if (rand() % 100 > 1) { + if (rand() % 100 > 30) { printf("sweet death...\n"); #if defined(OS_WIN) // Windows does more work on _exit() that we would like, so we use Kill. @@ -216,8 +228,29 @@ void CrashHandler(const std::string& str) { base::debug::BreakDebugger(); } +bool MessageHandler(int severity, const char* file, int line, + size_t message_start, const std::string& str) { + const size_t kMaxMessageLen = 48; + char message[kMaxMessageLen]; + size_t len = std::min(str.length() - message_start, kMaxMessageLen - 1); + + memcpy(message, str.c_str() + message_start, len); + message[len] = '\0'; +#if !defined(DISK_CACHE_TRACE_TO_LOG) + disk_cache::Trace("%s", message); +#endif + return false; +} + // ----------------------------------------------------------------------- +#if defined(OS_WIN) +// {B9A153D4-31C3-48e4-9ABF-D54383F14A0D} +const GUID kStressCacheTraceProviderName = { + 0xb9a153d4, 0x31c3, 0x48e4, + { 0x9a, 0xbf, 0xd5, 0x43, 0x83, 0xf1, 0x4a, 0xd } }; +#endif + int main(int argc, const char* argv[]) { // Setup an AtExitManager so Singleton objects will be destructed. base::AtExitManager at_exit_manager; @@ -226,6 +259,16 @@ int main(int argc, const char* argv[]) { return MasterCode(); logging::SetLogAssertHandler(CrashHandler); + logging::SetLogMessageHandler(MessageHandler); + +#if defined(OS_WIN) + logging::LogEventProvider::Initialize(kStressCacheTraceProviderName); +#else + CommandLine::Init(argc, argv); + logging::InitLogging(NULL, logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG, + logging::LOCK_LOG_FILE, logging::DELETE_OLD_LOG_FILE, + logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS); +#endif // Some time for the memory manager to flush stuff. base::PlatformThread::Sleep(3000); |