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 |