blob: 9ba6a7f3cf7d88a7511b1ddfdfc6eaf9bb52d40d [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/metrics/thread_watcher_report_hang.h"
// We disable optimizations for the whole file so the compiler doesn't merge
// them all together.
MSVC_DISABLE_OPTIMIZE()
MSVC_PUSH_DISABLE_WARNING(4748)
#include "base/debug/debugger.h"
#include "base/debug/dump_without_crashing.h"
#include "build/build_config.h"
namespace metrics {
// The following are unique function names for forcing the crash when a thread
// is unresponsive. This makes it possible to tell from the callstack alone what
// thread was unresponsive.
NOINLINE void ReportThreadHang() {
volatile const char* inhibit_comdat = __func__;
ALLOW_UNUSED_LOCAL(inhibit_comdat);
#if defined(NDEBUG)
base::debug::DumpWithoutCrashing();
#else
base::debug::BreakDebugger();
#endif
}
#if !defined(OS_ANDROID) || !defined(NDEBUG)
NOINLINE void StartupHang() {
volatile int inhibit_comdat = __LINE__;
ALLOW_UNUSED_LOCAL(inhibit_comdat);
// TODO(rtenneti): http://crbug.com/440885 enable crashing after fixing false
// positive startup hang data.
// ReportThreadHang();
}
#endif // OS_ANDROID
NOINLINE void ShutdownHang() {
volatile int inhibit_comdat = __LINE__;
ALLOW_UNUSED_LOCAL(inhibit_comdat);
ReportThreadHang();
}
NOINLINE void ThreadUnresponsive_UI() {
volatile int inhibit_comdat = __LINE__;
ALLOW_UNUSED_LOCAL(inhibit_comdat);
ReportThreadHang();
}
NOINLINE void ThreadUnresponsive_DB() {
volatile int inhibit_comdat = __LINE__;
ALLOW_UNUSED_LOCAL(inhibit_comdat);
ReportThreadHang();
}
NOINLINE void ThreadUnresponsive_FILE() {
volatile int inhibit_comdat = __LINE__;
ALLOW_UNUSED_LOCAL(inhibit_comdat);
ReportThreadHang();
}
NOINLINE void ThreadUnresponsive_FILE_USER_BLOCKING() {
volatile int inhibit_comdat = __LINE__;
ALLOW_UNUSED_LOCAL(inhibit_comdat);
ReportThreadHang();
}
NOINLINE void ThreadUnresponsive_PROCESS_LAUNCHER() {
volatile int inhibit_comdat = __LINE__;
ALLOW_UNUSED_LOCAL(inhibit_comdat);
ReportThreadHang();
}
NOINLINE void ThreadUnresponsive_CACHE() {
volatile int inhibit_comdat = __LINE__;
ALLOW_UNUSED_LOCAL(inhibit_comdat);
ReportThreadHang();
}
NOINLINE void ThreadUnresponsive_IO() {
volatile int inhibit_comdat = __LINE__;
ALLOW_UNUSED_LOCAL(inhibit_comdat);
ReportThreadHang();
}
NOINLINE void CrashBecauseThreadWasUnresponsive(int thread_id) {
// TODO(rtenneti): The following is a temporary change to check thread_id
// numbers explicitly so that we will have minimum code. Will change after the
// test run to use content::BrowserThread::ID enum.
if (thread_id == 0)
return ThreadUnresponsive_UI();
else if (thread_id == 1)
return ThreadUnresponsive_DB();
else if (thread_id == 2)
return ThreadUnresponsive_FILE();
else if (thread_id == 3)
return ThreadUnresponsive_FILE_USER_BLOCKING();
else if (thread_id == 4)
return ThreadUnresponsive_PROCESS_LAUNCHER();
else if (thread_id == 5)
return ThreadUnresponsive_CACHE();
else if (thread_id == 6)
return ThreadUnresponsive_IO();
}
} // namespace metrics
MSVC_POP_WARNING()
MSVC_ENABLE_OPTIMIZE();