OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/metrics/thread_watcher.h" | 5 #include "chrome/browser/metrics/thread_watcher.h" |
6 | 6 |
7 #include <math.h> // ceil | 7 #include <math.h> // ceil |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 #endif | 46 #endif |
47 | 47 |
48 void NullPointerCrash(int line_number) { | 48 void NullPointerCrash(int line_number) { |
49 #ifndef NDEBUG | 49 #ifndef NDEBUG |
50 *NullPointer() = line_number; // Crash. | 50 *NullPointer() = line_number; // Crash. |
51 #else | 51 #else |
52 base::debug::DumpWithoutCrashing(); | 52 base::debug::DumpWithoutCrashing(); |
53 #endif | 53 #endif |
54 } | 54 } |
55 | 55 |
| 56 #if !defined(OS_ANDROID) || !defined(NDEBUG) |
| 57 // TODO(rtenneti): Enabled crashing, after getting data. |
| 58 NOINLINE void StartupCrash() { |
| 59 NullPointerCrash(__LINE__); |
| 60 } |
| 61 #endif // OS_ANDROID |
| 62 |
56 NOINLINE void ShutdownCrash() { | 63 NOINLINE void ShutdownCrash() { |
57 NullPointerCrash(__LINE__); | 64 NullPointerCrash(__LINE__); |
58 } | 65 } |
59 | 66 |
60 NOINLINE void ThreadUnresponsive_UI() { | 67 NOINLINE void ThreadUnresponsive_UI() { |
61 NullPointerCrash(__LINE__); | 68 NullPointerCrash(__LINE__); |
62 } | 69 } |
63 | 70 |
64 NOINLINE void ThreadUnresponsive_DB() { | 71 NOINLINE void ThreadUnresponsive_DB() { |
65 NullPointerCrash(__LINE__); | 72 NullPointerCrash(__LINE__); |
(...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
875 | 882 |
876 // StartupWatchDogThread methods and members. | 883 // StartupWatchDogThread methods and members. |
877 // | 884 // |
878 // Class for detecting hangs during startup. | 885 // Class for detecting hangs during startup. |
879 class StartupWatchDogThread : public base::Watchdog { | 886 class StartupWatchDogThread : public base::Watchdog { |
880 public: | 887 public: |
881 // Constructor specifies how long the StartupWatchDogThread will wait before | 888 // Constructor specifies how long the StartupWatchDogThread will wait before |
882 // alarming. | 889 // alarming. |
883 explicit StartupWatchDogThread(const base::TimeDelta& duration) | 890 explicit StartupWatchDogThread(const base::TimeDelta& duration) |
884 : base::Watchdog(duration, "Startup watchdog thread", true) { | 891 : base::Watchdog(duration, "Startup watchdog thread", true) { |
| 892 #if defined(OS_ANDROID) |
| 893 // TODO(rtenneti): Delete this code, after getting data. |
| 894 start_time_clock_= base::Time::Now(); |
| 895 start_time_monotonic_ = base::TimeTicks::Now(); |
| 896 start_time_thread_now_ = base::TimeTicks::IsThreadNowSupported() |
| 897 ? base::TimeTicks::ThreadNow() : base::TimeTicks::Now(); |
| 898 #endif // OS_ANDROID |
885 } | 899 } |
886 | 900 |
887 // Alarm is called if the time expires after an Arm() without someone calling | 901 // Alarm is called if the time expires after an Arm() without someone calling |
888 // Disarm(). When Alarm goes off, in release mode we get the crash dump | 902 // Disarm(). When Alarm goes off, in release mode we get the crash dump |
889 // without crashing and in debug mode we break into the debugger. | 903 // without crashing and in debug mode we break into the debugger. |
890 virtual void Alarm() OVERRIDE { | 904 virtual void Alarm() OVERRIDE { |
891 #ifndef NDEBUG | 905 #if !defined(NDEBUG) |
892 DCHECK(false); | 906 StartupCrash(); |
893 #else | 907 return; |
894 WatchDogThread::PostTask(FROM_HERE, | 908 #elif !defined(OS_ANDROID) |
895 base::Bind(&base::debug::DumpWithoutCrashing)); | 909 WatchDogThread::PostTask(FROM_HERE, base::Bind(&StartupCrash)); |
896 #endif | 910 return; |
| 911 #else // Android release: gather stats to figure out when to crash. |
| 912 // TODO(rtenneti): Delete this code, after getting data. |
| 913 UMA_HISTOGRAM_TIMES("StartupTimebomm.Alarm.TimeDuration", |
| 914 base::Time::Now() - start_time_clock_); |
| 915 UMA_HISTOGRAM_TIMES("StartupTimebomm.Alarm.TimeTicksDuration", |
| 916 base::TimeTicks::Now() - start_time_monotonic_); |
| 917 if (base::TimeTicks::IsThreadNowSupported()) { |
| 918 UMA_HISTOGRAM_TIMES( |
| 919 "StartupTimebomm.Alarm.ThreadNowDuration", |
| 920 base::TimeTicks::ThreadNow() - start_time_thread_now_); |
| 921 } |
| 922 return; |
| 923 #endif // OS_ANDROID |
897 } | 924 } |
898 | 925 |
| 926 private: |
| 927 #if defined(OS_ANDROID) |
| 928 // TODO(rtenneti): Delete this code, after getting data. |
| 929 base::Time start_time_clock_; |
| 930 base::TimeTicks start_time_monotonic_; |
| 931 base::TimeTicks start_time_thread_now_; |
| 932 #endif // OS_ANDROID |
| 933 |
899 DISALLOW_COPY_AND_ASSIGN(StartupWatchDogThread); | 934 DISALLOW_COPY_AND_ASSIGN(StartupWatchDogThread); |
900 }; | 935 }; |
901 | 936 |
902 // ShutdownWatchDogThread methods and members. | 937 // ShutdownWatchDogThread methods and members. |
903 // | 938 // |
904 // Class for detecting hangs during shutdown. | 939 // Class for detecting hangs during shutdown. |
905 class ShutdownWatchDogThread : public base::Watchdog { | 940 class ShutdownWatchDogThread : public base::Watchdog { |
906 public: | 941 public: |
907 // Constructor specifies how long the ShutdownWatchDogThread will wait before | 942 // Constructor specifies how long the ShutdownWatchDogThread will wait before |
908 // alarming. | 943 // alarming. |
909 explicit ShutdownWatchDogThread(const base::TimeDelta& duration) | 944 explicit ShutdownWatchDogThread(const base::TimeDelta& duration) |
910 : base::Watchdog(duration, "Shutdown watchdog thread", true) { | 945 : base::Watchdog(duration, "Shutdown watchdog thread", true) { |
911 } | 946 } |
912 | 947 |
913 // Alarm is called if the time expires after an Arm() without someone calling | 948 // Alarm is called if the time expires after an Arm() without someone calling |
914 // Disarm(). We crash the browser if this method is called. | 949 // Disarm(). We crash the browser if this method is called. |
915 virtual void Alarm() OVERRIDE { | 950 virtual void Alarm() OVERRIDE { |
916 ShutdownCrash(); | 951 ShutdownCrash(); |
917 } | 952 } |
918 | 953 |
| 954 private: |
919 DISALLOW_COPY_AND_ASSIGN(ShutdownWatchDogThread); | 955 DISALLOW_COPY_AND_ASSIGN(ShutdownWatchDogThread); |
920 }; | 956 }; |
921 } // namespace | 957 } // namespace |
922 | 958 |
923 // StartupTimeBomb methods and members. | 959 // StartupTimeBomb methods and members. |
924 // | 960 // |
925 // static | 961 // static |
926 StartupTimeBomb* StartupTimeBomb::g_startup_timebomb_ = NULL; | 962 StartupTimeBomb* StartupTimeBomb::g_startup_timebomb_ = NULL; |
927 | 963 |
928 StartupTimeBomb::StartupTimeBomb() | 964 StartupTimeBomb::StartupTimeBomb() |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1014 | 1050 |
1015 #if defined(OS_WIN) | 1051 #if defined(OS_WIN) |
1016 // On Windows XP, give twice the time for shutdown. | 1052 // On Windows XP, give twice the time for shutdown. |
1017 if (base::win::GetVersion() <= base::win::VERSION_XP) | 1053 if (base::win::GetVersion() <= base::win::VERSION_XP) |
1018 actual_duration *= 2; | 1054 actual_duration *= 2; |
1019 #endif | 1055 #endif |
1020 | 1056 |
1021 shutdown_watchdog_ = new ShutdownWatchDogThread(actual_duration); | 1057 shutdown_watchdog_ = new ShutdownWatchDogThread(actual_duration); |
1022 shutdown_watchdog_->Arm(); | 1058 shutdown_watchdog_->Arm(); |
1023 } | 1059 } |
OLD | NEW |