diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-20 19:12:25 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-20 19:12:25 +0000 |
commit | ea9080b5665d0ac2007a6521d075ad73e9ad10b2 (patch) | |
tree | 4564eebf016a0ae0d1ebd1629493d8b2c1c52aa5 | |
parent | 794d83cda5183b25665e99296ab6f5e6c1dbf2dc (diff) | |
download | chromium_src-ea9080b5665d0ac2007a6521d075ad73e9ad10b2.zip chromium_src-ea9080b5665d0ac2007a6521d075ad73e9ad10b2.tar.gz chromium_src-ea9080b5665d0ac2007a6521d075ad73e9ad10b2.tar.bz2 |
Disk cache: Update stress_cache to perform deeper testsing.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/8352013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@106538 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/disk_cache/backend_impl.cc | 83 | ||||
-rw-r--r-- | net/disk_cache/backend_impl.h | 9 | ||||
-rw-r--r-- | net/disk_cache/backend_unittest.cc | 8 | ||||
-rw-r--r-- | net/disk_cache/disk_cache_test_base.cc | 4 | ||||
-rw-r--r-- | net/disk_cache/disk_cache_test_util.cc | 4 | ||||
-rw-r--r-- | net/disk_cache/disk_cache_test_util.h | 2 | ||||
-rw-r--r-- | net/disk_cache/entry_impl.cc | 9 | ||||
-rw-r--r-- | net/disk_cache/rankings.cc | 8 | ||||
-rw-r--r-- | net/disk_cache/stress_cache.cc | 89 | ||||
-rw-r--r-- | net/disk_cache/stress_support.h | 40 | ||||
-rw-r--r-- | net/disk_cache/trace.cc | 24 | ||||
-rw-r--r-- | net/disk_cache/trace.h | 1 |
12 files changed, 242 insertions, 39 deletions
diff --git a/net/disk_cache/backend_impl.cc b/net/disk_cache/backend_impl.cc index c1cdad7..0d9c7e3 100644 --- a/net/disk_cache/backend_impl.cc +++ b/net/disk_cache/backend_impl.cc @@ -453,6 +453,10 @@ int BackendImpl::Init(OldCompletionCallback* callback) { } int BackendImpl::SyncInit() { +#if defined(NET_BUILD_STRESS_CACHE) + // Start evictions right away. + up_ticks_ = kTrimDelay * 2; +#endif DCHECK(!init_); if (init_) return net::ERR_FAILED; @@ -476,6 +480,7 @@ int BackendImpl::SyncInit() { } init_ = true; + Trace("Init"); if (data_->header.experiment != NO_EXPERIMENT && cache_type_ != net::DISK_CACHE) { @@ -531,6 +536,14 @@ int BackendImpl::SyncInit() { disabled_ = !rankings_.Init(this, new_eviction_); +#if defined(STRESS_CACHE_EXTENDED_VALIDATION) + trace_object_->EnableTracing(false); + int sc = SelfCheck(); + if (sc < 0 && sc != ERR_NUM_ENTRIES_MISMATCH) + NOTREACHED(); + trace_object_->EnableTracing(true); +#endif + return disabled_ ? net::ERR_FAILED : net::OK; } @@ -931,8 +944,10 @@ void BackendImpl::UpdateRank(EntryImpl* entry, bool modified) { void BackendImpl::RecoveredEntry(CacheRankingsBlock* rankings) { Addr address(rankings->Data()->contents); EntryImpl* cache_entry = NULL; - if (NewEntry(address, &cache_entry)) + if (NewEntry(address, &cache_entry)) { + STRESS_NOTREACHED(); return; +} uint32 hash = cache_entry->GetHash(); cache_entry->Release(); @@ -972,9 +987,44 @@ void BackendImpl::InternalDoomEntry(EntryImpl* entry) { } } +#if defined(NET_BUILD_STRESS_CACHE) + +CacheAddr BackendImpl::GetNextAddr(Addr address) { + EntriesMap::iterator it = open_entries_.find(address.value()); + if (it != open_entries_.end()) { + EntryImpl* this_entry = it->second; + return this_entry->GetNextAddress(); + } + DCHECK(block_files_.IsValid(address)); + DCHECK(!address.is_separate_file() && address.file_type() == BLOCK_256); + + CacheEntryBlock entry(File(address), address); + CHECK(entry.Load()); + return entry.Data()->next; +} + +void BackendImpl::NotLinked(EntryImpl* entry) { + Addr entry_addr = entry->entry()->address(); + uint32 i = entry->GetHash() & mask_; + Addr address(data_->table[i]); + if (!address.is_initialized()) + return; + + for (;;) { + DCHECK(entry_addr.value() != address.value()); + address.set_value(GetNextAddr(address)); + if (!address.is_initialized()) + break; + } +} +#endif // NET_BUILD_STRESS_CACHE + // An entry may be linked on the DELETED list for a while after being doomed. // This function is called when we want to remove it. void BackendImpl::RemoveEntry(EntryImpl* entry) { +#if defined(NET_BUILD_STRESS_CACHE) + NotLinked(entry); +#endif if (!new_eviction_) return; @@ -1147,6 +1197,7 @@ void BackendImpl::FirstEviction() { } void BackendImpl::CriticalError(int error) { + STRESS_NOTREACHED(); LOG(ERROR) << "Critical error found " << error; if (disabled_) return; @@ -1166,6 +1217,8 @@ void BackendImpl::CriticalError(int error) { } void BackendImpl::ReportError(int error) { + STRESS_DCHECK(!error || error == ERR_PREVIOUS_CRASH); + // We transmit positive numbers, instead of direct error codes. DCHECK_LE(error, 0); CACHE_UMA(CACHE_ERROR, "Error", 0, error * -1); @@ -1284,12 +1337,16 @@ int BackendImpl::SelfCheck() { int num_entries = rankings_.SelfCheck(); if (num_entries < 0) { LOG(ERROR) << "Invalid rankings list, error " << num_entries; +#if !defined(NET_BUILD_STRESS_CACHE) return num_entries; +#endif } if (num_entries != data_->header.num_entries) { LOG(ERROR) << "Number of entries mismatch"; +#if !defined(NET_BUILD_STRESS_CACHE) return ERR_NUM_ENTRIES_MISMATCH; +#endif } return CheckAllEntries(); @@ -1547,9 +1604,12 @@ int BackendImpl::NewEntry(Addr address, EntryImpl** entry) { return 0; } + STRESS_DCHECK(block_files_.IsValid(address)); + if (!address.is_initialized() || address.is_separate_file() || address.file_type() != BLOCK_256) { LOG(WARNING) << "Wrong entry address."; + STRESS_NOTREACHED(); return ERR_INVALID_ADDRESS; } @@ -1568,9 +1628,13 @@ int BackendImpl::NewEntry(Addr address, EntryImpl** entry) { if (!cache_entry->SanityCheck()) { LOG(WARNING) << "Messed up entry found."; + STRESS_NOTREACHED(); return ERR_INVALID_ENTRY; } + STRESS_DCHECK(block_files_.IsValid( + Addr(cache_entry->entry()->Data()->rankings_node))); + if (!cache_entry->LoadNodeAddress()) return ERR_READ_FAILURE; @@ -1578,12 +1642,14 @@ int BackendImpl::NewEntry(Addr address, EntryImpl** entry) { cache_entry->SetDirtyFlag(GetCurrentEntryId()); if (!rankings_.SanityCheck(cache_entry->rankings(), false)) { + STRESS_NOTREACHED(); cache_entry->SetDirtyFlag(0); // Don't remove this from the list (it is not linked properly). Instead, // break the link back to the entry because it is going away, and leave the // rankings node to be deleted if we find it through a list. rankings_.SetContents(cache_entry->rankings(), 0); } else if (!rankings_.DataSanityCheck(cache_entry->rankings(), false)) { + STRESS_NOTREACHED(); cache_entry->SetDirtyFlag(0); rankings_.SetContents(cache_entry->rankings(), address.value()); } @@ -1816,6 +1882,7 @@ EntryImpl* BackendImpl::GetEnumeratedEntry(CacheRankingsBlock* next, EntryImpl* entry; int rv = NewEntry(Addr(next->Data()->contents), &entry); if (rv) { + STRESS_NOTREACHED(); rankings_.Remove(next, list, false); if (rv == ERR_INVALID_ADDRESS) { // There is nothing linked from the index. Delete the rankings node. @@ -1832,6 +1899,7 @@ EntryImpl* BackendImpl::GetEnumeratedEntry(CacheRankingsBlock* next, } if (!entry->Update()) { + STRESS_NOTREACHED(); entry->Release(); return NULL; } @@ -2069,12 +2137,14 @@ bool BackendImpl::CheckIndex() { AdjustMaxCacheSize(data_->header.table_len); +#if !defined(NET_BUILD_STRESS_CACHE) if (data_->header.num_bytes < 0 || (max_size_ < kint32max - kDefaultCacheSize && data_->header.num_bytes > max_size_ + kDefaultCacheSize)) { LOG(ERROR) << "Invalid cache (current) size"; return false; } +#endif if (data_->header.num_entries < 0) { LOG(ERROR) << "Invalid number of entries"; @@ -2093,15 +2163,17 @@ int BackendImpl::CheckAllEntries() { int num_dirty = 0; int num_entries = 0; DCHECK(mask_ < kuint32max); - for (int i = 0; i <= static_cast<int>(mask_); i++) { + for (unsigned int i = 0; i <= mask_; i++) { Addr address(data_->table[i]); if (!address.is_initialized()) continue; for (;;) { EntryImpl* tmp; int ret = NewEntry(address, &tmp); - if (ret) + if (ret) { + STRESS_NOTREACHED(); return ret; + } scoped_refptr<EntryImpl> cache_entry; cache_entry.swap(&tmp); @@ -2112,6 +2184,7 @@ int BackendImpl::CheckAllEntries() { else return ERR_INVALID_ENTRY; + DCHECK_EQ(i, cache_entry->entry()->Data()->hash & mask_); address.set_value(cache_entry->GetNextAddress()); if (!address.is_initialized()) break; @@ -2120,7 +2193,9 @@ int BackendImpl::CheckAllEntries() { Trace("CheckAllEntries End"); if (num_entries + num_dirty != data_->header.num_entries) { - LOG(ERROR) << "Number of entries mismatch"; + LOG(ERROR) << "Number of entries " << num_entries << " " << num_dirty << + " " << data_->header.num_entries; + DCHECK_LT(num_entries, data_->header.num_entries); return ERR_NUM_ENTRIES_MISMATCH; } diff --git a/net/disk_cache/backend_impl.h b/net/disk_cache/backend_impl.h index 8d529d3..c637791 100644 --- a/net/disk_cache/backend_impl.h +++ b/net/disk_cache/backend_impl.h @@ -17,6 +17,7 @@ #include "net/disk_cache/in_flight_backend_io.h" #include "net/disk_cache/rankings.h" #include "net/disk_cache/stats.h" +#include "net/disk_cache/stress_support.h" #include "net/disk_cache/trace.h" namespace net { @@ -127,6 +128,14 @@ class NET_EXPORT_PRIVATE BackendImpl : public Backend { // Permanently deletes an entry, but still keeps track of it. void InternalDoomEntry(EntryImpl* entry); +#if defined(NET_BUILD_STRESS_CACHE) + // Returns the address of the entry linked to the entry at a given |address|. + CacheAddr GetNextAddr(Addr address); + + // Verifies that |entry| is not currently reachable through the index. + void NotLinked(EntryImpl* entry); +#endif + // Removes all references to this entry. void RemoveEntry(EntryImpl* entry); diff --git a/net/disk_cache/backend_unittest.cc b/net/disk_cache/backend_unittest.cc index bae4649..8188894 100644 --- a/net/disk_cache/backend_unittest.cc +++ b/net/disk_cache/backend_unittest.cc @@ -1199,14 +1199,16 @@ void DiskCacheBackendTest::BackendTransaction(const std::string& name, ASSERT_TRUE(CopyTestCache(name)); DisableFirstCleanup(); + uint32 mask; if (load) { - SetMask(0xf); + mask = 0xf; SetMaxSize(0x100000); } else { // Clear the settings from the previous run. - SetMask(0); + mask = 0; SetMaxSize(0); } + SetMask(mask); InitCache(); ASSERT_EQ(num_entries + 1, cache_->GetEntryCount()); @@ -1227,7 +1229,7 @@ void DiskCacheBackendTest::BackendTransaction(const std::string& name, cache_ = NULL; cache_impl_ = NULL; - ASSERT_TRUE(CheckCacheIntegrity(GetCacheFilePath(), new_eviction_)); + ASSERT_TRUE(CheckCacheIntegrity(GetCacheFilePath(), new_eviction_, mask)); success_ = true; } diff --git a/net/disk_cache/disk_cache_test_base.cc b/net/disk_cache/disk_cache_test_base.cc index c200328..28c1233 100644 --- a/net/disk_cache/disk_cache_test_base.cc +++ b/net/disk_cache/disk_cache_test_base.cc @@ -58,7 +58,7 @@ void DiskCacheTestWithCache::SimulateCrash() { delete cache_impl_; FilePath path = GetCacheFilePath(); - EXPECT_TRUE(CheckCacheIntegrity(path, new_eviction_)); + EXPECT_TRUE(CheckCacheIntegrity(path, new_eviction_, mask_)); InitDiskCacheImpl(path); } @@ -213,7 +213,7 @@ void DiskCacheTestWithCache::TearDown() { if (!memory_only_ && integrity_) { FilePath path = GetCacheFilePath(); - EXPECT_TRUE(CheckCacheIntegrity(path, new_eviction_)); + EXPECT_TRUE(CheckCacheIntegrity(path, new_eviction_, mask_)); } PlatformTest::TearDown(); diff --git a/net/disk_cache/disk_cache_test_util.cc b/net/disk_cache/disk_cache_test_util.cc index b68e3eb..1a348cf 100644 --- a/net/disk_cache/disk_cache_test_util.cc +++ b/net/disk_cache/disk_cache_test_util.cc @@ -92,9 +92,9 @@ bool CopyTestCache(const std::string& name) { return file_util::CopyDirectory(path, dest, false); } -bool CheckCacheIntegrity(const FilePath& path, bool new_eviction) { +bool CheckCacheIntegrity(const FilePath& path, bool new_eviction, uint32 mask) { scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl( - path, base::MessageLoopProxy::current(), NULL)); + path, mask, base::MessageLoopProxy::current(), NULL)); if (!cache.get()) return false; if (new_eviction) diff --git a/net/disk_cache/disk_cache_test_util.h b/net/disk_cache/disk_cache_test_util.h index 0bd937c..6469761 100644 --- a/net/disk_cache/disk_cache_test_util.h +++ b/net/disk_cache/disk_cache_test_util.h @@ -34,7 +34,7 @@ void CacheTestFillBuffer(char* buffer, size_t len, bool no_nulls); std::string GenerateKey(bool same_length); // Returns true if the cache is not corrupt. -bool CheckCacheIntegrity(const FilePath& path, bool new_eviction); +bool CheckCacheIntegrity(const FilePath& path, bool new_eviction, uint32 mask); // Helper class which ensures that the cache dir returned by GetCacheFilePath // exists and is clear in ctor and that the directory gets deleted in dtor. diff --git a/net/disk_cache/entry_impl.cc b/net/disk_cache/entry_impl.cc index e830fa0..920600d 100644 --- a/net/disk_cache/entry_impl.cc +++ b/net/disk_cache/entry_impl.cc @@ -585,8 +585,11 @@ bool EntryImpl::SanityCheck() { Addr next_addr(stored->next); if (next_addr.is_initialized() && - (next_addr.is_separate_file() || next_addr.file_type() != BLOCK_256)) + (next_addr.is_separate_file() || next_addr.file_type() != BLOCK_256)) { + STRESS_NOTREACHED(); return false; + } + STRESS_DCHECK(next_addr.value() != entry_.address().value()); if (!rankings_addr.SanityCheck() || !next_addr.SanityCheck()) return false; @@ -658,6 +661,7 @@ void EntryImpl::FixForDelete() { if ((data_size <= kMaxBlockSize && data_addr.is_separate_file()) || (data_size > kMaxBlockSize && data_addr.is_block_file()) || !data_addr.SanityCheck()) { + STRESS_NOTREACHED(); // The address is weird so don't attempt to delete it. stored->data_addr[i] = 0; // In general, trust the stored size as it should be in sync with the @@ -896,6 +900,9 @@ EntryImpl::~EntryImpl() { if (doomed_) { DeleteEntryData(true); } else { +#if defined(NET_BUILD_STRESS_CACHE) + SanityCheck(); +#endif net_log_.AddEvent(net::NetLog::TYPE_ENTRY_CLOSE, NULL); bool ret = true; for (int index = 0; index < kNumStreams; index++) { diff --git a/net/disk_cache/rankings.cc b/net/disk_cache/rankings.cc index 9f183f5..8b31088 100644 --- a/net/disk_cache/rankings.cc +++ b/net/disk_cache/rankings.cc @@ -9,6 +9,7 @@ #include "net/disk_cache/entry_impl.h" #include "net/disk_cache/errors.h" #include "net/disk_cache/histogram_macros.h" +#include "net/disk_cache/stress_support.h" using base::Time; using base::TimeTicks; @@ -313,14 +314,17 @@ void Rankings::Remove(CacheRankingsBlock* node, List list, bool strict) { !prev_addr.is_initialized() || prev_addr.is_separate_file()) { if (next_addr.is_initialized() || prev_addr.is_initialized()) { LOG(ERROR) << "Invalid rankings info."; + STRESS_NOTREACHED(); } return; } CacheRankingsBlock next(backend_->File(next_addr), next_addr); CacheRankingsBlock prev(backend_->File(prev_addr), prev_addr); - if (!GetRanking(&next) || !GetRanking(&prev)) + if (!GetRanking(&next) || !GetRanking(&prev)) { + STRESS_NOTREACHED(); return; + } if (!CheckLinks(node, &prev, &next, &list)) return; @@ -758,6 +762,8 @@ bool Rankings::CheckLinks(CacheRankingsBlock* node, CacheRankingsBlock* prev, } LOG(ERROR) << "Inconsistent LRU."; + STRESS_NOTREACHED(); + backend_->CriticalError(ERR_INVALID_LINKS); return false; } 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); diff --git a/net/disk_cache/stress_support.h b/net/disk_cache/stress_support.h new file mode 100644 index 0000000..68457fb0 --- /dev/null +++ b/net/disk_cache/stress_support.h @@ -0,0 +1,40 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_DISK_CACHE_STRESS_SUPPORT_H_ +#define NET_DISK_CACHE_STRESS_SUPPORT_H_ +#pragma once + +#include "base/logging.h" + +namespace disk_cache { + +// Uncomment this line to generate a debug build of stress_cache with checks +// to ensure that we are not producing corrupt entries. +// #define NET_BUILD_STRESS_CACHE 1 + +// Uncomment this line to direct the in-memory disk cache tracing to the base +// logging system. On Windows this option will enable ETW (Event Tracing for +// Windows) so logs across multiple runs can be collected. +// #define DISK_CACHE_TRACE_TO_LOG 1 + +// Uncomment this line to perform extended integrity checks during init. It is +// not recommended to enable this option unless some corruption is being tracked +// down. +// #define STRESS_CACHE_EXTENDED_VALIDATION 1 + +#if defined(NET_BUILD_STRESS_CACHE) +#define STRESS_NOTREACHED() NOTREACHED() +#define STRESS_DCHECK(a) DCHECK(a) +#else +// We don't support streams with these macros, but that's a small price to pay +// to have a straightforward logic here. Please don't add something like +// LogMessageVoidify. +#define STRESS_NOTREACHED() {} +#define STRESS_DCHECK(a) {} +#endif + +} // namespace disk_cache + +#endif // NET_DISK_CACHE_STRESS_SUPPORT_H_ diff --git a/net/disk_cache/trace.cc b/net/disk_cache/trace.cc index c16068a..15c083d 100644 --- a/net/disk_cache/trace.cc +++ b/net/disk_cache/trace.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,6 +10,7 @@ #endif #include "base/logging.h" +#include "net/disk_cache/stress_support.h" // Change this value to 1 to enable tracing on a release build. By default, // tracing is enabled only on debug builds. @@ -23,7 +24,13 @@ namespace { const int kEntrySize = 48; +#if defined(NET_BUILD_STRESS_CACHE) +const int kNumberOfEntries = 500000; +#else const int kNumberOfEntries = 5000; // 240 KB. +#endif + +bool s_trace_enabled = false; struct TraceBuffer { int num_traces; @@ -67,11 +74,16 @@ TraceObject::~TraceObject() { DestroyTrace(); } +void TraceObject::EnableTracing(bool enable) { + s_trace_enabled = enable; +} + #if ENABLE_TRACING static TraceBuffer* s_trace_buffer = NULL; void InitTrace(void) { + s_trace_enabled = true; if (s_trace_buffer) return; @@ -86,7 +98,7 @@ void DestroyTrace(void) { } void Trace(const char* format, ...) { - if (!s_trace_buffer) + if (!s_trace_buffer || !s_trace_enabled) return; va_list ap; @@ -99,6 +111,14 @@ void Trace(const char* format, ...) { sizeof(s_trace_buffer->buffer[s_trace_buffer->current]), format, ap); #endif + +#if defined(DISK_CACHE_TRACE_TO_LOG) + char line[kEntrySize + 2]; + memcpy(line, s_trace_buffer->buffer[s_trace_buffer->current], kEntrySize); + line[kEntrySize] = '\0'; + LOG(INFO) << line; +#endif + s_trace_buffer->num_traces++; s_trace_buffer->current++; if (s_trace_buffer->current == kNumberOfEntries) diff --git a/net/disk_cache/trace.h b/net/disk_cache/trace.h index 99a35bd..ed840c4 100644 --- a/net/disk_cache/trace.h +++ b/net/disk_cache/trace.h @@ -26,6 +26,7 @@ class TraceObject : public base::RefCounted<TraceObject> { friend class base::RefCounted<TraceObject>; public: static TraceObject* GetTraceObject(); + void EnableTracing(bool enable); private: TraceObject(); |