agent/native/ext/Hooking.h (55 lines of code) (raw):
#pragma once
#include <main/php_version.h>
#include <Zend/zend_execute.h>
#include <Zend/zend_types.h>
#include <optional>
namespace elasticapm::php {
class Hooking {
public:
#if PHP_VERSION_ID < 70400
using zend_error_cb_lineno_t = uint;
#else
using zend_error_cb_lineno_t = uint32_t;
#endif
#if PHP_VERSION_ID < 80000
using zend_error_cb_t = void (*)(int type, const char *error_filename, const zend_error_cb_lineno_t error_lineno, const char *format, va_list args); //<8.0
#elif PHP_VERSION_ID < 80100
using zend_error_cb_t = void (*)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message); // 8.0
#else
using zend_error_cb_t = void (*)(int type, zend_string *error_filename, const uint32_t error_lineno, zend_string *message); // 8.1+
#endif
using zend_execute_internal_t = void (*)(zend_execute_data *execute_data, zval *return_value);
using zend_interrupt_function_t = void (*)(zend_execute_data *execute_data);
static Hooking &getInstance() {
static Hooking instance;
return instance;
}
void fetchOriginalHooks() {
original_execute_internal_ = zend_execute_internal;
original_zend_interrupt_function_ = zend_interrupt_function;
original_zend_error_cb_ = zend_error_cb;
}
void restoreOriginalHooks() {
zend_execute_internal = original_execute_internal_;
zend_interrupt_function = original_zend_interrupt_function_;
zend_error_cb = original_zend_error_cb_;
}
void replaceHooks(bool cfgCaptureErrors, bool cfgInferredSpansEnabled);
zend_execute_internal_t getOriginalExecuteInternal() {
return original_execute_internal_;
}
zend_interrupt_function_t getOriginalZendInterruptFunction() {
return original_zend_interrupt_function_;
}
zend_error_cb_t getOriginalZendErrorCb() {
return original_zend_error_cb_;
}
private:
Hooking(Hooking const &) = delete;
void operator=(Hooking const &) = delete;
Hooking() = default;
zend_execute_internal_t original_execute_internal_ = nullptr;
zend_interrupt_function_t original_zend_interrupt_function_ = nullptr;
zend_error_cb_t original_zend_error_cb_ = nullptr;
};
}