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 #if defined(OS_MACOSX) | 5 #if defined(OS_MACOSX) |
6 #include <signal.h> | 6 #include <signal.h> |
7 #include <unistd.h> | 7 #include <unistd.h> |
8 #endif // OS_MACOSX | 8 #endif // OS_MACOSX |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 #include "content/common/pepper_plugin_registry.h" | 28 #include "content/common/pepper_plugin_registry.h" |
29 #include "content/renderer/render_process_impl.h" | 29 #include "content/renderer/render_process_impl.h" |
30 #include "content/renderer/render_thread.h" | 30 #include "content/renderer/render_thread.h" |
31 #include "content/renderer/renderer_main_platform_delegate.h" | 31 #include "content/renderer/renderer_main_platform_delegate.h" |
32 #include "ui/base/system_monitor/system_monitor.h" | 32 #include "ui/base/system_monitor/system_monitor.h" |
33 #include "ui/base/ui_base_switches.h" | 33 #include "ui/base/ui_base_switches.h" |
34 | 34 |
35 #if defined(OS_MACOSX) | 35 #if defined(OS_MACOSX) |
36 #include <Carbon/Carbon.h> // TISCreateInputSourceList | 36 #include <Carbon/Carbon.h> // TISCreateInputSourceList |
37 | 37 |
38 #include "base/eintr_wrapper.h" | |
39 #include "base/sys_info.h" | 38 #include "base/sys_info.h" |
40 #include "chrome/app/breakpad_mac.h" | |
41 #include "third_party/mach_override/mach_override.h" | 39 #include "third_party/mach_override/mach_override.h" |
42 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | 40 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
43 #endif // OS_MACOSX | 41 #endif // OS_MACOSX |
44 | 42 |
45 #if defined(OS_MACOSX) | 43 #if defined(OS_MACOSX) |
46 namespace { | 44 namespace { |
47 | 45 |
48 CFArrayRef ChromeTISCreateInputSourceList( | 46 CFArrayRef ChromeTISCreateInputSourceList( |
49 CFDictionaryRef properties, | 47 CFDictionaryRef properties, |
50 Boolean includeAllInstalled) { | 48 Boolean includeAllInstalled) { |
(...skipping 15 matching lines...) Expand all Loading... |
66 // regresses page cycler memory usage on 10.5, don't do the unnecessary | 64 // regresses page cycler memory usage on 10.5, don't do the unnecessary |
67 // override there. | 65 // override there. |
68 mach_error_t err = mach_override_ptr( | 66 mach_error_t err = mach_override_ptr( |
69 (void*)&TISCreateInputSourceList, | 67 (void*)&TISCreateInputSourceList, |
70 (void*)&ChromeTISCreateInputSourceList, | 68 (void*)&ChromeTISCreateInputSourceList, |
71 NULL); | 69 NULL); |
72 CHECK_EQ(err_none, err); | 70 CHECK_EQ(err_none, err); |
73 } | 71 } |
74 } | 72 } |
75 | 73 |
76 // TODO(viettrungluu): crbug.com/28547: The following signal handling is needed, | |
77 // as a stopgap, to avoid leaking due to not releasing Breakpad properly. | |
78 // Without this problem, this could all be eliminated. Remove when Breakpad is | |
79 // fixed? | |
80 // TODO(viettrungluu): Code taken from browser_main.cc (with a bit of editing). | |
81 // The code should be properly shared (or this code should be eliminated). | |
82 int g_shutdown_pipe_write_fd = -1; | |
83 | |
84 void SIGTERMHandler(int signal) { | |
85 RAW_CHECK(signal == SIGTERM); | |
86 RAW_LOG(INFO, "Handling SIGTERM in renderer."); | |
87 | |
88 // Reinstall the default handler. We had one shot at graceful shutdown. | |
89 struct sigaction action; | |
90 memset(&action, 0, sizeof(action)); | |
91 action.sa_handler = SIG_DFL; | |
92 CHECK(sigaction(signal, &action, NULL) == 0); | |
93 | |
94 RAW_CHECK(g_shutdown_pipe_write_fd != -1); | |
95 size_t bytes_written = 0; | |
96 do { | |
97 int rv = HANDLE_EINTR( | |
98 write(g_shutdown_pipe_write_fd, | |
99 reinterpret_cast<const char*>(&signal) + bytes_written, | |
100 sizeof(signal) - bytes_written)); | |
101 RAW_CHECK(rv >= 0); | |
102 bytes_written += rv; | |
103 } while (bytes_written < sizeof(signal)); | |
104 | |
105 RAW_LOG(INFO, "Wrote signal to shutdown pipe."); | |
106 } | |
107 | |
108 class ShutdownDetector : public base::PlatformThread::Delegate { | |
109 public: | |
110 explicit ShutdownDetector(int shutdown_fd) : shutdown_fd_(shutdown_fd) { | |
111 CHECK(shutdown_fd_ != -1); | |
112 } | |
113 | |
114 virtual void ThreadMain() { | |
115 int signal; | |
116 size_t bytes_read = 0; | |
117 ssize_t ret; | |
118 do { | |
119 ret = HANDLE_EINTR( | |
120 read(shutdown_fd_, | |
121 reinterpret_cast<char*>(&signal) + bytes_read, | |
122 sizeof(signal) - bytes_read)); | |
123 if (ret < 0) { | |
124 NOTREACHED() << "Unexpected error: " << strerror(errno); | |
125 break; | |
126 } else if (ret == 0) { | |
127 NOTREACHED() << "Unexpected closure of shutdown pipe."; | |
128 break; | |
129 } | |
130 bytes_read += ret; | |
131 } while (bytes_read < sizeof(signal)); | |
132 | |
133 if (bytes_read == sizeof(signal)) | |
134 VLOG(1) << "Handling shutdown for signal " << signal << "."; | |
135 else | |
136 VLOG(1) << "Handling shutdown for unknown signal."; | |
137 | |
138 // Clean up Breakpad if necessary. | |
139 if (IsCrashReporterEnabled()) { | |
140 VLOG(1) << "Cleaning up Breakpad."; | |
141 DestructCrashReporter(); | |
142 } else { | |
143 VLOG(1) << "Breakpad not enabled; no clean-up needed."; | |
144 } | |
145 | |
146 // Something went seriously wrong, so get out. | |
147 if (bytes_read != sizeof(signal)) { | |
148 LOG(WARNING) << "Failed to get signal. Quitting ungracefully."; | |
149 _exit(1); | |
150 } | |
151 | |
152 // Re-raise the signal. | |
153 kill(getpid(), signal); | |
154 | |
155 // The signal may be handled on another thread. Give that a chance to | |
156 // happen. | |
157 sleep(3); | |
158 | |
159 // We really should be dead by now. For whatever reason, we're not. Exit | |
160 // immediately, with the exit status set to the signal number with bit 8 | |
161 // set. On the systems that we care about, this exit status is what is | |
162 // normally used to indicate an exit by this signal's default handler. | |
163 // This mechanism isn't a de jure standard, but even in the worst case, it | |
164 // should at least result in an immediate exit. | |
165 LOG(WARNING) << "Still here, exiting really ungracefully."; | |
166 _exit(signal | (1 << 7)); | |
167 } | |
168 | |
169 private: | |
170 const int shutdown_fd_; | |
171 | |
172 DISALLOW_COPY_AND_ASSIGN(ShutdownDetector); | |
173 }; | |
174 | |
175 } // namespace | 74 } // namespace |
176 #endif // OS_MACOSX | 75 #endif // OS_MACOSX |
177 | 76 |
178 // This function provides some ways to test crash and assertion handling | 77 // This function provides some ways to test crash and assertion handling |
179 // behavior of the renderer. | 78 // behavior of the renderer. |
180 static void HandleRendererErrorTestParameters(const CommandLine& command_line) { | 79 static void HandleRendererErrorTestParameters(const CommandLine& command_line) { |
181 // This parameter causes an assertion. | 80 // This parameter causes an assertion. |
182 if (command_line.HasSwitch(switches::kRendererAssertTest)) { | 81 if (command_line.HasSwitch(switches::kRendererAssertTest)) { |
183 DCHECK(false); | 82 DCHECK(false); |
184 } | 83 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 }; | 128 }; |
230 | 129 |
231 // mainline routine for running as the Renderer process | 130 // mainline routine for running as the Renderer process |
232 int RendererMain(const MainFunctionParams& parameters) { | 131 int RendererMain(const MainFunctionParams& parameters) { |
233 TRACE_EVENT_BEGIN("RendererMain", 0, ""); | 132 TRACE_EVENT_BEGIN("RendererMain", 0, ""); |
234 | 133 |
235 const CommandLine& parsed_command_line = parameters.command_line_; | 134 const CommandLine& parsed_command_line = parameters.command_line_; |
236 base::mac::ScopedNSAutoreleasePool* pool = parameters.autorelease_pool_; | 135 base::mac::ScopedNSAutoreleasePool* pool = parameters.autorelease_pool_; |
237 | 136 |
238 #if defined(OS_MACOSX) | 137 #if defined(OS_MACOSX) |
239 // TODO(viettrungluu): Code taken from browser_main.cc. | |
240 int pipefd[2]; | |
241 int ret = pipe(pipefd); | |
242 if (ret < 0) { | |
243 PLOG(DFATAL) << "Failed to create pipe"; | |
244 } else { | |
245 int shutdown_pipe_read_fd = pipefd[0]; | |
246 g_shutdown_pipe_write_fd = pipefd[1]; | |
247 const size_t kShutdownDetectorThreadStackSize = 4096; | |
248 if (!base::PlatformThread::CreateNonJoinable( | |
249 kShutdownDetectorThreadStackSize, | |
250 new ShutdownDetector(shutdown_pipe_read_fd))) { | |
251 LOG(DFATAL) << "Failed to create shutdown detector task."; | |
252 } | |
253 } | |
254 | |
255 // crbug.com/28547: When Breakpad is in use, handle SIGTERM to avoid leaking | |
256 // Mach ports. | |
257 struct sigaction action; | |
258 memset(&action, 0, sizeof(action)); | |
259 action.sa_handler = SIGTERMHandler; | |
260 CHECK(sigaction(SIGTERM, &action, NULL) == 0); | |
261 | |
262 InstallFrameworkHacks(); | 138 InstallFrameworkHacks(); |
263 #endif // OS_MACOSX | 139 #endif // OS_MACOSX |
264 | 140 |
265 #if defined(OS_CHROMEOS) | 141 #if defined(OS_CHROMEOS) |
266 // As Zygote process starts up earlier than browser process gets its own | 142 // As Zygote process starts up earlier than browser process gets its own |
267 // locale (at login time for Chrome OS), we have to set the ICU default | 143 // locale (at login time for Chrome OS), we have to set the ICU default |
268 // locale for renderer process here. | 144 // locale for renderer process here. |
269 // ICU locale will be used for fallback font selection etc. | 145 // ICU locale will be used for fallback font selection etc. |
270 if (parsed_command_line.HasSwitch(switches::kLang)) { | 146 if (parsed_command_line.HasSwitch(switches::kLang)) { |
271 const std::string locale = | 147 const std::string locale = |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 pool->Recycle(); | 231 pool->Recycle(); |
356 TRACE_EVENT_BEGIN("RendererMain.START_MSG_LOOP", 0, 0); | 232 TRACE_EVENT_BEGIN("RendererMain.START_MSG_LOOP", 0, 0); |
357 MessageLoop::current()->Run(); | 233 MessageLoop::current()->Run(); |
358 TRACE_EVENT_END("RendererMain.START_MSG_LOOP", 0, 0); | 234 TRACE_EVENT_END("RendererMain.START_MSG_LOOP", 0, 0); |
359 } | 235 } |
360 } | 236 } |
361 platform.PlatformUninitialize(); | 237 platform.PlatformUninitialize(); |
362 TRACE_EVENT_END("RendererMain", 0, ""); | 238 TRACE_EVENT_END("RendererMain", 0, ""); |
363 return 0; | 239 return 0; |
364 } | 240 } |
OLD | NEW |