mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-15 04:29:42 +00:00
[libFuzzer] Ignore synthetic exceptions on Fuchsia
Fuchsia has several exceptions which are merely informational and should not be treated as crashes. This patch puts logic that read from the exception port and handled the exception in a loop, and ignores non-exceptions and informational exceptions. Patch By: aarongreen Differential Revision: https://reviews.llvm.org/D62226 llvm-svn: 361407
This commit is contained in:
parent
418e23e33c
commit
9bd4dc929c
@ -13,6 +13,7 @@
|
||||
|
||||
#include "FuzzerInternal.h"
|
||||
#include "FuzzerUtil.h"
|
||||
#include <cassert>
|
||||
#include <cerrno>
|
||||
#include <cinttypes>
|
||||
#include <cstdint>
|
||||
@ -232,16 +233,28 @@ void CrashHandler(zx_handle_t *Event) {
|
||||
ExitOnErr(_zx_object_signal(*Event, 0, ZX_USER_SIGNAL_0),
|
||||
"_zx_object_signal");
|
||||
|
||||
// This thread lives as long as the process in order to keep handling
|
||||
// crashes. In practice, the first crashed thread to reach the end of the
|
||||
// StaticCrashHandler will end the process.
|
||||
while (true) {
|
||||
zx_port_packet_t Packet;
|
||||
ExitOnErr(_zx_port_wait(Port.Handle, ZX_TIME_INFINITE, &Packet),
|
||||
"_zx_port_wait");
|
||||
|
||||
// Ignore informational synthetic exceptions.
|
||||
assert(ZX_PKT_IS_EXCEPTION(Packet.type));
|
||||
if (ZX_EXCP_THREAD_STARTING == Packet.type ||
|
||||
ZX_EXCP_THREAD_EXITING == Packet.type ||
|
||||
ZX_EXCP_PROCESS_STARTING == Packet.type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// At this point, we want to get the state of the crashing thread, but
|
||||
// libFuzzer and the sanitizers assume this will happen from that same thread
|
||||
// via a POSIX signal handler. "Resurrecting" the thread in the middle of the
|
||||
// appropriate callback is as simple as forcibly setting the instruction
|
||||
// pointer/program counter, provided we NEVER EVER return from that function
|
||||
// (since otherwise our stack will not be valid).
|
||||
// libFuzzer and the sanitizers assume this will happen from that same
|
||||
// thread via a POSIX signal handler. "Resurrecting" the thread in the
|
||||
// middle of the appropriate callback is as simple as forcibly setting the
|
||||
// instruction pointer/program counter, provided we NEVER EVER return from
|
||||
// that function (since otherwise our stack will not be valid).
|
||||
ScopedHandle Thread;
|
||||
ExitOnErr(_zx_object_get_child(Self, Packet.exception.tid,
|
||||
ZX_RIGHT_SAME_RIGHTS, &Thread.Handle),
|
||||
@ -249,7 +262,8 @@ void CrashHandler(zx_handle_t *Event) {
|
||||
|
||||
zx_thread_state_general_regs_t GeneralRegisters;
|
||||
ExitOnErr(_zx_thread_read_state(Thread.Handle, ZX_THREAD_STATE_GENERAL_REGS,
|
||||
&GeneralRegisters, sizeof(GeneralRegisters)),
|
||||
&GeneralRegisters,
|
||||
sizeof(GeneralRegisters)),
|
||||
"_zx_thread_read_state");
|
||||
|
||||
// To unwind properly, we need to push the crashing thread's register state
|
||||
@ -277,12 +291,14 @@ void CrashHandler(zx_handle_t *Event) {
|
||||
#endif
|
||||
|
||||
// Now force the crashing thread's state.
|
||||
ExitOnErr(_zx_thread_write_state(Thread.Handle, ZX_THREAD_STATE_GENERAL_REGS,
|
||||
ExitOnErr(
|
||||
_zx_thread_write_state(Thread.Handle, ZX_THREAD_STATE_GENERAL_REGS,
|
||||
&GeneralRegisters, sizeof(GeneralRegisters)),
|
||||
"_zx_thread_write_state");
|
||||
|
||||
ExitOnErr(_zx_task_resume_from_exception(Thread.Handle, Port.Handle, 0),
|
||||
"_zx_task_resume_from_exception");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
Loading…
x
Reference in New Issue
Block a user