Skip to content

Commit

Permalink
Support debug init (#93)
Browse files Browse the repository at this point in the history
* Add Yasd\Api\setBreakpoint function

* Add execute_init_file

* Update init_file

* Format

* Check global is init

* Rename filename to fileAbsolutePath

* Call execute_init_file in rinit

* Check init_file is exist
  • Loading branch information
huanghantao committed Feb 10, 2021
1 parent c7ca465 commit 226be5a
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 1 deletion.
1 change: 1 addition & 0 deletions config.m4
Expand Up @@ -92,6 +92,7 @@ if test "$PHP_YASD" != "no"; then

yasd_source_file=" \
yasd.cc \
yasd_api.cc \
src/common.cc \
src/util.cc \
src/base.cc \
Expand Down
4 changes: 4 additions & 0 deletions init_file.php
@@ -0,0 +1,4 @@
<?php

echo 'execute init_file success' . PHP_EOL;
Yasd\Api\setBreakpoint(__DIR__ . DIRECTORY_SEPARATOR . 'test.php', 107);
1 change: 1 addition & 0 deletions php_yasd.h
Expand Up @@ -26,6 +26,7 @@ extern zend_module_entry yasd_module_entry;

ZEND_BEGIN_MODULE_GLOBALS(yasd)
char *breakpoints_file;
char *init_file;
char *debug_mode;
char *remote_host;
uint16_t remote_port;
Expand Down
37 changes: 37 additions & 0 deletions src/base.cc
Expand Up @@ -15,18 +15,53 @@
*/

#include <iostream>
#include <boost/filesystem.hpp>

#include "include/util.h"
#include "include/common.h"
#include "include/context.h"
#include "include/global.h"
#include "include/base.h"
#include "php_yasd.h"

#include "main/SAPI.h"
#include "Zend/zend_exceptions.h"

extern sapi_module_struct sapi_module;

static void (*old_execute_ex)(zend_execute_data *execute_data);

void execute_init_file() {
zval retval;
zend_file_handle file_handle;
zend_op_array *op_array;

if (!YASD_G(init_file)) {
return;
}

if (!boost::filesystem::exists(YASD_G(init_file))) {
yasd::Util::printfln_info(yasd::Color::YASD_ECHO_RED, "[yasd] init_file is configured, but does not exist");
exit(255);
}

memset(&file_handle, 0, sizeof(zend_file_handle));
file_handle.type = ZEND_HANDLE_FILENAME;
file_handle.filename = YASD_G(init_file);

CG(compiler_options) &= ~ZEND_COMPILE_EXTENDED_INFO;
op_array = zend_compile_file(&file_handle, ZEND_EVAL);
CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;

zend_execute_ex = old_execute_ex;
zend_execute(op_array, &retval);
zend_execute_ex = yasd_execute_ex;

zend_destroy_file_handle(&file_handle);
destroy_op_array(op_array);
efree_size(op_array, sizeof(zend_op_array));
}

bool skip_swoole_library_eval(zend_execute_data *execute_data) {
zend_op_array *op_array = &(execute_data->func->op_array);

Expand Down Expand Up @@ -179,6 +214,8 @@ void disable_opcache_optimizer() {
void yasd_rinit(int module_number) {
global = new yasd::Global();

execute_init_file();

disable_opcache_optimizer();
}

Expand Down
10 changes: 9 additions & 1 deletion yasd.cc
Expand Up @@ -29,7 +29,9 @@
#include "Zend/zend_extensions.h"
#include "Zend/zend_API.h"
#include "ext/standard/info.h"

#include "./php_yasd.h"
#include "yasd_api.h"

#include "include/util.h"
#include "include/context.h"
Expand All @@ -55,6 +57,8 @@ STD_PHP_INI_ENTRY("yasd.log_level", "-1", PHP_INI_ALL, OnUpdateLong,
log_level, zend_yasd_globals, yasd_globals)
STD_PHP_INI_ENTRY("yasd.max_executed_opline_num", "0", PHP_INI_ALL, OnUpdateLong,
max_executed_opline_num, zend_yasd_globals, yasd_globals)
STD_PHP_INI_ENTRY("yasd.init_file", "", PHP_INI_ALL, OnUpdateStringUnempty,
init_file, zend_yasd_globals, yasd_globals)

// compatible with phpstorm
STD_PHP_INI_ENTRY("xdebug.coverage_enable", "1", PHP_INI_ALL, OnUpdateLong,
Expand All @@ -70,7 +74,9 @@ STD_PHP_INI_ENTRY("xdebug.remote_mode", "req", PHP_INI_ALL, OnUpdateString,
PHP_INI_END()
// clang-format on

static void php_yasd_init_globals(zend_yasd_globals *yasd_globals) {}
static void php_yasd_init_globals(zend_yasd_globals *yasd_globals) {
memset(yasd_globals, 0, sizeof(zend_yasd_globals));
}

static void check_other_debugger() {
// We should not use the E_ERROR level, otherwise php --ini would throw fetal error
Expand Down Expand Up @@ -117,6 +123,8 @@ PHP_MINIT_FUNCTION(yasd) {

yasd_minit(module_number);

yasd_api_module_init(module_number);

return SUCCESS;
}

Expand Down
55 changes: 55 additions & 0 deletions yasd_api.cc
@@ -0,0 +1,55 @@
#include "main/php.h"
#include "main/SAPI.h"
#include "Zend/zend_extensions.h"
#include "Zend/zend_API.h"
#include "Zend/zend_exceptions.h"
#include "ext/standard/info.h"
#include "./php_yasd.h"

#include "include/global.h"

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_Yasd_Api_setBreakpoint, ZEND_RETURN_VALUE, 2, _IS_BOOL, 0)
ZEND_ARG_INFO(0, fileAbsolutePath)
ZEND_ARG_INFO(0, lineno)
ZEND_END_ARG_INFO()

static PHP_FUNCTION(Yasd_Api_setBreakpoint) {
zend_string *file_absolute_path;
zend_long lineno;

ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_STR(file_absolute_path)
Z_PARAM_LONG(lineno)
ZEND_PARSE_PARAMETERS_END();

if (!global) {
zend_throw_exception(zend_ce_exception, "debugger is not init", 0);
RETURN_FALSE;
}

auto iter = global->breakpoints->find(ZSTR_VAL(file_absolute_path));

if (iter != global->breakpoints->end()) {
iter->second.insert(lineno);
} else {
std::set<int> lineno_set;
lineno_set.insert(lineno);
global->breakpoints->insert(std::make_pair(ZSTR_VAL(file_absolute_path), lineno_set));
}

RETURN_TRUE;
}

static const zend_function_entry yasd_api_functions[] = {
ZEND_FENTRY(Yasd\\Api\\setBreakpoint, PHP_FN(Yasd_Api_setBreakpoint), arginfo_Yasd_Api_setBreakpoint, 0)
PHP_FE_END /* Must be the last line in yasd_functions[] */
};

int yasd_api_module_init(int module_number)
{
if (zend_register_functions(NULL, yasd_api_functions, NULL, MODULE_PERSISTENT) != SUCCESS) {
return FAILURE;
}

return SUCCESS;
}
3 changes: 3 additions & 0 deletions yasd_api.h
@@ -0,0 +1,3 @@
#pragma once

int yasd_api_module_init(int module_number);

0 comments on commit 226be5a

Please sign in to comment.