class CaptiveThread

Defined at line 74 of file ../../src/lib/captive-thread/include/lib/captive-thread/captive-thread.h

CaptiveThread is a large and immovable object. To move one around, create

it with std::make_unique

<CaptiveThread

>(...) and use it via std::unique_ptr.

CaptiveThread is constructed just like a std::thread to launch a thread.

Its ForceJoin() method forces the thread to exit before doing

std::thread::join. The thread is always joined this way on CaptiveThread

destruction.

Other methods provide for catching exceptions the thread hits or for

suspending it asynchronously; and for easily accessing its register state

while it's stopped for an exception or suspension.

Public Methods

void CaptiveThread (const CaptiveThread & )

Defined at line 88 of file ../../src/lib/captive-thread/include/lib/captive-thread/captive-thread.h

void CaptiveThread (CaptiveThread && other)

Defined at line 89 of file ../../src/lib/captive-thread/include/lib/captive-thread/captive-thread.h

template <typename F, typename... Args>
void CaptiveThread (F f, Args &&... args)

Defined at line 99 of file ../../src/lib/captive-thread/include/lib/captive-thread/captive-thread.h

bool Joined ()

True if ForceJoin() or BlockUntilSuccess() has already been called.

Defined at line 138 of file ../../src/lib/captive-thread/include/lib/captive-thread/captive-thread.h

zx::unowned_thread thread_handle ()

Borrow the thread's kernel handle. This handle is valid for the life of

the CaptiveThread object, even after the actual thread dies.

Defined at line 142 of file ../../src/lib/captive-thread/include/lib/captive-thread/captive-thread.h

zx::unowned_exception exception ()

Borrow the handle for the current exception. This handle is only valid

while InException() is true, until ResolveException() is called.

Defined at line 146 of file ../../src/lib/captive-thread/include/lib/captive-thread/captive-thread.h

zx::result<CaptiveThread *> WaitForException (zx::time deadline)

Wait for the thread to get an exception or exit. If this succeeds, then

either InException() is true, or the thread has exited. If the thread is

suspended, this will wait until it resumes and hits an exception or exits.

On success, the result value is just the `this` pointer. This return

value is accepted by the

<lib

/captive-thread/testing/matchers.h> gmock

matchers for `EXPECT_THAT(thread.WaitForException(), ...);` use in tests.

Defined at line 155 of file ../../src/lib/captive-thread/include/lib/captive-thread/captive-thread.h

zx::result<CaptiveThread *> WaitForStop (zx::time deadline)

Wait for the thread to be stopped in any fashion. If Suspend() hasn't

been called, then this is similar to WaitForException().

Defined at line 165 of file ../../src/lib/captive-thread/include/lib/captive-thread/captive-thread.h

bool InException ()

Report if the thread is currently stopped in exception or suspension, or

has a suspension in progress. If Suspend() has been called, then

InSuspend() and IsStopped() are true even if WaitForStop() is still needed

to actually synchronize and be able access registers, etc.

Defined at line 178 of file ../../src/lib/captive-thread/include/lib/captive-thread/captive-thread.h

bool InSuspend ()

Defined at line 179 of file ../../src/lib/captive-thread/include/lib/captive-thread/captive-thread.h

bool IsStopped ()

Defined at line 180 of file ../../src/lib/captive-thread/include/lib/captive-thread/captive-thread.h

std::optional<zx_exception_report_t> ExceptionReport ()

Return the report for the exception, or std::nullopt if !InException().

Defined at line 183 of file ../../src/lib/captive-thread/include/lib/captive-thread/captive-thread.h

void CaptiveThread (Routine )

Create a thread that runs the given function (can be move-only).

Defined at line 256 of file ../../src/lib/captive-thread/captive-thread.cc

zx::result<std::unique_ptr<CaptiveThread>> CreateRaw (std::string_view name, Raw regs, bool suspended)

This starts a new raw thread made with zx::thread::create(). The

