Unless `zend_test.observer.enabled` is on, we must not add observer
handlers, so we let the INI modify handler fail early.
We also need to ensure that the functions to observe have already been
called, so that their begin and end handlers are properly initialized.
Otherwise we will not observe the function execution, but a segfault.
Co-authored-by: Bob Weinand <bobwei9@hotmail.com>
Closes GH-16438.
zend_pass_function also has no name, so we might also be referring to an
internal function here. In this case, ZEND_NEW uses the zend_pass_function when
there is no constructor.
Fixes GH-16294
Closes GH-16301
The usage of the current API within an observer handler leads to bugs like https://bugs.xdebug.org/view.php?id=2232.
Given two observer handlers, next to each other. The first one is executed. It removes itself. The second observer handler gets moved to the place of the first. The first one returns. The handler in the second slot is fetched, but is now NULL, because the it's now in the slot of the first observer; i.e. the second handler is skipped and the begin/end symmetry guarantee is violated.
Providing the next handler to the caller is a zero-cost way to avoid any impact in the paths of zend_observe_fcall_begin/end.
Signed-off-by: Bob Weinand <bobwei9@hotmail.com>
`zend_uchar` suggests that the value is an ASCII character, but here,
it's about very small integers. This is misleading, so let's use a
C99 integer instead.
On all architectures currently supported by PHP, `zend_uchar` and
`uint8_t` are identical. This change is only about code readability.
There are two main motivations to this:
a) The logic for handling internal and userland observation can be unified.
b) Unwinding of observed functions on a bailout does notably not include observers. Even if users of observers were to ensure such handling themselves, it would be impossible to retain the relative ordering - either the user has to unwind all internal observed frames before the automatic unwinding (zend_observer_fcall_end_all) or afterwards, but not properly interleaved.
Signed-off-by: Bob Weinand <bobwei9@hotmail.com>
Properly use globals init/shutdown to allocate the observer_observe_function_names hashtable instead of attempting to do everything in the ini changed handler