Index: components/crash/content/app/crashpad.cc |
diff --git a/components/crash/content/app/crashpad.cc b/components/crash/content/app/crashpad.cc |
index 2ac5a8c4892128dc106169841e108b14d53ed758..e471628fdb7b34de3fcc8cefaeb8cfbfbc502630 100644 |
--- a/components/crash/content/app/crashpad.cc |
+++ b/components/crash/content/app/crashpad.cc |
@@ -42,7 +42,6 @@ |
#if BUILDFLAG(ENABLE_KASKO) |
#include "base/win/scoped_handle.h" |
-#include "base/win/win_util.h" |
#include "third_party/crashpad/crashpad/snapshot/api/module_annotations_win.h" |
#endif |
@@ -105,10 +104,59 @@ void DumpWithoutCrashing() { |
} |
#if BUILDFLAG(ENABLE_KASKO) |
+// TODO(ananta) |
+// We cannot depend on functionality in base which pulls in dependencies on |
+// user32 directly or indirectly. The GetLoadedModulesSnapshot is a copy of the |
+// function in base/win/win_util.cc. Depending on the base function pulls in |
+// dependencies on user32 due to other functionality in win_util.cc. This |
+// function should be removed when KASKO is removed. |
+bool GetLoadedModulesSnapshot(HANDLE process, std::vector<HMODULE>* snapshot) { |
+ DCHECK(snapshot); |
+ DCHECK_EQ(0u, snapshot->size()); |
+ snapshot->resize(128); |
+ |
+ // We will retry at least once after first determining |bytes_required|. If |
+ // the list of modules changes after we receive |bytes_required| we may retry |
+ // more than once. |
+ int retries_remaining = 5; |
+ do { |
+ DWORD bytes_required = 0; |
+ // EnumProcessModules returns 'success' even if the buffer size is too |
+ // small. |
+ DCHECK_GE(std::numeric_limits<DWORD>::max(), |
+ snapshot->size() * sizeof(HMODULE)); |
+ if (!::EnumProcessModules( |
+ process, &(*snapshot)[0], |
+ static_cast<DWORD>(snapshot->size() * sizeof(HMODULE)), |
+ &bytes_required)) { |
+ DPLOG(ERROR) << "::EnumProcessModules failed."; |
+ return false; |
+ } |
+ DCHECK_EQ(0u, bytes_required % sizeof(HMODULE)); |
+ size_t num_modules = bytes_required / sizeof(HMODULE); |
+ if (num_modules <= snapshot->size()) { |
+ // Buffer size was too big, presumably because a module was unloaded. |
+ snapshot->erase(snapshot->begin() + num_modules, snapshot->end()); |
+ return true; |
+ } else if (num_modules == 0) { |
+ DLOG(ERROR) << "Can't determine the module list size."; |
+ return false; |
+ } else { |
+ // Buffer size was too small. Try again with a larger buffer. A little |
+ // more room is given to avoid multiple expensive calls to |
+ // ::EnumProcessModules() just because one module has been added. |
+ snapshot->resize(num_modules + 8, NULL); |
+ } |
+ } while (--retries_remaining); |
+ |
+ DLOG(ERROR) << "Failed to enumerate modules."; |
+ return false; |
+} |
+ |
HMODULE GetModuleInProcess(base::ProcessHandle process, |
const wchar_t* module_name) { |
std::vector<HMODULE> modules_snapshot; |
- if (!base::win::GetLoadedModulesSnapshot(process, &modules_snapshot)) |
+ if (!GetLoadedModulesSnapshot(process, &modules_snapshot)) |
return nullptr; |
for (HMODULE module : modules_snapshot) { |