arguments are the initial register values passed to zx::thread::start().

With the optional suspend flag set, Suspend() will be done before the

thread starts (it's still necessary to use WaitForStop() to examine it).

When a "raw" thread is started via CreateRaw() or StartRaw(), it must run

code that's pure assembly or otherwise refrains from any interaction with

normal ABI code or any libc expectations of any kind. If it's allowed to

run to completion, it must use zx_thread_exit() directly. When it's

forcibly "joined", that won't use std::thread::join() or run any normal

C++ or libc thread exit code. Instead, it will force the thread into an

exception state if not already there, and then force it to exit via the

exception handling mechanism.

Defined at line 581 of file ../../src/lib/captive-thread/captive-thread.cc

zx::result<std::unique_ptr<CaptiveThread>> StartRaw (zx::thread thread, Raw regs, zx::suspend_token )

This is like CreateRaw(), but takes ownership of a zx::thread already

created but not yet started. This allows the thread to be created in some

special fashion (even in another process), or have properties set,

etc. before it starts. To suspend the thread before it starts, pass in an

existing zx::suspend_token for it that's taken over as if from Suspend().

Defined at line 598 of file ../../src/lib/captive-thread/captive-thread.cc

void ~CaptiveThread ()

After destruction, the thread is guaranteed to be exited and joined.

Defined at line 252 of file ../../src/lib/captive-thread/captive-thread.cc

void ForceJoin ()

If the thread is not already exiting, then force it to exit. Then join

with it as in std::thread::join. Other methods are not necessarily valid

after ForceJoin(), but it is always safe to call ForceJoin() again or to

call ForceJoin() after BlockUntilSuccess().

Defined at line 265 of file ../../src/lib/captive-thread/captive-thread.cc

zx::result<> Suspend ()

Request a thread suspension. If it's already stopped in any fashion, this

returns immediate success.

Defined at line 400 of file ../../src/lib/captive-thread/captive-thread.cc

void BlockUntilSuccess ()

This presumes the thread will finish running the function and waits until

it has done so. If the thread gets an exception, it will not be caught.

Must not be called when IsStopped().

Defined at line 475 of file ../../src/lib/captive-thread/captive-thread.cc

template <RegistersType Regs = zx_thread_state_general_regs_t>
zx::result<Regs> Registers ()

Fetch the thread registers. This caches the value until the next

resumption or SetRegisters(), so it's cheap to call repeatedly.

Defined at line 356 of file ../../src/lib/captive-thread/captive-thread.cc

template <RegistersType Regs = zx_thread_state_general_regs_t>
zx::result<> SetRegisters (const Regs & regs)

Modify the thread registers. This clears any values previously cached and

does zx::thread::write_state, so the next Registers

<Regs

>() call will read

the normalized values back with zx::thread::read_state.

Defined at line 384 of file ../../src/lib/captive-thread/captive-thread.cc

void ResolveException ()

Resume and resolve the exception so no other handler will see it. Must be

called when InException() is true.

Defined at line 407 of file ../../src/lib/captive-thread/captive-thread.cc

void Resume ()

Resume from being stopped. Must be called when IsStopped() is true. When

InException(), this results in cascading to the next exception handler

(system crash service, etc.).

Defined at line 423 of file ../../src/lib/captive-thread/captive-thread.cc

zx::result<> ResolveExceptionSingleStep ()

As above, but resume with single-step enabled.

Defined at line 413 of file ../../src/lib/captive-thread/captive-thread.cc

zx::result<> ResumeSingleStep ()

Defined at line 428 of file ../../src/lib/captive-thread/captive-thread.cc

zx::result<CaptiveThread *> StepToException (zx::time deadline)

This is shorthand for ResolveExceptionSingleStep() and WaitForException().

Defined at line 574 of file ../../src/lib/captive-thread/captive-thread.cc

Records

Friends

void CaptiveThread (const CaptiveThread & std::ostream * os)