diff options
Diffstat (limited to 'chrome/browser/metrics/thread_watcher.cc')
-rw-r--r-- | chrome/browser/metrics/thread_watcher.cc | 105 |
1 files changed, 67 insertions, 38 deletions
diff --git a/chrome/browser/metrics/thread_watcher.cc b/chrome/browser/metrics/thread_watcher.cc index afc84f2..a76e6e3 100644 --- a/chrome/browser/metrics/thread_watcher.cc +++ b/chrome/browser/metrics/thread_watcher.cc @@ -11,6 +11,7 @@ #include "base/debug/alias.h" #include "base/lazy_instance.h" #include "base/string_split.h" +#include "base/stringprintf.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_tokenizer.h" #include "base/threading/thread_restrictions.h" @@ -408,6 +409,18 @@ const int ThreadWatcherList::kUnresponsiveCount = 9; // static const int ThreadWatcherList::kLiveThreadsThreshold = 3; +ThreadWatcherList::CrashDataThresholds::CrashDataThresholds( + uint32 live_threads_threshold, + uint32 unresponsive_threshold) + : live_threads_threshold(live_threads_threshold), + unresponsive_threshold(unresponsive_threshold) { +} + +ThreadWatcherList::CrashDataThresholds::CrashDataThresholds() + : live_threads_threshold(kLiveThreadsThreshold), + unresponsive_threshold(kUnresponsiveCount) { +} + // static void ThreadWatcherList::StartWatchingAll(const CommandLine& command_line) { uint32 unresponsive_threshold; @@ -498,7 +511,7 @@ void ThreadWatcherList::ParseCommandLine( const CommandLine& command_line, uint32* unresponsive_threshold, CrashOnHangThreadMap* crash_on_hang_threads) { - // Determine |unresponsive_threshold| based on switches::kCrashOnHangSeconds. + // Initialize |unresponsive_threshold| to a default value. *unresponsive_threshold = kUnresponsiveCount; // Increase the unresponsive_threshold on the Stable and Beta channels to @@ -518,47 +531,27 @@ void ThreadWatcherList::ParseCommandLine( *unresponsive_threshold *= 2; #endif - std::string crash_on_hang_seconds = - command_line.GetSwitchValueASCII(switches::kCrashOnHangSeconds); - if (!crash_on_hang_seconds.empty()) { - int crash_seconds = atoi(crash_on_hang_seconds.c_str()); - if (crash_seconds > 0) { - *unresponsive_threshold = static_cast<uint32>( - ceil(static_cast<float>(crash_seconds) / kUnresponsiveSeconds)); - } - } - + uint32 crash_seconds = *unresponsive_threshold * kUnresponsiveSeconds; std::string crash_on_hang_thread_names; - - // Default to crashing the browser if UI or IO threads are not responsive - // except in stable channel. - if (channel == chrome::VersionInfo::CHANNEL_STABLE) - crash_on_hang_thread_names = ""; - else - crash_on_hang_thread_names = "UI:3,IO:9"; - bool has_command_line_overwrite = false; if (command_line.HasSwitch(switches::kCrashOnHangThreads)) { crash_on_hang_thread_names = command_line.GetSwitchValueASCII(switches::kCrashOnHangThreads); has_command_line_overwrite = true; + } else if (channel != chrome::VersionInfo::CHANNEL_STABLE) { + // Default to crashing the browser if UI or IO or FILE threads are not + // responsive except in stable channel. + crash_on_hang_thread_names = base::StringPrintf( + "UI:%d:%d,IO:%d:%d,FILE:%d:%d", + kLiveThreadsThreshold, crash_seconds, + kLiveThreadsThreshold, crash_seconds, + kLiveThreadsThreshold, crash_seconds * 5); } - base::StringTokenizer tokens(crash_on_hang_thread_names, ","); - std::vector<std::string> values; - while (tokens.GetNext()) { - const std::string& token = tokens.token(); - base::SplitString(token, ':', &values); - if (values.size() != 2) - continue; - std::string thread_name = values[0]; - uint32 live_threads_threshold; - if (!base::StringToUint(values[1], &live_threads_threshold)) - continue; - CrashOnHangThreadMap::iterator it = - crash_on_hang_threads->find(thread_name); - if (crash_on_hang_threads->end() == it) - (*crash_on_hang_threads)[thread_name] = live_threads_threshold; - } + + ParseCommandLineCrashOnHangThreads(crash_on_hang_thread_names, + kLiveThreadsThreshold, + crash_seconds, + crash_on_hang_threads); if (channel != chrome::VersionInfo::CHANNEL_CANARY || has_command_line_overwrite) { @@ -576,8 +569,43 @@ void ThreadWatcherList::ParseCommandLine( "ThreadWatcher", 100, "default_hung_threads", 2013, 10, 30, NULL)); int io_hung_thread_group = field_trial->AppendGroup("io_hung_thread", 10); - if (field_trial->group() == io_hung_thread_group) - it->second = INT_MAX; // Crash anytime IO thread hangs. + if (field_trial->group() == io_hung_thread_group) { + // Crash anytime IO thread hangs. + it->second.live_threads_threshold = INT_MAX; + } +} + +// static +void ThreadWatcherList::ParseCommandLineCrashOnHangThreads( + const std::string& crash_on_hang_thread_names, + uint32 default_live_threads_threshold, + uint32 default_crash_seconds, + CrashOnHangThreadMap* crash_on_hang_threads) { + base::StringTokenizer tokens(crash_on_hang_thread_names, ","); + std::vector<std::string> values; + while (tokens.GetNext()) { + const std::string& token = tokens.token(); + base::SplitString(token, ':', &values); + std::string thread_name = values[0]; + + uint32 live_threads_threshold = default_live_threads_threshold; + uint32 crash_seconds = default_crash_seconds; + if (values.size() >= 2 && + (!base::StringToUint(values[1], &live_threads_threshold))) { + continue; + } + if (values.size() >= 3 && + (!base::StringToUint(values[2], &crash_seconds))) { + continue; + } + uint32 unresponsive_threshold = static_cast<uint32>( + ceil(static_cast<float>(crash_seconds) / kUnresponsiveSeconds)); + + CrashDataThresholds crash_data(live_threads_threshold, + unresponsive_threshold); + // Use the last specifier. + (*crash_on_hang_threads)[thread_name] = crash_data; + } } // static @@ -630,7 +658,8 @@ void ThreadWatcherList::StartWatching( uint32 live_threads_threshold = 0; if (it != crash_on_hang_threads.end()) { crash_on_hang = true; - live_threads_threshold = it->second; + live_threads_threshold = it->second.live_threads_threshold; + unresponsive_threshold = it->second.unresponsive_threshold; } ThreadWatcher::StartWatching( |