summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
authorpolina@google.com <polina@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-26 22:38:37 +0000
committerpolina@google.com <polina@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-26 22:38:37 +0000
commit6ed0388cbf008ea2c07ef81ef967f0639f982887 (patch)
treeddc6b8b68fb44d6213b7a9f007b9b57ed0bd6911 /ppapi
parentb73d08f40eea6bb93e3a807b36ebc2ed717b1f47 (diff)
downloadchromium_src-6ed0388cbf008ea2c07ef81ef967f0639f982887.zip
chromium_src-6ed0388cbf008ea2c07ef81ef967f0639f982887.tar.gz
chromium_src-6ed0388cbf008ea2c07ef81ef967f0639f982887.tar.bz2
NaCl PPAPI Proxy: wrap up with crash detection. Clean-up handling code to skip remote shutdown calls when the nexe is known to be dead. Add a test for crashing on other than the main thread, which depending on thread timing might happen when the main thread is servicing a PPP call or waiting for the next one. Add another test that will fail on a CHECK for an unsupported Pepper call off the main thread.
BUG= http://code.google.com/p/nativeclient/issues/detail?id=1780, http://code.google.com/p/nativeclient/issues/detail?id=2105, http://code.google.com/p/nativeclient/issues/detail?id=1682 TEST=scons run_ppapi_crash_browser_test Review URL: http://codereview.chromium.org/7741036 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@98507 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/browser_globals.cc3
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.cc10
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.h2
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_messaging_rpc_server.cc2
-rw-r--r--ppapi/native_client/src/trusted/plugin/plugin.cc15
-rw-r--r--ppapi/native_client/tests/ppapi_browser/crash/nacl.scons6
-rw-r--r--ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash.html41
-rw-r--r--ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_off_main_thread.cc48
-rw-r--r--ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_off_main_thread.nmf7
-rw-r--r--ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_ppapi_off_main_thread.cc40
-rw-r--r--ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_ppapi_off_main_thread.nmf7
11 files changed, 158 insertions, 23 deletions
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_globals.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_globals.cc
index 667f344..b1fa08e 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/browser_globals.cc
+++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_globals.cc
@@ -171,8 +171,7 @@ void CleanUpAfterDeadNexe(PP_Instance instance) {
BrowserPpp* proxy = LookupBrowserPppForInstance(instance);
if (proxy == NULL)
return;
- proxy->ShutdownModule();
- proxy->plugin()->ReportDeadNexe(); // Deletes the proxy.
+ proxy->plugin()->ReportDeadNexe(); // Shuts down and deletes the proxy.
}
void SetPPBGetInterface(PPB_GetInterface get_interface_function,
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.cc
index 1227f3e..18928b8 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.cc
+++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.cc
@@ -125,16 +125,18 @@ void BrowserPpp::ShutdownModule() {
CHECK(!is_nexe_alive_);
return; // The proxy has already been shut down.
}
- NaClSrpcError srpc_result =
- PppRpcClient::PPP_ShutdownModule(main_channel_);
- DebugPrintf("PPP_ShutdownModule: %s\n", NaClSrpcErrorString(srpc_result));
+ if (is_nexe_alive_) {
+ NaClSrpcError srpc_result =
+ PppRpcClient::PPP_ShutdownModule(main_channel_);
+ DebugPrintf("PPP_ShutdownModule: %s\n", NaClSrpcErrorString(srpc_result));
+ }
NaClThreadJoin(&upcall_thread_);
UnsetBrowserPppForInstance(plugin_->pp_instance());
UnsetModuleIdForSrpcChannel(main_channel_);
UnsetInstanceIdForSrpcChannel(main_channel_);
main_channel_ = NULL;
is_nexe_alive_ = false;
- DebugPrintf("PPP_Shutdown: done\n");
+ DebugPrintf("PPP_Shutdown: main_channel=NULL\n");
}
const void* BrowserPpp::GetPluginInterface(const char* interface_name) {
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.h b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.h
index 3ae6561..440b062 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.h
+++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppp.h
@@ -75,6 +75,8 @@ class BrowserPpp {
int plugin_pid() const { return plugin_pid_; }
plugin::Plugin* plugin() { return plugin_; }
+ void ReportDeadNexe() { is_nexe_alive_ = false; }
+
private:
// The "main" SRPC channel used to communicate with the plugin.
// NULL if proxy has been shut down.
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_messaging_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_messaging_rpc_server.cc
index 40c8cb5..eb3d27d 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_messaging_rpc_server.cc
+++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppp_messaging_rpc_server.cc
@@ -26,6 +26,6 @@ void PppMessagingRpcServer::PPP_Messaging_HandleMessage(
if (!DeserializeTo(rpc->channel, message_bytes, message_size, 1, &message))
return;
PPPMessagingInterface()->HandleMessage(instance, message);
- DebugPrintf("PPP_Instance::HandleMessage\n");
+ DebugPrintf("PPP_Messaging::HandleMessage\n");
rpc->result = NACL_SRPC_RESULT_OK;
}
diff --git a/ppapi/native_client/src/trusted/plugin/plugin.cc b/ppapi/native_client/src/trusted/plugin/plugin.cc
index 6a3d5c8..1fdf449 100644
--- a/ppapi/native_client/src/trusted/plugin/plugin.cc
+++ b/ppapi/native_client/src/trusted/plugin/plugin.cc
@@ -472,7 +472,7 @@ void Plugin::LoadMethods() {
}
bool Plugin::HasMethod(uintptr_t method_id, CallType call_type) {
- PLUGIN_PRINTF(("Plugin::HasMethod (method_id=%x) = ",
+ PLUGIN_PRINTF(("Plugin::HasMethod (method_id=%x)\n",
static_cast<int>(method_id)));
if (GetMethodInfo(method_id, call_type)) {
PLUGIN_PRINTF(("true\n"));
@@ -1305,6 +1305,8 @@ bool Plugin::StartProxiedExecution(NaClSrpcChannel* srpc_channel,
void Plugin::ReportDeadNexe() {
PLUGIN_PRINTF(("Plugin::ReportDeadNexe\n"));
+ if (ppapi_proxy_ != NULL)
+ ppapi_proxy_->ReportDeadNexe();
if (nacl_ready_state() == DONE) { // After loadEnd.
int64_t crash_time = NaClGetTimeOfDayMicroseconds();
@@ -1321,7 +1323,9 @@ void Plugin::ReportDeadNexe() {
CHECK(ppapi_proxy_ != NULL && !ppapi_proxy_->is_valid());
ShutdownProxy();
}
- // else LoadNaClModule and NexeFileDidOpen will provide error handling.
+ // else ReportLoadError() and ReportAbortError() will be used by loading code
+ // to provide error handling and proxy shutdown.
+ //
// NOTE: not all crashes during load will make it here.
// Those in BrowserPpp::InitializeModule and creation of PPP interfaces
// will just get reported back as PP_ERROR_FAILED.
@@ -1333,10 +1337,11 @@ void Plugin::ShutdownProxy() {
// We do not call remote PPP_Instance::DidDestroy because the untrusted
// side can no longer take full advantage of mostly asynchronous Pepper
// per-Instance interfaces at this point.
- if (BrowserPpp::is_valid(ppapi_proxy_))
+ if (ppapi_proxy_ != NULL) {
ppapi_proxy_->ShutdownModule();
- delete ppapi_proxy_;
- ppapi_proxy_ = NULL;
+ delete ppapi_proxy_;
+ ppapi_proxy_ = NULL;
+ }
}
void Plugin::NaClManifestBufferReady(int32_t pp_error) {
diff --git a/ppapi/native_client/tests/ppapi_browser/crash/nacl.scons b/ppapi/native_client/tests/ppapi_browser/crash/nacl.scons
index 7da4e0f..2f942e1 100644
--- a/ppapi/native_client/tests/ppapi_browser/crash/nacl.scons
+++ b/ppapi/native_client/tests/ppapi_browser/crash/nacl.scons
@@ -12,7 +12,11 @@ Import('env')
env.Prepend(CPPDEFINES=['XP_UNIX'])
-crash_types = ['via_check_failure', 'via_exit_call', 'in_callback']
+crash_types = ['via_check_failure',
+ 'via_exit_call',
+ 'in_callback',
+ 'off_main_thread',
+ 'ppapi_off_main_thread']
published_files = []
for crash_type in crash_types:
diff --git a/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash.html b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash.html
index 77b8dfe..c7df160 100644
--- a/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash.html
+++ b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash.html
@@ -23,21 +23,37 @@
name="nacl_module"
src="ppapi_crash_in_callback.nmf"
width="0" height="0" />
+ <embed type="application/x-nacl" id="crash_ppapi_off_main_thread"
+ name="nacl_module"
+ src="ppapi_crash_ppapi_off_main_thread.nmf"
+ width="0" height="0" />
+ <embed type="application/x-nacl" id="crash_off_main_thread"
+ name="nacl_module"
+ src="ppapi_crash_off_main_thread.nmf"
+ width="0" height="0" />
<script type="text/javascript">
//<![CDATA[
var tester = new Tester();
- function AddTest(plugin, testName, expectedHandler, unexpectedHandler) {
+ function AddTest(plugin, testName, expectedEvent, unexpectedEvent,
+ pingToDetectCrash) {
tester.addAsyncTest(testName, function(test) {
- plugin.addEventListener(
- expectedHandler,
- test.wrap(function(e) { test.pass(); }),
- false);
- plugin.addEventListener(
- unexpectedHandler,
- test.wrap(function(e) { test.fail(); }),
- false);
+ test.expectEvent(plugin, expectedEvent,
+ function(e) { test.pass(); });
+ test.expectEvent(plugin, unexpectedEvent,
+ function(e) { test.fail(); });
plugin.postMessage(testName);
+ // In case the nexe does not crash right away, we will ping it
+ // until we detect that it's death. DidChangeView and other events
+ // can do this too, but are less reliable.
+ if (pingToDetectCrash) {
+ function PingBack(message) {
+ test.log(message.data);
+ plugin.postMessage('Ping');
+ }
+ plugin.addEventListener('message', PingBack, false);
+ plugin.postMessage("Ping");
+ }
});
tester.waitFor(plugin);
}
@@ -46,7 +62,12 @@
'CrashViaCheckFailure', 'crash', 'error');
AddTest($('crash_via_exit_call'),
'CrashViaExitCall', 'crash', 'error');
- AddTest($('crash_in_callback'), 'CrashInCallback', 'crash', 'error');
+ AddTest($('crash_in_callback'),
+ 'CrashInCallback', 'crash', 'error');
+ AddTest($('crash_ppapi_off_main_thread'),
+ 'CrashPPAPIOffMainThread', 'crash', 'error');
+ AddTest($('crash_off_main_thread'),
+ 'CrashOffMainThread', 'crash', 'error', true);
tester.run();
//]]>
diff --git a/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_off_main_thread.cc b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_off_main_thread.cc
new file mode 100644
index 0000000..c5bbc47
--- /dev/null
+++ b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_off_main_thread.cc
@@ -0,0 +1,48 @@
+// Copyright (c) 2011 The Native Client Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Test that we handle crashes on threads other than main.
+
+#include <pthread.h>
+#include <stdio.h>
+
+#include "native_client/src/shared/platform/nacl_check.h"
+#include "native_client/tests/ppapi_test_lib/test_interface.h"
+
+namespace {
+
+void* CrashOffMainThreadFunction(void* thread_arg) {
+ printf("--- CrashOffMainThreadFunction\n");
+ usleep(1000); // Try to wait until PPP_Messaging::HandleMessage returns.
+ CRASH;
+ return NULL;
+}
+
+// Depending on how the detached thread is scheduled, this will either crash
+// during PPP_Messaging::HandleMessage or after it and before the next PPP call.
+// If a crash occurs within a PPP call, it returns an RPC error.
+// If a crash occurs between PPP calls, the next call will return an RPC error.
+void CrashOffMainThread() {
+ printf("--- CrashOffMainThread\n");
+ pthread_t tid;
+ pthread_create(&tid, NULL /*attr*/, CrashOffMainThreadFunction, NULL);
+ pthread_detach(tid);
+}
+
+// This will allow us to ping the nexe to detect a crash that occured
+// while the main thread was waiting for the next PPP call.
+void Ping() {
+ LOG_TO_BROWSER("ping received");
+}
+
+} // namespace
+
+void SetupTests() {
+ RegisterTest("CrashOffMainThread", CrashOffMainThread);
+ RegisterTest("Ping", Ping);
+}
+
+void SetupPluginInterfaces() {
+ // none
+}
diff --git a/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_off_main_thread.nmf b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_off_main_thread.nmf
new file mode 100644
index 0000000..322389f
--- /dev/null
+++ b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_off_main_thread.nmf
@@ -0,0 +1,7 @@
+{
+ "program": {
+ "x86-32": {"url": "ppapi_crash_off_main_thread_x86-32.nexe"},
+ "x86-64": {"url": "ppapi_crash_off_main_thread_x86-64.nexe"},
+ "arm": {"url": "ppapi_crash_off_main_thread_arm.nexe"}
+ }
+}
diff --git a/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_ppapi_off_main_thread.cc b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_ppapi_off_main_thread.cc
new file mode 100644
index 0000000..f32b10f
--- /dev/null
+++ b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_ppapi_off_main_thread.cc
@@ -0,0 +1,40 @@
+// Copyright (c) 2011 The Native Client Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Test that we kill the nexe on a CHECK and handle it gracefully on the
+// trusted side when untrusted code makes unsupported PPAPI calls
+// on other than the main thread.
+
+#include "native_client/src/shared/platform/nacl_check.h"
+#include "native_client/tests/ppapi_test_lib/get_browser_interface.h"
+#include "native_client/tests/ppapi_test_lib/test_interface.h"
+#include "ppapi/c/ppb_url_request_info.h"
+
+namespace {
+
+void* CrashOffMainThreadFunction(void* thread_arg) {
+ printf("--- CrashPPAPIOffMainThreadFunction\n");
+ PPBURLRequestInfo()->Create(pp_instance()); // Fatal CHECK failure.
+ return NULL;
+}
+
+
+// This will crash PPP_Messaging::HandleMessage.
+void CrashPPAPIOffMainThread() {
+ printf("--- CrashPPAPIOffMainThread\n");
+ pthread_t tid;
+ void* thread_result;
+ pthread_create(&tid, NULL /*attr*/, CrashOffMainThreadFunction, NULL);
+ pthread_join(tid, &thread_result); // Wait for the thread to crash.
+}
+
+} // namespace
+
+void SetupTests() {
+ RegisterTest("CrashPPAPIOffMainThread", CrashPPAPIOffMainThread);
+}
+
+void SetupPluginInterfaces() {
+ // none
+}
diff --git a/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_ppapi_off_main_thread.nmf b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_ppapi_off_main_thread.nmf
new file mode 100644
index 0000000..56aa503
--- /dev/null
+++ b/ppapi/native_client/tests/ppapi_browser/crash/ppapi_crash_ppapi_off_main_thread.nmf
@@ -0,0 +1,7 @@
+{
+ "program": {
+ "x86-32": {"url": "ppapi_crash_ppapi_off_main_thread_x86-32.nexe"},
+ "x86-64": {"url": "ppapi_crash_ppapi_off_main_thread_x86-64.nexe"},
+ "arm": {"url": "ppapi_crash_ppapi_off_main_thread_arm.nexe"}
+ }
+}