Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(516)

Side by Side Diff: chromecast/crash/linux/synchronized_minidump_manager.cc

Issue 2203123003: [Chromecast] Remove usage of nonreentrant functions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: synchronized_minidump_manager changes Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 #include "chromecast/crash/linux/synchronized_minidump_manager.h" 5 #include "chromecast/crash/linux/synchronized_minidump_manager.h"
6 6
7 #include <dirent.h>
8 #include <errno.h> 7 #include <errno.h>
9 #include <fcntl.h>
10 #include <stddef.h> 8 #include <stddef.h>
11 #include <stdint.h> 9 #include <stdint.h>
12 #include <string.h> 10 #include <string.h>
13 #include <sys/file.h>
14 #include <sys/stat.h> 11 #include <sys/stat.h>
bcf 2016/08/03 02:40:24 Can usage of stat.h, types,h, unistd.h be removed?
ameyak 2016/08/03 18:50:32 time_t/size_t are required and defined in sys/type
bcf 2016/08/03 20:45:10 Can you try to remove time_t usage?
ameyak 2016/08/04 15:25:30 Done.
15 #include <sys/types.h> 12 #include <sys/types.h>
16 #include <time.h> 13 #include <time.h>
17 #include <unistd.h> 14 #include <unistd.h>
18 15
19 #include <utility> 16 #include <utility>
20 17
21 #include "base/files/dir_reader_posix.h" 18 #include "base/files/dir_reader_posix.h"
22 #include "base/files/file_util.h" 19 #include "base/files/file_util.h"
23 #include "base/logging.h" 20 #include "base/logging.h"
24 #include "base/memory/ptr_util.h" 21 #include "base/memory/ptr_util.h"
22 #include "base/strings/string_number_conversions.h"
25 #include "base/strings/string_split.h" 23 #include "base/strings/string_split.h"
26 #include "base/strings/stringprintf.h" 24 #include "base/strings/stringprintf.h"
25 #include "chromecast/base/file_utils.h"
27 #include "chromecast/base/path_utils.h" 26 #include "chromecast/base/path_utils.h"
28 #include "chromecast/base/serializers.h" 27 #include "chromecast/base/serializers.h"
29 #include "chromecast/crash/linux/dump_info.h" 28 #include "chromecast/crash/linux/dump_info.h"
30 29
31 // if |cond| is false, returns |retval|. 30 // if |cond| is false, returns |retval|.
32 #define RCHECK(cond, retval) \ 31 #define RCHECK(cond, retval) \
33 do { \ 32 do { \
34 if (!(cond)) { \ 33 if (!(cond)) { \
35 return (retval); \ 34 return (retval); \
36 } \ 35 } \
37 } while (0) 36 } while (0)
38 37
39 namespace chromecast { 38 namespace chromecast {
40 39
41 namespace { 40 namespace {
42 41
43 const mode_t kDirMode = 0770;
44 const mode_t kFileMode = 0660;
45 const char kLockfileName[] = "lockfile"; 42 const char kLockfileName[] = "lockfile";
46 const char kMetadataName[] = "metadata"; 43 const char kMetadataName[] = "metadata";
47 const char kMinidumpsDir[] = "minidumps"; 44 const char kMinidumpsDir[] = "minidumps";
48 45
49 const char kLockfileRatelimitKey[] = "ratelimit"; 46 const char kLockfileRatelimitKey[] = "ratelimit";
50 const char kLockfileRatelimitPeriodStartKey[] = "period_start"; 47 const char kLockfileRatelimitPeriodStartKey[] = "period_start";
51 const char kLockfileRatelimitPeriodDumpsKey[] = "period_dumps"; 48 const char kLockfileRatelimitPeriodDumpsKey[] = "period_dumps";
52 const std::size_t kLockfileNumRatelimitParams = 2; 49 const std::size_t kLockfileNumRatelimitParams = 2;
53 50
54 // Gets the ratelimit parameter dictionary given a deserialized |metadata|. 51 // Gets the ratelimit parameter dictionary given a deserialized |metadata|.
(...skipping 14 matching lines...) Expand all
69 time_t GetRatelimitPeriodStart(base::Value* metadata) { 66 time_t GetRatelimitPeriodStart(base::Value* metadata) {
70 time_t result = static_cast<time_t>(-1); 67 time_t result = static_cast<time_t>(-1);
71 base::DictionaryValue* ratelimit_params = GetRatelimitParams(metadata); 68 base::DictionaryValue* ratelimit_params = GetRatelimitParams(metadata);
72 RCHECK(ratelimit_params, result); 69 RCHECK(ratelimit_params, result);
73 70
74 std::string period_start_str; 71 std::string period_start_str;
75 RCHECK(ratelimit_params->GetString(kLockfileRatelimitPeriodStartKey, 72 RCHECK(ratelimit_params->GetString(kLockfileRatelimitPeriodStartKey,
76 &period_start_str), 73 &period_start_str),
77 result); 74 result);
78 75
79 errno = 0; 76 base::StringToInt64(period_start_str, &result);
bcf 2016/08/03 02:40:23 Check return value.
ameyak 2016/08/03 18:50:32 Done. Overlooked that result can be changed even o
80 result = static_cast<time_t>(strtoll(period_start_str.c_str(), nullptr, 0));
81 if (errno != 0) {
82 return static_cast<time_t>(-1);
83 }
84
85 return result; 77 return result;
86 } 78 }
87 79
88 // Sets the time of the current ratelimit period's start in |metadata| to 80 // Sets the time of the current ratelimit period's start in |metadata| to
89 // |period_start|. Returns 0 on success, < 0 on error. 81 // |period_start|. Returns 0 on success, < 0 on error.
90 int SetRatelimitPeriodStart(base::Value* metadata, time_t period_start) { 82 int SetRatelimitPeriodStart(base::Value* metadata, time_t period_start) {
91 DCHECK_GE(period_start, 0); 83 DCHECK_GE(period_start, 0);
92 84
93 base::DictionaryValue* ratelimit_params = GetRatelimitParams(metadata); 85 base::DictionaryValue* ratelimit_params = GetRatelimitParams(metadata);
94 RCHECK(ratelimit_params, -1); 86 RCHECK(ratelimit_params, -1);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 GetRatelimitPeriodDumps(metadata) >= 0; 133 GetRatelimitPeriodDumps(metadata) >= 0;
142 } 134 }
143 135
144 } // namespace 136 } // namespace
145 137
146 // One day 138 // One day
147 const int SynchronizedMinidumpManager::kRatelimitPeriodSeconds = 24 * 3600; 139 const int SynchronizedMinidumpManager::kRatelimitPeriodSeconds = 24 * 3600;
148 const int SynchronizedMinidumpManager::kRatelimitPeriodMaxDumps = 100; 140 const int SynchronizedMinidumpManager::kRatelimitPeriodMaxDumps = 100;
149 141
150 SynchronizedMinidumpManager::SynchronizedMinidumpManager() 142 SynchronizedMinidumpManager::SynchronizedMinidumpManager()
151 : non_blocking_(false), 143 : dump_path_(GetHomePathASCII(kMinidumpsDir)),
152 dump_path_(GetHomePathASCII(kMinidumpsDir)),
153 lockfile_path_(dump_path_.Append(kLockfileName).value()), 144 lockfile_path_(dump_path_.Append(kLockfileName).value()),
154 metadata_path_(dump_path_.Append(kMetadataName).value()), 145 metadata_path_(dump_path_.Append(kMetadataName).value()),
155 lockfile_fd_(-1) { 146 initialized(false) {}
bcf 2016/08/03 02:40:24 How about instead call it "lock_held_"
ameyak 2016/08/03 18:50:32 Done.
156 }
157 147
158 SynchronizedMinidumpManager::~SynchronizedMinidumpManager() { 148 SynchronizedMinidumpManager::~SynchronizedMinidumpManager() {
159 // Release the lock if held. 149 // Release the lock if held.
160 ReleaseLockFile(); 150 ReleaseLockFile();
161 } 151 }
162 152
163 // TODO(slan): Move some of this pruning logic to ReleaseLockFile? 153 // TODO(slan): Move some of this pruning logic to ReleaseLockFile?
164 int SynchronizedMinidumpManager::GetNumDumps(bool delete_all_dumps) { 154 int SynchronizedMinidumpManager::GetNumDumps(bool delete_all_dumps) {
165 DIR* dirp;
166 struct dirent* dptr;
167 int num_dumps = 0; 155 int num_dumps = 0;
168 156
169 // folder does not exist 157 base::DirReaderPosix reader(dump_path_.value().c_str());
170 dirp = opendir(dump_path_.value().c_str()); 158 if (!reader.IsValid()) {
171 if (dirp == NULL) {
172 LOG(ERROR) << "Unable to open directory " << dump_path_.value(); 159 LOG(ERROR) << "Unable to open directory " << dump_path_.value();
173 return 0; 160 return 0;
174 } 161 }
175 162
176 while ((dptr = readdir(dirp)) != NULL) { 163 while (reader.Next()) {
177 struct stat buf; 164 if (strcmp(reader.name(), ".") == 0 || strcmp(reader.name(), "..") == 0)
178 const std::string file_fullname = dump_path_.value() + "/" + dptr->d_name;
179 if (lstat(file_fullname.c_str(), &buf) == -1 || !S_ISREG(buf.st_mode)) {
180 // if we cannot lstat this file, it is probably bad, so skip
181 // if the file is not regular, skip
182 continue; 165 continue;
183 }
184 166
185 // 'lockfile' and 'metadata' is not counted 167 const base::FilePath dump_file(dump_path_.Append(reader.name()));
186 if (lockfile_path_ != file_fullname && metadata_path_ != file_fullname) { 168 // If file cannot be found, skip.
169 if (!base::PathExists(dump_file))
170 continue;
171
172 // Do not count |lockfile_path_| and |metadata_path_|.
173 if (lockfile_path_ != dump_file && metadata_path_ != dump_file) {
187 ++num_dumps; 174 ++num_dumps;
188 if (delete_all_dumps) { 175 if (delete_all_dumps) {
189 LOG(INFO) << "Removing " << dptr->d_name 176 LOG(INFO) << "Removing " << reader.name()
190 << "which was not in the lockfile"; 177 << "which was not in the lockfile";
191 if (remove(file_fullname.c_str()) < 0) { 178 if (!base::DeleteFile(dump_file, false)) {
192 LOG(INFO) << "remove failed. error " << strerror(errno); 179 LOG(INFO) << "remove failed. error " << strerror(errno);
193 } 180 }
194 } 181 }
195 } 182 }
196 } 183 }
197 184
198 closedir(dirp);
199 return num_dumps; 185 return num_dumps;
200 } 186 }
201 187
202 int SynchronizedMinidumpManager::AcquireLockAndDoWork() { 188 int SynchronizedMinidumpManager::AcquireLockAndDoWork() {
203 int success = -1; 189 int success = -1;
204 if (AcquireLockFile() >= 0) { 190 if (AcquireLockFile() >= 0) {
205 success = DoWork(); 191 success = DoWork();
206 ReleaseLockFile(); 192 ReleaseLockFile();
207 } 193 }
208 return success; 194 return success;
209 } 195 }
210 196
211 int SynchronizedMinidumpManager::AcquireLockFile() { 197 int SynchronizedMinidumpManager::AcquireLockFile() {
212 DCHECK_LT(lockfile_fd_, 0); 198 DCHECK(!initialized);
213 // Make the directory for the minidumps if it does not exist. 199 // Make the directory for the minidumps if it does not exist.
214 if (mkdir(dump_path_.value().c_str(), kDirMode) < 0 && errno != EEXIST) { 200 if (!CreateDirectory(dump_path_)) {
bcf 2016/08/03 02:40:24 This uses mode 0700. Can you make sure this works?
ameyak 2016/08/03 18:50:32 Acknowledged. Seems ok, as discussed.
215 LOG(ERROR) << "mkdir for " << dump_path_.value().c_str() 201 LOG(ERROR) << "mkdir for " << dump_path_.value() << " failed.";
216 << " failed. error = " << strerror(errno);
217 return -1; 202 return -1;
218 } 203 }
219 204
220 // Open the lockfile. Create it if it does not exist. 205 // Open the lockfile. Create it if it does not exist.
221 lockfile_fd_ = open(lockfile_path_.c_str(), O_RDWR | O_CREAT, kFileMode); 206 base::File lockfile(lockfile_path_, base::File::FLAG_OPEN_ALWAYS);
222 207
223 // If opening or creating the lockfile failed, we don't want to proceed 208 // If opening or creating the lockfile failed, we don't want to proceed
224 // with dump writing for fear of exhausting up system resources. 209 // with dump writing for fear of exhausting up system resources.
225 if (lockfile_fd_ < 0) { 210 if (!lockfile.IsValid()) {
226 LOG(ERROR) << "open lockfile failed " << lockfile_path_; 211 LOG(ERROR) << "open lockfile failed " << lockfile_path_.value();
227 return -1; 212 return -1;
228 } 213 }
229 214
230 // Acquire the lock on the file. Whether or not we are in non-blocking mode, 215 if (!LockFile(lockfile_path_)) {
231 // flock failure means that we did not acquire it and this method should fail.
232 int operation_mode = non_blocking_ ? (LOCK_EX | LOCK_NB) : LOCK_EX;
233 if (flock(lockfile_fd_, operation_mode) < 0) {
234 ReleaseLockFile(); 216 ReleaseLockFile();
235 LOG(INFO) << "flock lockfile failed, error = " << strerror(errno);
236 return -1; 217 return -1;
237 } 218 }
238 219
220 initialized = true;
221
239 // The lockfile is open and locked. Parse it to provide subclasses with a 222 // The lockfile is open and locked. Parse it to provide subclasses with a
240 // record of all the current dumps. 223 // record of all the current dumps.
241 if (ParseFiles() < 0) { 224 if (ParseFiles() < 0) {
242 LOG(ERROR) << "Lockfile did not parse correctly. "; 225 LOG(ERROR) << "Lockfile did not parse correctly. ";
243 if (InitializeFiles() < 0 || ParseFiles() < 0) { 226 if (InitializeFiles() < 0 || ParseFiles() < 0) {
244 LOG(ERROR) << "Failed to create a new lock file!"; 227 LOG(ERROR) << "Failed to create a new lock file!";
245 return -1; 228 return -1;
246 } 229 }
247 } 230 }
248 231
249 DCHECK(dumps_); 232 DCHECK(dumps_);
250 DCHECK(metadata_); 233 DCHECK(metadata_);
251 234
252 // We successfully have acquired the lock. 235 // We successfully have acquired the lock.
253 return 0; 236 return 0;
254 } 237 }
255 238
256 int SynchronizedMinidumpManager::ParseFiles() { 239 int SynchronizedMinidumpManager::ParseFiles() {
257 DCHECK_GE(lockfile_fd_, 0); 240 DCHECK(initialized);
258 DCHECK(!dumps_); 241 DCHECK(!dumps_);
259 DCHECK(!metadata_); 242 DCHECK(!metadata_);
260 243
261 std::string lockfile; 244 std::string lockfile;
262 RCHECK(ReadFileToString(base::FilePath(lockfile_path_), &lockfile), -1); 245 RCHECK(ReadFileToString(lockfile_path_, &lockfile), -1);
263 246
264 std::vector<std::string> lines = base::SplitString( 247 std::vector<std::string> lines = base::SplitString(
265 lockfile, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); 248 lockfile, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
266 249
267 std::unique_ptr<base::ListValue> dumps = 250 std::unique_ptr<base::ListValue> dumps =
268 base::WrapUnique(new base::ListValue()); 251 base::WrapUnique(new base::ListValue());
269 252
270 // Validate dumps 253 // Validate dumps
271 for (const std::string& line : lines) { 254 for (const std::string& line : lines) {
272 if (line.size() == 0) 255 if (line.size() == 0)
273 continue; 256 continue;
274 std::unique_ptr<base::Value> dump_info = DeserializeFromJson(line); 257 std::unique_ptr<base::Value> dump_info = DeserializeFromJson(line);
275 DumpInfo info(dump_info.get()); 258 DumpInfo info(dump_info.get());
276 RCHECK(info.valid(), -1); 259 RCHECK(info.valid(), -1);
277 dumps->Append(std::move(dump_info)); 260 dumps->Append(std::move(dump_info));
278 } 261 }
279 262
280 std::unique_ptr<base::Value> metadata = 263 std::unique_ptr<base::Value> metadata =
281 DeserializeJsonFromFile(base::FilePath(metadata_path_)); 264 DeserializeJsonFromFile(metadata_path_);
282 RCHECK(ValidateMetadata(metadata.get()), -1); 265 RCHECK(ValidateMetadata(metadata.get()), -1);
283 266
284 dumps_ = std::move(dumps); 267 dumps_ = std::move(dumps);
285 metadata_ = std::move(metadata); 268 metadata_ = std::move(metadata);
286 return 0; 269 return 0;
287 } 270 }
288 271
289 int SynchronizedMinidumpManager::WriteFiles(const base::ListValue* dumps, 272 int SynchronizedMinidumpManager::WriteFiles(const base::ListValue* dumps,
290 const base::Value* metadata) { 273 const base::Value* metadata) {
291 DCHECK(dumps); 274 DCHECK(dumps);
292 DCHECK(metadata); 275 DCHECK(metadata);
293 std::string lockfile; 276 std::string lockfile;
294 277
295 for (const auto& elem : *dumps) { 278 for (const auto& elem : *dumps) {
296 std::unique_ptr<std::string> dump_info = SerializeToJson(*elem); 279 std::unique_ptr<std::string> dump_info = SerializeToJson(*elem);
297 RCHECK(dump_info, -1); 280 RCHECK(dump_info, -1);
298 lockfile += *dump_info; 281 lockfile += *dump_info;
299 lockfile += "\n"; // Add line seperatators 282 lockfile += "\n"; // Add line seperatators
300 } 283 }
301 284
302 if (WriteFile(base::FilePath(lockfile_path_), 285 if (WriteFile(lockfile_path_, lockfile.c_str(), lockfile.size()) < 0) {
303 lockfile.c_str(),
304 lockfile.size()) < 0) {
305 return -1; 286 return -1;
306 } 287 }
307 288
308 return SerializeJsonToFile(base::FilePath(metadata_path_), *metadata) ? 0 289 return SerializeJsonToFile(metadata_path_, *metadata) ? 0 : -1;
309 : -1;
310 } 290 }
311 291
312 int SynchronizedMinidumpManager::InitializeFiles() { 292 int SynchronizedMinidumpManager::InitializeFiles() {
313 std::unique_ptr<base::DictionaryValue> metadata = 293 std::unique_ptr<base::DictionaryValue> metadata =
314 base::WrapUnique(new base::DictionaryValue()); 294 base::WrapUnique(new base::DictionaryValue());
315 295
316 base::DictionaryValue* ratelimit_fields = new base::DictionaryValue(); 296 base::DictionaryValue* ratelimit_fields = new base::DictionaryValue();
317 metadata->Set(kLockfileRatelimitKey, base::WrapUnique(ratelimit_fields)); 297 metadata->Set(kLockfileRatelimitKey, base::WrapUnique(ratelimit_fields));
318 ratelimit_fields->SetString(kLockfileRatelimitPeriodStartKey, "0"); 298 ratelimit_fields->SetString(kLockfileRatelimitPeriodStartKey, "0");
319 ratelimit_fields->SetInteger(kLockfileRatelimitPeriodDumpsKey, 0); 299 ratelimit_fields->SetInteger(kLockfileRatelimitPeriodDumpsKey, 0);
320 300
321 std::unique_ptr<base::ListValue> dumps = 301 std::unique_ptr<base::ListValue> dumps =
322 base::WrapUnique(new base::ListValue()); 302 base::WrapUnique(new base::ListValue());
323 303
324 return WriteFiles(dumps.get(), metadata.get()); 304 return WriteFiles(dumps.get(), metadata.get());
325 } 305 }
326 306
327 int SynchronizedMinidumpManager::AddEntryToLockFile(const DumpInfo& dump_info) { 307 int SynchronizedMinidumpManager::AddEntryToLockFile(const DumpInfo& dump_info) {
328 DCHECK_LE(0, lockfile_fd_); 308 DCHECK(initialized);
329 DCHECK(dumps_); 309 DCHECK(dumps_);
330 310
331 // Make sure dump_info is valid. 311 // Make sure dump_info is valid.
332 if (!dump_info.valid()) { 312 if (!dump_info.valid()) {
333 LOG(ERROR) << "Entry to be added is invalid"; 313 LOG(ERROR) << "Entry to be added is invalid";
334 return -1; 314 return -1;
335 } 315 }
336 316
337 dumps_->Append(dump_info.GetAsValue()); 317 dumps_->Append(dump_info.GetAsValue());
338 318
339 return 0; 319 return 0;
340 } 320 }
341 321
342 int SynchronizedMinidumpManager::RemoveEntryFromLockFile(int index) { 322 int SynchronizedMinidumpManager::RemoveEntryFromLockFile(int index) {
343 return dumps_->Remove(static_cast<size_t>(index), nullptr) ? 0 : -1; 323 return dumps_->Remove(static_cast<size_t>(index), nullptr) ? 0 : -1;
344 } 324 }
345 325
346 void SynchronizedMinidumpManager::ReleaseLockFile() { 326 void SynchronizedMinidumpManager::ReleaseLockFile() {
347 // flock is associated with the fd entry in the open fd table, so closing 327 // flock is associated with the fd entry in the open fd table, so closing
348 // all fd's will release the lock. To be safe, we explicitly unlock. 328 // all fd's will release the lock. To be safe, we explicitly unlock.
349 if (lockfile_fd_ >= 0) { 329 if (initialized) {
350 if (dumps_) 330 if (dumps_)
351 WriteFiles(dumps_.get(), metadata_.get()); 331 WriteFiles(dumps_.get(), metadata_.get());
352 332
353 flock(lockfile_fd_, LOCK_UN); 333 chromecast::UnlockFile(lockfile_path_);
354 close(lockfile_fd_); 334 initialized = false;
355
356 // We may use this object again, so we should reset this.
357 lockfile_fd_ = -1;
358 } 335 }
359 336
360 dumps_.reset(); 337 dumps_.reset();
361 metadata_.reset(); 338 metadata_.reset();
362 } 339 }
363 340
364 ScopedVector<DumpInfo> SynchronizedMinidumpManager::GetDumps() { 341 ScopedVector<DumpInfo> SynchronizedMinidumpManager::GetDumps() {
365 ScopedVector<DumpInfo> dumps; 342 ScopedVector<DumpInfo> dumps;
366 343
367 for (const auto& elem : *dumps_) { 344 for (const auto& elem : *dumps_) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 SetRatelimitPeriodStart(metadata_.get(), period_start); 384 SetRatelimitPeriodStart(metadata_.get(), period_start);
408 SetRatelimitPeriodDumps(metadata_.get(), period_dumps_count); 385 SetRatelimitPeriodDumps(metadata_.get(), period_dumps_count);
409 } 386 }
410 387
411 return period_dumps_count < kRatelimitPeriodMaxDumps; 388 return period_dumps_count < kRatelimitPeriodMaxDumps;
412 } 389 }
413 390
414 bool SynchronizedMinidumpManager::HasDumps() { 391 bool SynchronizedMinidumpManager::HasDumps() {
415 // Check if lockfile has entries. 392 // Check if lockfile has entries.
416 int64_t size = 0; 393 int64_t size = 0;
417 if (GetFileSize(base::FilePath(lockfile_path_), &size) && size > 0) 394 if (base::GetFileSize(lockfile_path_, &size) && size > 0)
418 return true; 395 return true;
419 396
420 // Check if any files are in minidump directory 397 // Check if any files are in minidump directory
421 base::DirReaderPosix reader(dump_path_.value().c_str()); 398 base::DirReaderPosix reader(dump_path_.value().c_str());
422 if (!reader.IsValid()) { 399 if (!reader.IsValid()) {
423 DLOG(FATAL) << "Could not open minidump dir: " << dump_path_.value(); 400 DLOG(FATAL) << "Could not open minidump dir: " << dump_path_.value();
424 return false; 401 return false;
425 } 402 }
426 403
427 while (reader.Next()) { 404 while (reader.Next()) {
428 if (strcmp(reader.name(), ".") == 0 || strcmp(reader.name(), "..") == 0) 405 if (strcmp(reader.name(), ".") == 0 || strcmp(reader.name(), "..") == 0)
429 continue; 406 continue;
430 407
431 const std::string file_path = dump_path_.Append(reader.name()).value(); 408 const base::FilePath file_path = dump_path_.Append(reader.name());
432 if (file_path != lockfile_path_ && file_path != metadata_path_) 409 if (file_path != lockfile_path_ && file_path != metadata_path_)
433 return true; 410 return true;
434 } 411 }
435 412
436 return false; 413 return false;
437 } 414 }
438 415
439 } // namespace chromecast 416 } // namespace chromecast
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698