Merge pull request #1699 from drwez/suppressDefault
Suppress default exception handling
This commit is contained in:
commit
dd06b16e76
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user