Merge pull request #1699 from drwez/suppressDefault

Suppress default exception handling
This commit is contained in:
Gennadiy Civil 2018-08-07 08:08:39 -07:00 committed by GitHub
commit dd06b16e76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -67,6 +67,7 @@
# include <lib/fdio/spawn.h> # include <lib/fdio/spawn.h>
# include <zircon/processargs.h> # include <zircon/processargs.h>
# include <zircon/syscalls.h> # include <zircon/syscalls.h>
# include <zircon/syscalls/port.h>
# endif // GTEST_OS_FUCHSIA # endif // GTEST_OS_FUCHSIA
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
@ -805,6 +806,12 @@ class FuchsiaDeathTest : public DeathTestImpl {
const char* file, const char* file,
int line) int line)
: DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {}
virtual ~FuchsiaDeathTest() {
zx_status_t status = zx_handle_close(child_process_);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
status = zx_handle_close(port_);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
}
// All of these virtual functions are inherited from DeathTest. // All of these virtual functions are inherited from DeathTest.
virtual int Wait(); virtual int Wait();
@ -816,7 +823,8 @@ class FuchsiaDeathTest : public DeathTestImpl {
// The line number on which the death test is located. // The line number on which the death test is located.
const int line_; const int line_;
zx_handle_t child_process_; zx_handle_t child_process_ = ZX_HANDLE_INVALID;
zx_handle_t port_ = ZX_HANDLE_INVALID;
}; };
// Utility class for accumulating command-line arguments. // Utility class for accumulating command-line arguments.
@ -863,16 +871,38 @@ int FuchsiaDeathTest::Wait() {
if (!spawned()) if (!spawned())
return 0; return 0;
// Wait for child process to terminate. // Register to wait for the child process to terminate.
zx_status_t status_zx; zx_status_t status_zx;
zx_signals_t signals; status_zx = zx_object_wait_async(child_process_,
status_zx = zx_object_wait_one( port_,
child_process_, 0 /* key */,
ZX_PROCESS_TERMINATED, ZX_PROCESS_TERMINATED,
ZX_TIME_INFINITE, ZX_WAIT_ASYNC_ONCE);
&signals);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
// Wait for it to terminate, or an exception to be received.
zx_port_packet_t packet;
status_zx = zx_port_wait(port_, ZX_TIME_INFINITE, &packet);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
if (ZX_PKT_IS_EXCEPTION(packet.type)) {
// Process encountered an exception. Kill it directly rather than letting
// other handlers process the event.
status_zx = zx_task_kill(child_process_);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
// Now wait for |child_process_| to terminate.
zx_signals_t signals = 0;
status_zx = zx_object_wait_one(
child_process_, ZX_PROCESS_TERMINATED, ZX_TIME_INFINITE, &signals);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
GTEST_DEATH_TEST_CHECK_(signals & ZX_PROCESS_TERMINATED);
} else {
// Process terminated.
GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type));
GTEST_DEATH_TEST_CHECK_(packet.observed & ZX_PROCESS_TERMINATED);
}
ReadAndInterpretStatusByte(); ReadAndInterpretStatusByte();
zx_info_process_t buffer; zx_info_process_t buffer;
@ -936,13 +966,10 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
set_read_fd(status); set_read_fd(status);
// Set the pipe handle for the child. // Set the pipe handle for the child.
fdio_spawn_action_t add_handle_action = { fdio_spawn_action_t add_handle_action = {};
.action = FDIO_SPAWN_ACTION_ADD_HANDLE, add_handle_action.action = FDIO_SPAWN_ACTION_ADD_HANDLE;
.h = { add_handle_action.h.id = PA_HND(type, kFuchsiaReadPipeFd);
.id = PA_HND(type, kFuchsiaReadPipeFd), add_handle_action.h.handle = child_pipe_handle;
.handle = child_pipe_handle
}
};
// Spawn the child process. // Spawn the child process.
status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL,
@ -950,6 +977,14 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
&add_handle_action, &child_process_, nullptr); &add_handle_action, &child_process_, nullptr);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK); GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
// Create an exception port and attach it to the |child_process_|, to allow
// us to suppress the system default exception handler from firing.
status = zx_port_create(0, &port_);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
status = zx_task_bind_exception_port(
child_process_, port_, 0 /* key */, 0 /*options */);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
set_spawned(true); set_spawned(true);
return OVERSEE_TEST; return OVERSEE_TEST;
} }