| 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 |