diff options
author | siggi <siggi@chromium.org> | 2016-02-18 10:57:17 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-18 18:58:38 +0000 |
commit | 90ea8c8da1869b3f959f0d7e450d8fd86de2bf0a (patch) | |
tree | af5e8100a6ef2002bc8938a0968c2489419ee7f0 /chrome/chrome_watcher | |
parent | 3ade867b39121742b6ff01d2ec17a5f15ace51f7 (diff) | |
download | chromium_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/OWNERS | 1 | ||||
-rw-r--r-- | chrome/chrome_watcher/chrome_watcher_main.cc | 34 |
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) { |