OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "components/browser_watcher/stability_paths.h" | 5 #include "components/browser_watcher/stability_paths.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <windows.h> | 8 #include <windows.h> |
9 #endif // defined(OS_WIN) | 9 #endif // defined(OS_WIN) |
10 | 10 |
11 #include <memory> | 11 #include <memory> |
12 #include <string> | 12 #include <string> |
13 #include <utility> | 13 #include <utility> |
14 | 14 |
15 #include "base/debug/activity_tracker.h" | 15 #include "base/debug/activity_tracker.h" |
16 #include "base/feature_list.h" | 16 #include "base/feature_list.h" |
17 #include "base/files/file.h" | 17 #include "base/files/file.h" |
| 18 #include "base/files/file_enumerator.h" |
18 #include "base/files/memory_mapped_file.h" | 19 #include "base/files/memory_mapped_file.h" |
19 #include "base/metrics/persistent_memory_allocator.h" | 20 #include "base/metrics/persistent_memory_allocator.h" |
20 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
21 #include "base/time/time.h" | 22 #include "base/time/time.h" |
22 #include "components/browser_watcher/features.h" | 23 #include "components/browser_watcher/features.h" |
23 #include "components/browser_watcher/stability_metrics.h" | 24 #include "components/browser_watcher/stability_metrics.h" |
24 | 25 |
25 #if defined(OS_WIN) | 26 #if defined(OS_WIN) |
26 | 27 |
27 #include "third_party/crashpad/crashpad/util/win/time.h" | 28 #include "third_party/crashpad/crashpad/util/win/time.h" |
28 | 29 |
29 namespace browser_watcher { | 30 namespace browser_watcher { |
30 | 31 |
| 32 using base::FilePath; |
31 using base::FilePersistentMemoryAllocator; | 33 using base::FilePersistentMemoryAllocator; |
32 using base::MemoryMappedFile; | 34 using base::MemoryMappedFile; |
33 using base::PersistentMemoryAllocator; | 35 using base::PersistentMemoryAllocator; |
34 | 36 |
35 namespace { | 37 namespace { |
36 | 38 |
37 bool GetCreationTime(const base::Process& process, FILETIME* creation_time) { | 39 bool GetCreationTime(const base::Process& process, FILETIME* creation_time) { |
38 FILETIME ignore; | 40 FILETIME ignore; |
39 return ::GetProcessTimes(process.Handle(), creation_time, &ignore, &ignore, | 41 return ::GetProcessTimes(process.Handle(), creation_time, &ignore, &ignore, |
40 &ignore) != 0; | 42 &ignore) != 0; |
41 } | 43 } |
42 | 44 |
43 bool SetPmaFileDeleted(const base::FilePath& file_path) { | 45 bool SetPmaFileDeleted(const base::FilePath& file_path) { |
44 // Map the file read-write so it can guarantee consistency between | 46 // Map the file read-write so it can guarantee consistency between |
45 // the analyzer and any trackers that may still be active. | 47 // the analyzer and any trackers that may still be active. |
46 std::unique_ptr<MemoryMappedFile> mmfile(new MemoryMappedFile()); | 48 std::unique_ptr<MemoryMappedFile> mmfile(new MemoryMappedFile()); |
47 mmfile->Initialize(file_path, MemoryMappedFile::READ_WRITE); | 49 mmfile->Initialize(file_path, MemoryMappedFile::READ_WRITE); |
48 if (!mmfile->IsValid()) | 50 if (!mmfile->IsValid()) |
49 return false; | 51 return false; |
50 if (!FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile, true)) | 52 if (!FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile, true)) |
51 return false; | 53 return false; |
52 FilePersistentMemoryAllocator allocator(std::move(mmfile), 0, 0, | 54 FilePersistentMemoryAllocator allocator(std::move(mmfile), 0, 0, |
53 base::StringPiece(), true); | 55 base::StringPiece(), true); |
54 allocator.SetMemoryState(PersistentMemoryAllocator::MEMORY_DELETED); | 56 allocator.SetMemoryState(PersistentMemoryAllocator::MEMORY_DELETED); |
55 return true; | 57 return true; |
56 } | 58 } |
57 | 59 |
58 } // namespace | 60 } // namespace |
59 | 61 |
60 base::FilePath GetStabilityDir(const base::FilePath& user_data_dir) { | 62 FilePath GetStabilityDir(const FilePath& user_data_dir) { |
61 return user_data_dir.AppendASCII("Stability"); | 63 return user_data_dir.AppendASCII("Stability"); |
62 } | 64 } |
63 | 65 |
64 base::FilePath GetStabilityFileForProcess(base::ProcessId pid, | 66 FilePath GetStabilityFileForProcess(base::ProcessId pid, |
65 timeval creation_time, | 67 timeval creation_time, |
66 const base::FilePath& user_data_dir) { | 68 const FilePath& user_data_dir) { |
67 base::FilePath stability_dir = GetStabilityDir(user_data_dir); | 69 FilePath stability_dir = GetStabilityDir(user_data_dir); |
68 | 70 |
69 constexpr uint64_t kMicrosecondsPerSecond = static_cast<uint64_t>(1E6); | 71 constexpr uint64_t kMicrosecondsPerSecond = static_cast<uint64_t>(1E6); |
70 int64_t creation_time_us = | 72 int64_t creation_time_us = |
71 creation_time.tv_sec * kMicrosecondsPerSecond + creation_time.tv_usec; | 73 creation_time.tv_sec * kMicrosecondsPerSecond + creation_time.tv_usec; |
72 | 74 |
73 std::string file_name = base::StringPrintf("%u-%lld", pid, creation_time_us); | 75 std::string file_name = base::StringPrintf("%u-%lld", pid, creation_time_us); |
74 return stability_dir.AppendASCII(file_name).AddExtension( | 76 return stability_dir.AppendASCII(file_name).AddExtension( |
75 base::PersistentMemoryAllocator::kFileExtension); | 77 base::PersistentMemoryAllocator::kFileExtension); |
76 } | 78 } |
77 | 79 |
78 bool GetStabilityFileForProcess(const base::Process& process, | 80 bool GetStabilityFileForProcess(const base::Process& process, |
79 const base::FilePath& user_data_dir, | 81 const FilePath& user_data_dir, |
80 base::FilePath* file_path) { | 82 FilePath* file_path) { |
81 DCHECK(file_path); | 83 DCHECK(file_path); |
82 | 84 |
83 FILETIME creation_time; | 85 FILETIME creation_time; |
84 if (!GetCreationTime(process, &creation_time)) | 86 if (!GetCreationTime(process, &creation_time)) |
85 return false; | 87 return false; |
86 | 88 |
87 // We rely on Crashpad's conversion to ensure the resulting filename is the | 89 // We rely on Crashpad's conversion to ensure the resulting filename is the |
88 // same as on crash, when the creation time is obtained via Crashpad. | 90 // same as on crash, when the creation time is obtained via Crashpad. |
89 *file_path = GetStabilityFileForProcess( | 91 *file_path = GetStabilityFileForProcess( |
90 process.Pid(), crashpad::FiletimeToTimevalEpoch(creation_time), | 92 process.Pid(), crashpad::FiletimeToTimevalEpoch(creation_time), |
91 user_data_dir); | 93 user_data_dir); |
92 return true; | 94 return true; |
93 } | 95 } |
94 | 96 |
95 base::FilePath::StringType GetStabilityFilePattern() { | 97 FilePath::StringType GetStabilityFilePattern() { |
96 return base::FilePath::StringType(FILE_PATH_LITERAL("*-*")) + | 98 return FilePath::StringType(FILE_PATH_LITERAL("*-*")) + |
97 base::PersistentMemoryAllocator::kFileExtension; | 99 base::PersistentMemoryAllocator::kFileExtension; |
98 } | 100 } |
99 | 101 |
| 102 std::vector<FilePath> GetStabilityFiles( |
| 103 const FilePath& stability_dir, |
| 104 const FilePath::StringType& stability_file_pattern, |
| 105 const std::set<FilePath>& excluded_stability_files) { |
| 106 DCHECK_NE(true, stability_dir.empty()); |
| 107 DCHECK_NE(true, stability_file_pattern.empty()); |
| 108 |
| 109 std::vector<FilePath> paths; |
| 110 base::FileEnumerator enumerator(stability_dir, false /* recursive */, |
| 111 base::FileEnumerator::FILES, |
| 112 stability_file_pattern); |
| 113 FilePath path; |
| 114 for (path = enumerator.Next(); !path.empty(); path = enumerator.Next()) { |
| 115 if (excluded_stability_files.find(path) == excluded_stability_files.end()) |
| 116 paths.push_back(path); |
| 117 } |
| 118 return paths; |
| 119 } |
| 120 |
100 void MarkOwnStabilityFileDeleted(const base::FilePath& user_data_dir) { | 121 void MarkOwnStabilityFileDeleted(const base::FilePath& user_data_dir) { |
101 base::debug::GlobalActivityTracker* global_tracker = | 122 base::debug::GlobalActivityTracker* global_tracker = |
102 base::debug::GlobalActivityTracker::Get(); | 123 base::debug::GlobalActivityTracker::Get(); |
103 if (!global_tracker) | 124 if (!global_tracker) |
104 return; // No stability instrumentation. | 125 return; // No stability instrumentation. |
105 | 126 |
106 global_tracker->MarkDeleted(); | 127 global_tracker->MarkDeleted(); |
107 LogStabilityRecordEvent(StabilityRecordEvent::kMarkDeleted); | 128 LogStabilityRecordEvent(StabilityRecordEvent::kMarkDeleted); |
108 | 129 |
109 // Open (with delete) and then immediately close the file by going out of | 130 // Open (with delete) and then immediately close the file by going out of |
(...skipping 19 matching lines...) Expand all Loading... |
129 | 150 |
130 base::File deleter(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ | | 151 base::File deleter(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ | |
131 base::File::FLAG_DELETE_ON_CLOSE); | 152 base::File::FLAG_DELETE_ON_CLOSE); |
132 if (!deleter.IsValid()) | 153 if (!deleter.IsValid()) |
133 LogCollectOnCrashEvent(CollectOnCrashEvent::kOpenForDeleteFailed); | 154 LogCollectOnCrashEvent(CollectOnCrashEvent::kOpenForDeleteFailed); |
134 } | 155 } |
135 | 156 |
136 } // namespace browser_watcher | 157 } // namespace browser_watcher |
137 | 158 |
138 #endif // defined(OS_WIN) | 159 #endif // defined(OS_WIN) |
OLD | NEW |