OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/nacl/renderer/nexe_load_manager.h" | 5 #include "components/nacl/renderer/nexe_load_manager.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/strings/string_tokenizer.h" | 10 #include "base/strings/string_tokenizer.h" |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
82 | 82 |
83 NexeLoadManager::NexeLoadManager( | 83 NexeLoadManager::NexeLoadManager( |
84 PP_Instance pp_instance) | 84 PP_Instance pp_instance) |
85 : pp_instance_(pp_instance), | 85 : pp_instance_(pp_instance), |
86 nacl_ready_state_(PP_NACL_READY_STATE_UNSENT), | 86 nacl_ready_state_(PP_NACL_READY_STATE_UNSENT), |
87 nexe_error_reported_(false), | 87 nexe_error_reported_(false), |
88 is_installed_(false), | 88 is_installed_(false), |
89 exit_status_(-1), | 89 exit_status_(-1), |
90 nexe_size_(0), | 90 nexe_size_(0), |
91 plugin_instance_(content::PepperPluginInstance::Get(pp_instance)), | 91 plugin_instance_(content::PepperPluginInstance::Get(pp_instance)), |
92 crash_info_shmem_handle_(base::SharedMemory::NULLHandle()), | |
92 weak_factory_(this) { | 93 weak_factory_(this) { |
93 SetLastError(""); | 94 SetLastError(""); |
94 HistogramEnumerateOsArch(GetSandboxArch()); | 95 HistogramEnumerateOsArch(GetSandboxArch()); |
95 if (plugin_instance_) { | 96 if (plugin_instance_) { |
96 plugin_base_url_ = | 97 plugin_base_url_ = |
97 plugin_instance_->GetContainer()->element().document().url(); | 98 plugin_instance_->GetContainer()->element().document().url(); |
98 } | 99 } |
99 } | 100 } |
100 | 101 |
101 NexeLoadManager::~NexeLoadManager() { | 102 NexeLoadManager::~NexeLoadManager() { |
102 if (!nexe_error_reported_) { | 103 if (!nexe_error_reported_) { |
103 base::TimeDelta uptime = base::Time::Now() - ready_time_; | 104 base::TimeDelta uptime = base::Time::Now() - ready_time_; |
104 HistogramTimeLarge("NaCl.ModuleUptime.Normal", uptime.InMilliseconds()); | 105 HistogramTimeLarge("NaCl.ModuleUptime.Normal", uptime.InMilliseconds()); |
105 } | 106 } |
107 if (base::SharedMemory::IsHandleValid(crash_info_shmem_handle_)) | |
108 base::SharedMemory::CloseHandle(crash_info_shmem_handle_); | |
106 } | 109 } |
107 | 110 |
108 void NexeLoadManager::NexeFileDidOpen(int32_t pp_error, | 111 void NexeLoadManager::NexeFileDidOpen(int32_t pp_error, |
109 const base::File& file, | 112 const base::File& file, |
110 int32_t http_status, | 113 int32_t http_status, |
111 int64_t nexe_bytes_read, | 114 int64_t nexe_bytes_read, |
112 const std::string& url, | 115 const std::string& url, |
113 base::TimeDelta time_since_open) { | 116 base::TimeDelta time_since_open) { |
114 // Check that we are on the main renderer thread. | 117 // Check that we are on the main renderer thread. |
115 DCHECK(content::RenderThread::Get()); | 118 DCHECK(content::RenderThread::Get()); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
224 SetLastError(error_string); | 227 SetLastError(error_string); |
225 | 228 |
226 // Inform JavaScript that loading was aborted and is complete. | 229 // Inform JavaScript that loading was aborted and is complete. |
227 DispatchProgressEvent(pp_instance_, ProgressEvent(PP_NACL_EVENT_ABORT)); | 230 DispatchProgressEvent(pp_instance_, ProgressEvent(PP_NACL_EVENT_ABORT)); |
228 DispatchProgressEvent(pp_instance_, ProgressEvent(PP_NACL_EVENT_LOADEND)); | 231 DispatchProgressEvent(pp_instance_, ProgressEvent(PP_NACL_EVENT_LOADEND)); |
229 | 232 |
230 HistogramEnumerateLoadStatus(PP_NACL_ERROR_LOAD_ABORTED, is_installed_); | 233 HistogramEnumerateLoadStatus(PP_NACL_ERROR_LOAD_ABORTED, is_installed_); |
231 LogToConsole(error_string); | 234 LogToConsole(error_string); |
232 } | 235 } |
233 | 236 |
234 void NexeLoadManager::NexeDidCrash(const char* crash_log) { | 237 void NexeLoadManager::NexeDidCrash() { |
235 VLOG(1) << "Plugin::NexeDidCrash: crash event!"; | 238 VLOG(1) << "Plugin::NexeDidCrash: crash event!"; |
236 // The NaCl module voluntarily exited. However, this is still a | 239 // The NaCl module voluntarily exited. However, this is still a |
237 // crash from the point of view of Pepper, since PPAPI plugins are | 240 // crash from the point of view of Pepper, since PPAPI plugins are |
238 // event handlers and should never exit. | 241 // event handlers and should never exit. |
239 VLOG_IF(1, exit_status_ != -1) | 242 VLOG_IF(1, exit_status_ != -1) |
240 << "Plugin::NexeDidCrash: nexe exited with status " << exit_status_ | 243 << "Plugin::NexeDidCrash: nexe exited with status " << exit_status_ |
241 << " so this is a \"controlled crash\"."; | 244 << " so this is a \"controlled crash\"."; |
242 // If the crash occurs during load, we just want to report an error | 245 // If the crash occurs during load, we just want to report an error |
243 // that fits into our load progress event grammar. If the crash | 246 // that fits into our load progress event grammar. If the crash |
244 // occurs after loaded/loadend, then we use ReportDeadNexe to send a | 247 // occurs after loaded/loadend, then we use ReportDeadNexe to send a |
245 // "crash" event. | 248 // "crash" event. |
246 if (nexe_error_reported_) { | 249 if (nexe_error_reported_) { |
247 VLOG(1) << "Plugin::NexeDidCrash: error already reported; suppressing"; | 250 VLOG(1) << "Plugin::NexeDidCrash: error already reported; suppressing"; |
248 } else { | 251 } else { |
249 if (nacl_ready_state_ == PP_NACL_READY_STATE_DONE) { | 252 if (nacl_ready_state_ == PP_NACL_READY_STATE_DONE) { |
250 ReportDeadNexe(); | 253 ReportDeadNexe(); |
251 } else { | 254 } else { |
252 ReportLoadError(PP_NACL_ERROR_START_PROXY_CRASH, | 255 ReportLoadError(PP_NACL_ERROR_START_PROXY_CRASH, |
253 "Nexe crashed during startup"); | 256 "Nexe crashed during startup"); |
254 } | 257 } |
255 } | 258 } |
256 // In all cases, try to grab the crash log. The first error | 259 // In all cases, try to grab the crash log. The first error |
257 // reported may have come from the start_module RPC reply indicating | 260 // reported may have come from the start_module RPC reply indicating |
258 // a validation error or something similar, which wouldn't grab the | 261 // a validation error or something similar, which wouldn't grab the |
259 // crash log. In the event that this is called twice, the second | 262 // crash log. In the event that this is called twice, the second |
260 // invocation will just be a no-op, since the entire crash log will | 263 // invocation will just be a no-op, since the entire crash log will |
261 // have been received and we'll just get an EOF indication. | 264 // have been received and we'll just get an EOF indication. |
262 CopyCrashLogToJsConsole(crash_log); | 265 |
266 base::SharedMemory shmem(crash_info_shmem_handle_, true); | |
267 if (shmem.Map(kNaClCrashInfoShmemSize)) { | |
268 uint32_t crash_log_length; | |
269 // We cast the length value to volatile here to prevent the compiler from | |
270 // reordering instructions in a way that could introduce a TOCTTOU race. | |
271 crash_log_length = *(static_cast<volatile uint32_t*>(shmem.memory())); | |
272 crash_log_length = std::min<uint32_t>(crash_log_length, | |
273 kNaClCrashInfoMaxLogSize); | |
274 | |
275 scoped_ptr<char[]> crash_log_data(new char[kNaClCrashInfoShmemSize]); | |
276 // char crash_log_data[kNaClCrashInfoShmemSize]; | |
Mark Seaborn
2014/08/19 23:38:51
I think you forgot to remove this.
teravest
2014/08/20 14:23:28
Removed.
| |
277 memcpy(crash_log_data.get(), | |
278 static_cast<char*>(shmem.memory()) + sizeof(uint32_t), | |
279 crash_log_length); | |
280 std::string crash_log(crash_log_data.get(), crash_log_length); | |
281 CopyCrashLogToJsConsole(crash_log); | |
282 } | |
263 } | 283 } |
264 | 284 |
265 void NexeLoadManager::set_trusted_plugin_channel( | 285 void NexeLoadManager::set_trusted_plugin_channel( |
266 scoped_ptr<TrustedPluginChannel> channel) { | 286 scoped_ptr<TrustedPluginChannel> channel) { |
267 trusted_plugin_channel_ = channel.Pass(); | 287 trusted_plugin_channel_ = channel.Pass(); |
268 } | 288 } |
269 | 289 |
270 void NexeLoadManager::set_manifest_service_channel( | 290 void NexeLoadManager::set_manifest_service_channel( |
271 scoped_ptr<ManifestServiceChannel> channel) { | 291 scoped_ptr<ManifestServiceChannel> channel) { |
272 manifest_service_channel_ = channel.Pass(); | 292 manifest_service_channel_ = channel.Pass(); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
417 // to provide error handling. | 437 // to provide error handling. |
418 } | 438 } |
419 | 439 |
420 void NexeLoadManager::CopyCrashLogToJsConsole(const std::string& crash_log) { | 440 void NexeLoadManager::CopyCrashLogToJsConsole(const std::string& crash_log) { |
421 base::StringTokenizer t(crash_log, "\n"); | 441 base::StringTokenizer t(crash_log, "\n"); |
422 while (t.GetNext()) | 442 while (t.GetNext()) |
423 LogToConsole(t.token()); | 443 LogToConsole(t.token()); |
424 } | 444 } |
425 | 445 |
426 } // namespace nacl | 446 } // namespace nacl |
OLD | NEW |