-
Notifications
You must be signed in to change notification settings - Fork 7.9k
New instrumentation API #5582
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New instrumentation API #5582
Conversation
Another prototype for our XHProf fork using this API: tideways/php-xhprof-extension#96 |
The instrument API can be used to add handlers that get called before and after a function call. An interested extension can add a call to `zend_instrument_register(...)` during MINIT; zend extensions can do the same during STARTUP. When a function is called for the first time, the registered instruments will be queried to provide the begin/end handlers they wish to install. If they do not want to instrument the function then they may return NULL for both handlers. Co-authored-by: Nikita Popov <[email protected]> Co-authored-by: Sammy Powers <[email protected]>
57b4289
to
350a95d
Compare
The failures are JIT related. A simple script that does
Running with
And it's pretty simple to see the direct sigsegv cause: |
This leaves room for other types of instruments in the future. Also passes the return_value into the end handler, or an undef one in the case of an exception.
Can you clarify what you have in mind here? Separate callback for whether to intrument and internal/userland function? |
Yes, split the decision code. Today we have execute_ex and execute_internal
and I want to match the ability to instrument none, one, or both.
…On Wed, May 20, 2020, 8:50 AM Nikita Popov ***@***.***> wrote:
Split the API for userland and internal functions. It's reasonable to
instrument only one or the other and the infrastructure itself is already
split so it won't be hard to do.
Can you clarify what you have in mind here? Separate callback for whether
to intrument and internal/userland function?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#5582 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAB53BGLMHEWIK5F7FZ3AXTRSPU2LANCNFSM4NBX3RLQ>
.
|
@dstogov I'm working on the ~24 non-JIT failures. What do you think of the general approach? Everyone I've collaborated with thinks it's okay but we don't have the same expertise in the engine as you (except Nikita). |
I afraid, the overhead of this patch is going to be enormous... :( I would like to disable ability to override execute_ex and provide simple and efficient solution, but this is not simple.
function my_execute_ex() {
$t = time();
orig_execute_ex();
echo time() - $t;
}
|
|
@dstogov Thanks for looking at this. About performance: when something registers on every function it's on par with I agree about local stack use being convenient, but this is literally the problem we have to avoid. We cannot use the C stack or it will overflow. This is a hard requirement. If we need to provide a temporary value from Why don't you see a reason for before/after callbacks for internal functions? It's the same as user functions: if I only instrument a few of them I should only pay costs for a few, not all of them. As mentioned it we want to split the API so you can instrument only USERLAND or only INTERNAL or BOTH; patch right now does both. |
I don't particularly care about this PR; what I (and other extension authors whom I've collaborated with) care about is an API that:
Hopefully you can see how we took these constraints and came up with the design of this PR. As mentioned we still have some things to do, but with my level of expertise in the engine I don't see how we can significantly change the design and achieve these goals. Global handlers are prone to users not calling previous handlers; see xdebug and the exception hooks, or basically any extension that uses opcode handlers; they ignore that other extensions might be doing the same thing. All it takes is one bad extension and it causes problems for all other extensions. We need to design it differently to make it harder to screw up. Using What do you think? I'm open to an alternative design, but it has to solve these goals (and maybe some others I forgot). I think this PR is decent. It solves the design goals or at least is not too far off. Aside from the already mentioned pieces, we probably still need to reduce the overhead when hooks are not used, though. |
I don't care about performance lose when instrumentation is enabled. I do care only about the overhead introduced by the patch even when instrumentation is disabled.
The existing API (zend_execute_internal) doesn't suffer from C stack problem. |
I understand your intention and like it, but I don't think it's practical to introduce a possibility for instrumentation with significant cost for production use. May be introduce special PHP compiler flag, that will use "extended" versions of DO_FCALL instructions with instrumentation. This way, we may chose between performance and instrumentation. |
If we can invalidate opcache (even file_cache) if this setting is changed (bidirectionally), then this is may work. Ideally it would also invalidate if the extensions list changes as there are already bugs there, but that's harder as it's a list of data instead of a single flag. If we can't invalidate opcache if this flag switches then it's not a viable approach, IMO. We'll prepare some performance numbers, but I hope we can choose performance and instrumentation, not one or the other. |
@dstogov Are there any op_array types that won't let me use the op_array extension? I'm trying to rework this PR to use the |
op_array->reserved[] must not be changed for op_arrays with ZEND_ACC_IMMUTABLE flag. run_time_cache and ZEND_OP_ARRAY_EXTENSION() should be used instead.
run_time_cache for closures may be duplicated during instantiation, but I don't see what kind of problems this may make. |
This patch takes into account the PHP 8.0 internal API changes in order to bring to php-spx a minimal / working PHP 8.0 support. The PHP 8.0 support can indeed be improved, especially regarding some new features like the JIT compiler, via the use of the new observer API which can replace the legacy, hook-based, one for most use cases. More details about the new observer API here: php/php-src#5582
This is a new API that tries to get the benefits of
zend_execute_ex
without the C stack overflow issue. It allows extensions to register function-specific begin/end handlers when the function is called for the first time in a request. This is intended for use by deterministic profilers, tracers, debuggers, security auditing, etc.An extension using the API can be found at sammyk/observer.
We plan to do these changes:
zend_test
extension.Some known limitations:
dtrace
does it then all extensions should also be able to do it.exit
or extensions that callzend_bailout
will not trigger the function close handler yet. We are hopingexit
will be implemented via an exception for PHP 8, but if not we will try handling this another way.