| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Performs basic inspection of the disk cache files with minimal disruption | 5 // Performs basic inspection of the disk cache files with minimal disruption |
| 6 // to the actual files (they still may change if an error is detected on the | 6 // to the actual files (they still may change if an error is detected on the |
| 7 // files). | 7 // files). |
| 8 | 8 |
| 9 #include <set> |
| 9 #include <stdio.h> | 10 #include <stdio.h> |
| 10 #include <string> | 11 #include <string> |
| 11 | 12 |
| 12 #include "base/file_util.h" | 13 #include "base/file_util.h" |
| 13 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
| 14 #include "net/base/file_stream.h" | 15 #include "net/base/file_stream.h" |
| 15 #include "net/disk_cache/block_files.h" | 16 #include "net/disk_cache/block_files.h" |
| 16 #include "net/disk_cache/disk_format.h" | 17 #include "net/disk_cache/disk_format.h" |
| 17 #include "net/disk_cache/mapped_file.h" | 18 #include "net/disk_cache/mapped_file.h" |
| 18 #include "net/disk_cache/storage_block.h" | 19 #include "net/disk_cache/storage_block.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 printf("entries: %d\n", header.num_entries); | 61 printf("entries: %d\n", header.num_entries); |
| 61 printf("total bytes: %d\n", header.num_bytes); | 62 printf("total bytes: %d\n", header.num_bytes); |
| 62 printf("last file number: %d\n", header.last_file); | 63 printf("last file number: %d\n", header.last_file); |
| 63 printf("current id: %d\n", header.this_id); | 64 printf("current id: %d\n", header.this_id); |
| 64 printf("table length: %d\n", header.table_len); | 65 printf("table length: %d\n", header.table_len); |
| 65 printf("last crash: %d\n", header.crash); | 66 printf("last crash: %d\n", header.crash); |
| 66 printf("experiment: %d\n", header.experiment); | 67 printf("experiment: %d\n", header.experiment); |
| 67 for (int i = 0; i < 5; i++) { | 68 for (int i = 0; i < 5; i++) { |
| 68 printf("head %d: 0x%x\n", i, header.lru.heads[i]); | 69 printf("head %d: 0x%x\n", i, header.lru.heads[i]); |
| 69 printf("tail %d: 0x%x\n", i, header.lru.tails[i]); | 70 printf("tail %d: 0x%x\n", i, header.lru.tails[i]); |
| 71 printf("size %d: 0x%x\n", i, header.lru.sizes[i]); |
| 70 } | 72 } |
| 71 printf("transaction: 0x%x\n", header.lru.transaction); | 73 printf("transaction: 0x%x\n", header.lru.transaction); |
| 72 printf("operation: %d\n", header.lru.operation); | 74 printf("operation: %d\n", header.lru.operation); |
| 73 printf("operation list: %d\n", header.lru.operation_list); | 75 printf("operation list: %d\n", header.lru.operation_list); |
| 74 printf("-------------------------\n\n"); | 76 printf("-------------------------\n\n"); |
| 75 } | 77 } |
| 76 | 78 |
| 77 // Dumps the contents of a block-file header. | 79 // Dumps the contents of a block-file header. |
| 78 void DumpBlockHeader(const std::wstring& name) { | 80 void DumpBlockHeader(const std::wstring& name) { |
| 79 disk_cache::BlockFileHeader header; | 81 disk_cache::BlockFileHeader header; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 bool LoadRankings(disk_cache::CacheAddr addr, | 126 bool LoadRankings(disk_cache::CacheAddr addr, |
| 125 disk_cache::RankingsNode* rankings); | 127 disk_cache::RankingsNode* rankings); |
| 126 | 128 |
| 127 private: | 129 private: |
| 128 std::wstring path_; | 130 std::wstring path_; |
| 129 disk_cache::BlockFiles block_files_; | 131 disk_cache::BlockFiles block_files_; |
| 130 scoped_refptr<disk_cache::MappedFile> index_file_; | 132 scoped_refptr<disk_cache::MappedFile> index_file_; |
| 131 disk_cache::Index* index_; | 133 disk_cache::Index* index_; |
| 132 int current_hash_; | 134 int current_hash_; |
| 133 disk_cache::CacheAddr next_addr_; | 135 disk_cache::CacheAddr next_addr_; |
| 136 std::set<disk_cache::CacheAddr> dumped_entries_; |
| 134 DISALLOW_COPY_AND_ASSIGN(CacheDumper); | 137 DISALLOW_COPY_AND_ASSIGN(CacheDumper); |
| 135 }; | 138 }; |
| 136 | 139 |
| 137 bool CacheDumper::Init() { | 140 bool CacheDumper::Init() { |
| 138 if (!block_files_.Init(false)) { | 141 if (!block_files_.Init(false)) { |
| 139 printf("Unable to init block files\n"); | 142 printf("Unable to init block files\n"); |
| 140 return false; | 143 return false; |
| 141 } | 144 } |
| 142 | 145 |
| 143 std::wstring index_name(path_); | 146 std::wstring index_name(path_); |
| 144 file_util::AppendToPath(&index_name, kIndexName); | 147 file_util::AppendToPath(&index_name, kIndexName); |
| 145 index_file_ = new disk_cache::MappedFile; | 148 index_file_ = new disk_cache::MappedFile; |
| 146 index_ = reinterpret_cast<disk_cache::Index*>(index_file_->Init( | 149 index_ = reinterpret_cast<disk_cache::Index*>(index_file_->Init( |
| 147 FilePath::FromWStringHack(index_name), 0)); | 150 FilePath::FromWStringHack(index_name), 0)); |
| 148 if (!index_) { | 151 if (!index_) { |
| 149 printf("Unable to map index\n"); | 152 printf("Unable to map index\n"); |
| 150 return false; | 153 return false; |
| 151 } | 154 } |
| 152 | 155 |
| 153 return true; | 156 return true; |
| 154 } | 157 } |
| 155 | 158 |
| 156 bool CacheDumper::GetEntry(disk_cache::EntryStore* entry) { | 159 bool CacheDumper::GetEntry(disk_cache::EntryStore* entry) { |
| 160 if (dumped_entries_.find(next_addr_) != dumped_entries_.end()) { |
| 161 printf("Loop detected\n"); |
| 162 next_addr_ = 0; |
| 163 current_hash_++; |
| 164 } |
| 165 |
| 157 if (next_addr_) { | 166 if (next_addr_) { |
| 158 if (LoadEntry(next_addr_, entry)) { | 167 if (LoadEntry(next_addr_, entry)) |
| 159 next_addr_ = entry->next; | |
| 160 if (!next_addr_) | |
| 161 current_hash_++; | |
| 162 return true; | 168 return true; |
| 163 } else { | 169 |
| 164 printf("Unable to load entry at address 0x%x\n", next_addr_); | 170 printf("Unable to load entry at address 0x%x\n", next_addr_); |
| 165 next_addr_ = 0; | 171 next_addr_ = 0; |
| 166 current_hash_++; | 172 current_hash_++; |
| 167 } | |
| 168 } | 173 } |
| 169 | 174 |
| 170 for (int i = current_hash_; i < index_->header.table_len; i++) { | 175 for (int i = current_hash_; i < index_->header.table_len; i++) { |
| 171 // Yes, we'll crash if the table is shorter than expected, but only after | 176 // Yes, we'll crash if the table is shorter than expected, but only after |
| 172 // dumping every entry that we can find. | 177 // dumping every entry that we can find. |
| 173 if (index_->table[i]) { | 178 if (index_->table[i]) { |
| 174 current_hash_ = i; | 179 current_hash_ = i; |
| 175 if (LoadEntry(index_->table[i], entry)) { | 180 if (LoadEntry(index_->table[i], entry)) |
| 176 next_addr_ = entry->next; | |
| 177 if (!next_addr_) | |
| 178 current_hash_++; | |
| 179 return true; | 181 return true; |
| 180 } else { | 182 |
| 181 printf("Unable to load entry at address 0x%x\n", index_->table[i]); | 183 printf("Unable to load entry at address 0x%x\n", index_->table[i]); |
| 182 } | |
| 183 } | 184 } |
| 184 } | 185 } |
| 185 return false; | 186 return false; |
| 186 } | 187 } |
| 187 | 188 |
| 188 bool CacheDumper::LoadEntry(disk_cache::CacheAddr addr, | 189 bool CacheDumper::LoadEntry(disk_cache::CacheAddr addr, |
| 189 disk_cache::EntryStore* entry) { | 190 disk_cache::EntryStore* entry) { |
| 190 disk_cache::Addr address(addr); | 191 disk_cache::Addr address(addr); |
| 191 disk_cache::MappedFile* file = block_files_.GetFile(address); | 192 disk_cache::MappedFile* file = block_files_.GetFile(address); |
| 192 if (!file) | 193 if (!file) |
| 193 return false; | 194 return false; |
| 194 | 195 |
| 195 disk_cache::CacheEntryBlock entry_block(file, address); | 196 disk_cache::CacheEntryBlock entry_block(file, address); |
| 196 if (!entry_block.Load()) | 197 if (!entry_block.Load()) |
| 197 return false; | 198 return false; |
| 198 | 199 |
| 199 memcpy(entry, entry_block.Data(), sizeof(*entry)); | 200 memcpy(entry, entry_block.Data(), sizeof(*entry)); |
| 200 printf("Entry at 0x%x\n", addr); | 201 printf("Entry at 0x%x\n", addr); |
| 202 |
| 203 // Prepare for the next entry to load. |
| 204 next_addr_ = entry->next; |
| 205 if (next_addr_) { |
| 206 dumped_entries_.insert(addr); |
| 207 } else { |
| 208 current_hash_++; |
| 209 dumped_entries_.clear(); |
| 210 } |
| 201 return true; | 211 return true; |
| 202 } | 212 } |
| 203 | 213 |
| 204 bool CacheDumper::LoadRankings(disk_cache::CacheAddr addr, | 214 bool CacheDumper::LoadRankings(disk_cache::CacheAddr addr, |
| 205 disk_cache::RankingsNode* rankings) { | 215 disk_cache::RankingsNode* rankings) { |
| 206 disk_cache::Addr address(addr); | 216 disk_cache::Addr address(addr); |
| 207 disk_cache::MappedFile* file = block_files_.GetFile(address); | 217 disk_cache::MappedFile* file = block_files_.GetFile(address); |
| 208 if (!file) | 218 if (!file) |
| 209 return false; | 219 return false; |
| 210 | 220 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 DumpEntry(entry); | 318 DumpEntry(entry); |
| 309 disk_cache::RankingsNode rankings; | 319 disk_cache::RankingsNode rankings; |
| 310 if (dumper.LoadRankings(entry.rankings_node, &rankings)) | 320 if (dumper.LoadRankings(entry.rankings_node, &rankings)) |
| 311 DumpRankings(rankings); | 321 DumpRankings(rankings); |
| 312 } | 322 } |
| 313 | 323 |
| 314 printf("Done.\n"); | 324 printf("Done.\n"); |
| 315 | 325 |
| 316 return 0; | 326 return 0; |
| 317 } | 327 } |
| OLD | NEW |