summaryrefslogtreecommitdiffstats
path: root/chrome/chrome_watcher
diff options
context:
space:
mode:
authorsiggi <siggi@chromium.org>2016-02-18 10:57:17 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-18 18:58:38 +0000
commit90ea8c8da1869b3f959f0d7e450d8fd86de2bf0a (patch)
treeaf5e8100a6ef2002bc8938a0968c2489419ee7f0 /chrome/chrome_watcher
parent3ade867b39121742b6ff01d2ec17a5f15ace51f7 (diff)
downloadchromium_src-90ea8c8da1869b3f959f0d7e450d8fd86de2bf0a.zip
chromium_src-90ea8c8da1869b3f959f0d7e450d8fd86de2bf0a.tar.gz
chromium_src-90ea8c8da1869b3f959f0d7e450d8fd86de2bf0a.tar.bz2
Grab a context record for the main thread of hung processes.
BUG=585953 Review URL: https://codereview.chromium.org/1707813003 Cr-Commit-Position: refs/heads/master@{#376215}
Diffstat (limited to 'chrome/chrome_watcher')
-rw-r--r--chrome/chrome_watcher/OWNERS1
-rw-r--r--chrome/chrome_watcher/chrome_watcher_main.cc34
2 files changed, 31 insertions, 4 deletions
diff --git a/chrome/chrome_watcher/OWNERS b/chrome/chrome_watcher/OWNERS
index 147afd9..3224b9e 100644
--- a/chrome/chrome_watcher/OWNERS
+++ b/chrome/chrome_watcher/OWNERS
@@ -1 +1,2 @@
siggi@chromium.org
+pmonette@chromium.org
diff --git a/chrome/chrome_watcher/chrome_watcher_main.cc b/chrome/chrome_watcher/chrome_watcher_main.cc
index 14765fb..cb35279 100644
--- a/chrome/chrome_watcher/chrome_watcher_main.cc
+++ b/chrome/chrome_watcher/chrome_watcher_main.cc
@@ -251,16 +251,42 @@ void DumpHungBrowserProcess(DWORD main_thread_id,
key_buffers.push_back(nullptr);
value_buffers.push_back(nullptr);
- // Synthesize an exception for the main thread.
+ // Synthesize an exception for the main thread. Populate the record with the
+ // current context of the thread to get the stack trace bucketed on the crash
+ // backend.
CONTEXT thread_context = {};
EXCEPTION_RECORD exception_record = {};
exception_record.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
EXCEPTION_POINTERS exception_pointers = {&exception_record, &thread_context};
+ base::win::ScopedHandle main_thread(::OpenThread(
+ THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION,
+ FALSE, main_thread_id));
+
+ bool have_context = false;
+ if (main_thread.IsValid()) {
+ DWORD suspend_count = ::SuspendThread(main_thread.Get());
+ if (suspend_count != -1) {
+ // Best effort capture of the context.
+ thread_context.ContextFlags = CONTEXT_FLOATING_POINT | CONTEXT_SEGMENTS |
+ CONTEXT_INTEGER | CONTEXT_CONTROL;
+ if (::GetThreadContext(main_thread.Get(), &thread_context) == TRUE)
+ have_context = true;
+
+ ::ResumeThread(main_thread.Get());
+ }
+ }
+
// TODO(erikwright): Make the dump-type channel-dependent.
- kasko::api::SendReportForProcess(
- process.Handle(), main_thread_id, &exception_pointers,
- kasko::api::LARGER_DUMP_TYPE, key_buffers.data(), value_buffers.data());
+ if (have_context) {
+ kasko::api::SendReportForProcess(
+ process.Handle(), main_thread_id, &exception_pointers,
+ kasko::api::LARGER_DUMP_TYPE, key_buffers.data(), value_buffers.data());
+ } else {
+ kasko::api::SendReportForProcess(process.Handle(), 0, nullptr,
+ kasko::api::LARGER_DUMP_TYPE,
+ key_buffers.data(), value_buffers.data());
+ }
}
void LoggedDeregisterEventSource(HANDLE event_source_handle) {