mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 22:16:13 +00:00
ExceptionPorts::GetExceptionPorts(): don’t return ExceptionHandler
elements whose handler port would be MACH_PORT_NULL. For most exception targets, *_get_exception_ports() will normally return an exception port of MACH_PORT_NULL when no handler is registered. However, as of Mac OS X 10.9, thread_get_exception_ports() will return an empty list when no handler is registered for any exception type on a thread. Consequently, a caller would have to do additional processing to determine whether a specific exception port is registered: an unregistered port will either appear but have a handler port of MACH_PORT_NULL, or it will not appear at all. This is confusing for callers. The behaviors are unified, and when a handler port of MACH_PORT_NULL is found, it will not be returned to the caller. This is expected to be the simpler of the two possible behaviors for callers to make use of. The change in the kernel can be seen by comparing 10.8.5 xnu-2050.48.11/osfmk/kern/ipc_tt.c thread_get_exception_ports() to the same function in 10.9.4 xnu-2422.110.17. The 10.9 version has a special check for thread->exc_actions being NULL, which short-circuits the rest of the function without returning any exception ports. In 10.8.5, thread->exc_actions can never be NULL. This new check is only present for thread targets, presumably because it’s very common for threads to not have any exception ports set, and not having to initialize this data is an optimization. Typical user-level tasks in Mac OS X always have at least some exception ports set at the task level. TEST=util_test ExceptionPorts.TaskAndThreadExceptionPorts R=rsesek@chromium.org Review URL: https://codereview.chromium.org/584223002
This commit is contained in:
parent
c93fcf8278
commit
51e696ade9
@ -99,12 +99,14 @@ bool ExceptionPorts::GetExceptionPorts(
|
||||
|
||||
handlers->clear();
|
||||
for (mach_msg_type_number_t index = 0; index < handler_count; ++index) {
|
||||
ExceptionHandler handler;
|
||||
handler.mask = masks[index];
|
||||
handler.port = ports[index];
|
||||
handler.behavior = behaviors[index];
|
||||
handler.flavor = flavors[index];
|
||||
handlers->push_back(handler);
|
||||
if (ports[index] != MACH_PORT_NULL) {
|
||||
ExceptionHandler handler;
|
||||
handler.mask = masks[index];
|
||||
handler.port = ports[index];
|
||||
handler.behavior = behaviors[index];
|
||||
handler.flavor = flavors[index];
|
||||
handlers->push_back(handler);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -112,7 +112,11 @@ class ExceptionPorts {
|
||||
//! \param[out] handlers The exception handlers registered for \a target_port
|
||||
//! to handle exceptions indicated in \a mask. The caller must take
|
||||
//! ownership of the \a port members of the returned ExceptionHandler
|
||||
//! objects. On failure, this argument is untouched.
|
||||
//! objects. If no execption port is registered for a bit in \a mask, \a
|
||||
//! handlers will not contain an entry corresponding to that bit. This is
|
||||
//! a departure from the `*_get_exception_ports()` functions, which may
|
||||
//! return a handler whose port is set to `EXCEPTION_PORT_NULL` in this
|
||||
//! case. On failure, this argument is untouched.
|
||||
//!
|
||||
//! \return `true` if `*_get_exception_ports()` returned `KERN_SUCCESS`, with
|
||||
//! \a handlers set appropriately. `false` otherwise, with an appropriate
|
||||
|
Loading…
x
Reference in New Issue
Block a user