OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/browser_main_posix.h" | 5 #include "chrome/browser/browser_main_posix.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <limits.h> |
8 #include <signal.h> | 9 #include <signal.h> |
9 #include <sys/resource.h> | 10 #include <sys/resource.h> |
| 11 #include <unistd.h> |
10 | 12 |
11 #include <string> | 13 #include <string> |
12 | 14 |
13 #include "base/command_line.h" | 15 #include "base/command_line.h" |
14 #include "base/eintr_wrapper.h" | 16 #include "base/eintr_wrapper.h" |
15 #include "base/logging.h" | 17 #include "base/logging.h" |
16 #include "base/string_number_conversions.h" | 18 #include "base/string_number_conversions.h" |
17 #include "base/threading/platform_thread.h" | |
18 #include "chrome/browser/defaults.h" | 19 #include "chrome/browser/defaults.h" |
19 #include "chrome/browser/ui/browser_list.h" | 20 #include "chrome/browser/ui/browser_list.h" |
20 #include "chrome/common/chrome_switches.h" | 21 #include "chrome/common/chrome_switches.h" |
21 #include "content/browser/browser_thread.h" | 22 #include "content/browser/browser_thread.h" |
22 | 23 |
23 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | 24 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
24 #include "chrome/browser/printing/print_dialog_gtk.h" | 25 #include "chrome/browser/printing/print_dialog_gtk.h" |
25 #endif | 26 #endif |
26 | 27 |
27 namespace { | 28 namespace { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 const int shutdown_fd_; | 83 const int shutdown_fd_; |
83 | 84 |
84 DISALLOW_COPY_AND_ASSIGN(ShutdownDetector); | 85 DISALLOW_COPY_AND_ASSIGN(ShutdownDetector); |
85 }; | 86 }; |
86 | 87 |
87 ShutdownDetector::ShutdownDetector(int shutdown_fd) | 88 ShutdownDetector::ShutdownDetector(int shutdown_fd) |
88 : shutdown_fd_(shutdown_fd) { | 89 : shutdown_fd_(shutdown_fd) { |
89 CHECK_NE(shutdown_fd_, -1); | 90 CHECK_NE(shutdown_fd_, -1); |
90 } | 91 } |
91 | 92 |
| 93 |
| 94 // These functions are used to help us diagnose crash dumps that happen |
| 95 // during the shutdown process. |
| 96 NOINLINE void ShutdownFDReadError() { |
| 97 // Ensure function isn't optimized away. |
| 98 asm(""); |
| 99 sleep(UINT_MAX); |
| 100 } |
| 101 |
| 102 NOINLINE void ShutdownFDClosedError() { |
| 103 // Ensure function isn't optimized away. |
| 104 asm(""); |
| 105 sleep(UINT_MAX); |
| 106 } |
| 107 |
| 108 NOINLINE void CloseAllBrowsersAndExitPosted() { |
| 109 // Ensure function isn't optimized away. |
| 110 asm(""); |
| 111 sleep(UINT_MAX); |
| 112 } |
| 113 |
92 void ShutdownDetector::ThreadMain() { | 114 void ShutdownDetector::ThreadMain() { |
93 base::PlatformThread::SetName("CrShutdownDetector"); | 115 base::PlatformThread::SetName("CrShutdownDetector"); |
94 | 116 |
95 int signal; | 117 int signal; |
96 size_t bytes_read = 0; | 118 size_t bytes_read = 0; |
97 ssize_t ret; | 119 ssize_t ret; |
98 do { | 120 do { |
99 ret = HANDLE_EINTR( | 121 ret = HANDLE_EINTR( |
100 read(shutdown_fd_, | 122 read(shutdown_fd_, |
101 reinterpret_cast<char*>(&signal) + bytes_read, | 123 reinterpret_cast<char*>(&signal) + bytes_read, |
102 sizeof(signal) - bytes_read)); | 124 sizeof(signal) - bytes_read)); |
103 if (ret < 0) { | 125 if (ret < 0) { |
104 NOTREACHED() << "Unexpected error: " << strerror(errno); | 126 NOTREACHED() << "Unexpected error: " << strerror(errno); |
| 127 ShutdownFDReadError(); |
105 break; | 128 break; |
106 } else if (ret == 0) { | 129 } else if (ret == 0) { |
107 NOTREACHED() << "Unexpected closure of shutdown pipe."; | 130 NOTREACHED() << "Unexpected closure of shutdown pipe."; |
| 131 ShutdownFDClosedError(); |
108 break; | 132 break; |
109 } | 133 } |
110 bytes_read += ret; | 134 bytes_read += ret; |
111 } while (bytes_read < sizeof(signal)); | 135 } while (bytes_read < sizeof(signal)); |
112 | 136 |
113 VLOG(1) << "Handling shutdown for signal " << signal << "."; | 137 VLOG(1) << "Handling shutdown for signal " << signal << "."; |
114 | 138 |
115 if (!BrowserThread::PostTask( | 139 if (!BrowserThread::PostTask( |
116 BrowserThread::UI, FROM_HERE, | 140 BrowserThread::UI, FROM_HERE, |
117 NewRunnableFunction(BrowserList::CloseAllBrowsersAndExit))) { | 141 NewRunnableFunction(BrowserList::CloseAllBrowsersAndExit))) { |
118 // Without a UI thread to post the exit task to, there aren't many | 142 // Without a UI thread to post the exit task to, there aren't many |
119 // options. Raise the signal again. The default handler will pick it up | 143 // options. Raise the signal again. The default handler will pick it up |
120 // and cause an ungraceful exit. | 144 // and cause an ungraceful exit. |
121 RAW_LOG(WARNING, "No UI thread, exiting ungracefully."); | 145 RAW_LOG(WARNING, "No UI thread, exiting ungracefully."); |
122 kill(getpid(), signal); | 146 kill(getpid(), signal); |
123 | 147 |
124 // The signal may be handled on another thread. Give that a chance to | 148 // The signal may be handled on another thread. Give that a chance to |
125 // happen. | 149 // happen. |
126 sleep(3); | 150 sleep(3); |
127 | 151 |
128 // We really should be dead by now. For whatever reason, we're not. Exit | 152 // We really should be dead by now. For whatever reason, we're not. Exit |
129 // immediately, with the exit status set to the signal number with bit 8 | 153 // immediately, with the exit status set to the signal number with bit 8 |
130 // set. On the systems that we care about, this exit status is what is | 154 // set. On the systems that we care about, this exit status is what is |
131 // normally used to indicate an exit by this signal's default handler. | 155 // normally used to indicate an exit by this signal's default handler. |
132 // This mechanism isn't a de jure standard, but even in the worst case, it | 156 // This mechanism isn't a de jure standard, but even in the worst case, it |
133 // should at least result in an immediate exit. | 157 // should at least result in an immediate exit. |
134 RAW_LOG(WARNING, "Still here, exiting really ungracefully."); | 158 RAW_LOG(WARNING, "Still here, exiting really ungracefully."); |
135 _exit(signal | (1 << 7)); | 159 _exit(signal | (1 << 7)); |
136 } | 160 } |
| 161 CloseAllBrowsersAndExitPosted(); |
137 } | 162 } |
138 | 163 |
139 // Sets the file descriptor soft limit to |max_descriptors| or the OS hard | 164 // Sets the file descriptor soft limit to |max_descriptors| or the OS hard |
140 // limit, whichever is lower. | 165 // limit, whichever is lower. |
141 void SetFileDescriptorLimit(unsigned int max_descriptors) { | 166 void SetFileDescriptorLimit(unsigned int max_descriptors) { |
142 struct rlimit limits; | 167 struct rlimit limits; |
143 if (getrlimit(RLIMIT_NOFILE, &limits) == 0) { | 168 if (getrlimit(RLIMIT_NOFILE, &limits) == 0) { |
144 unsigned int new_limit = max_descriptors; | 169 unsigned int new_limit = max_descriptors; |
145 if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) { | 170 if (limits.rlim_max > 0 && limits.rlim_max < max_descriptors) { |
146 new_limit = limits.rlim_max; | 171 new_limit = limits.rlim_max; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 new ShutdownDetector(g_shutdown_pipe_read_fd))) { | 253 new ShutdownDetector(g_shutdown_pipe_read_fd))) { |
229 LOG(DFATAL) << "Failed to create shutdown detector task."; | 254 LOG(DFATAL) << "Failed to create shutdown detector task."; |
230 } | 255 } |
231 } | 256 } |
232 | 257 |
233 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | 258 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
234 printing::PrintingContextCairo::SetCreatePrintDialogFunction( | 259 printing::PrintingContextCairo::SetCreatePrintDialogFunction( |
235 &PrintDialogGtk::CreatePrintDialog); | 260 &PrintDialogGtk::CreatePrintDialog); |
236 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) | 261 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) |
237 } | 262 } |
OLD | NEW |