mirror of
https://github.com/php/php-src.git
synced 2024-09-22 10:27:25 +00:00
Remove the ugly hack via a temp file to store breakpoints
This commit is contained in:
parent
fd8a70b1ee
commit
297baa0c18
@ -1039,13 +1039,7 @@ int main(int argc, char **argv) /* {{{ */
|
||||
zend_bool remote = 0;
|
||||
int step = 0;
|
||||
zend_phpdbg_globals *settings = NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
char *bp_tmp_file = NULL;
|
||||
#else
|
||||
char bp_tmp_file[] = "/tmp/phpdbg.XXXXXX";
|
||||
#endif
|
||||
|
||||
char *bp_tmp = NULL;
|
||||
char *address;
|
||||
int listen = -1;
|
||||
int server = -1;
|
||||
@ -1081,29 +1075,6 @@ int main(int argc, char **argv) /* {{{ */
|
||||
#endif
|
||||
|
||||
phpdbg_main:
|
||||
if (!cleaning) {
|
||||
|
||||
#ifdef _WIN32
|
||||
bp_tmp_file = malloc(L_tmpnam);
|
||||
|
||||
if (bp_tmp_file) {
|
||||
if (!tmpnam(bp_tmp_file)) {
|
||||
free(bp_tmp_file);
|
||||
bp_tmp_file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bp_tmp_file) {
|
||||
phpdbg_error("tmpfile", "", "Unable to create temporary file");
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
if (!mkstemp(bp_tmp_file)) {
|
||||
memset(bp_tmp_file, 0, sizeof(bp_tmp_file));
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
ini_entries = NULL;
|
||||
ini_entries_len = 0;
|
||||
ini_ignore = 0;
|
||||
@ -1502,9 +1473,13 @@ phpdbg_main:
|
||||
PHPDBG_G(flags) |= PHPDBG_IS_INITIALIZING;
|
||||
zend_try {
|
||||
phpdbg_init(init_file, init_file_len, init_file_default TSRMLS_CC);
|
||||
PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
|
||||
phpdbg_try_file_init(bp_tmp_file, strlen(bp_tmp_file), 0 TSRMLS_CC);
|
||||
PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
|
||||
if (bp_tmp) {
|
||||
PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
|
||||
phpdbg_string_init(bp_tmp TSRMLS_CC);
|
||||
free(bp_tmp);
|
||||
bp_tmp = NULL;
|
||||
PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
|
||||
}
|
||||
} zend_end_try();
|
||||
PHPDBG_G(flags) &= ~PHPDBG_IS_INITIALIZING;
|
||||
|
||||
@ -1532,23 +1507,27 @@ phpdbg_interact:
|
||||
do {
|
||||
zend_try {
|
||||
if (phpdbg_startup_run) {
|
||||
zend_bool quit_immediately = phpdbg_startup_run > 1;
|
||||
phpdbg_startup_run = 0;
|
||||
PHPDBG_COMMAND_HANDLER(run)(NULL TSRMLS_CC);
|
||||
if (phpdbg_startup_run > 1) {
|
||||
if (quit_immediately) {
|
||||
/* if -r is on the command line more than once just quit */
|
||||
EG(bailout) = __orig_bailout; /* reset zend_try */
|
||||
break;
|
||||
}
|
||||
phpdbg_startup_run = 0;
|
||||
}
|
||||
|
||||
phpdbg_interactive(1 TSRMLS_CC);
|
||||
} zend_catch {
|
||||
if ((PHPDBG_G(flags) & PHPDBG_IS_CLEANING)) {
|
||||
FILE *bp_tmp_fp = fopen(bp_tmp_file, "w");
|
||||
char *bp_tmp_str;
|
||||
PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
|
||||
phpdbg_export_breakpoints(bp_tmp_fp TSRMLS_CC);
|
||||
phpdbg_export_breakpoints_to_string(&bp_tmp_str TSRMLS_CC);
|
||||
PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
|
||||
fclose(bp_tmp_fp);
|
||||
if (bp_tmp_str) {
|
||||
bp_tmp = strdup(bp_tmp_str);
|
||||
efree(bp_tmp_str);
|
||||
}
|
||||
cleaning = 1;
|
||||
} else {
|
||||
cleaning = 0;
|
||||
@ -1688,11 +1667,5 @@ phpdbg_out:
|
||||
free(PHPDBG_G(sapi_name_ptr));
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
free(bp_tmp_file);
|
||||
#else
|
||||
unlink(bp_tmp_file);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
} /* }}} */
|
||||
|
@ -110,11 +110,20 @@ PHPDBG_API void phpdbg_reset_breakpoints(TSRMLS_D) /* {{{ */
|
||||
} /* }}} */
|
||||
|
||||
PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
char *string;
|
||||
phpdbg_export_breakpoints_to_string(&string TSRMLS_CC);
|
||||
fputs(string, handle);
|
||||
}
|
||||
|
||||
PHPDBG_API void phpdbg_export_breakpoints_to_string(char **str TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
HashPosition position[2];
|
||||
HashTable **table = NULL;
|
||||
zend_ulong id = 0L;
|
||||
|
||||
*str = "";
|
||||
|
||||
if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])) {
|
||||
phpdbg_notice("exportbreakpoint", "count=\"%d\"", "Exporting %d breakpoints", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]));
|
||||
/* this only looks like magic, it isn't */
|
||||
@ -126,55 +135,57 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
|
||||
zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], NULL, NULL, &id, 0, &position[0]);
|
||||
|
||||
for (zend_hash_internal_pointer_reset_ex((*table), &position[1]);
|
||||
zend_hash_get_current_data_ex((*table), (void**)&brake, &position[1]) == SUCCESS;
|
||||
zend_hash_move_forward_ex((*table), &position[1])) {
|
||||
zend_hash_get_current_data_ex((*table), (void**)&brake, &position[1]) == SUCCESS;
|
||||
zend_hash_move_forward_ex((*table), &position[1])) {
|
||||
if (brake->id == id) {
|
||||
char *new_str = NULL;
|
||||
|
||||
switch (brake->type) {
|
||||
case PHPDBG_BREAK_FILE: {
|
||||
fprintf(handle,
|
||||
"break %s:%lu\n",
|
||||
phpdbg_asprintf(&new_str,
|
||||
"%sbreak %s:%lu\n", *str,
|
||||
((phpdbg_breakfile_t*)brake)->filename,
|
||||
((phpdbg_breakfile_t*)brake)->line);
|
||||
} break;
|
||||
|
||||
case PHPDBG_BREAK_SYM: {
|
||||
fprintf(handle,
|
||||
"break %s\n",
|
||||
phpdbg_asprintf(&new_str,
|
||||
"%sbreak %s\n", *str,
|
||||
((phpdbg_breaksymbol_t*)brake)->symbol);
|
||||
} break;
|
||||
|
||||
case PHPDBG_BREAK_METHOD: {
|
||||
fprintf(handle,
|
||||
"break %s::%s\n",
|
||||
phpdbg_asprintf(&new_str,
|
||||
"%sbreak %s::%s\n", *str,
|
||||
((phpdbg_breakmethod_t*)brake)->class_name,
|
||||
((phpdbg_breakmethod_t*)brake)->func_name);
|
||||
} break;
|
||||
|
||||
case PHPDBG_BREAK_METHOD_OPLINE: {
|
||||
fprintf(handle,
|
||||
"break %s::%s#%ld\n",
|
||||
phpdbg_asprintf(&new_str,
|
||||
"%sbreak %s::%s#%ld\n", *str,
|
||||
((phpdbg_breakopline_t*)brake)->class_name,
|
||||
((phpdbg_breakopline_t*)brake)->func_name,
|
||||
((phpdbg_breakopline_t*)brake)->opline_num);
|
||||
} break;
|
||||
|
||||
case PHPDBG_BREAK_FUNCTION_OPLINE: {
|
||||
fprintf(handle,
|
||||
"break %s#%ld\n",
|
||||
phpdbg_asprintf(&new_str,
|
||||
"%sbreak %s#%ld\n", *str,
|
||||
((phpdbg_breakopline_t*)brake)->func_name,
|
||||
((phpdbg_breakopline_t*)brake)->opline_num);
|
||||
} break;
|
||||
|
||||
case PHPDBG_BREAK_FILE_OPLINE: {
|
||||
fprintf(handle,
|
||||
"break %s:#%ld\n",
|
||||
phpdbg_asprintf(&new_str,
|
||||
"%sbreak %s:#%ld\n", *str,
|
||||
((phpdbg_breakopline_t*)brake)->class_name,
|
||||
((phpdbg_breakopline_t*)brake)->opline_num);
|
||||
} break;
|
||||
|
||||
case PHPDBG_BREAK_OPCODE: {
|
||||
fprintf(handle,
|
||||
"break %s\n",
|
||||
phpdbg_asprintf(&new_str,
|
||||
"%sbreak %s\n", *str,
|
||||
((phpdbg_breakop_t*)brake)->name);
|
||||
} break;
|
||||
|
||||
@ -184,20 +195,20 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
|
||||
if (conditional->paramed) {
|
||||
switch (conditional->param.type) {
|
||||
case STR_PARAM:
|
||||
fprintf(handle,
|
||||
"break at %s if %s\n", conditional->param.str, conditional->code);
|
||||
phpdbg_asprintf(&new_str,
|
||||
"%sbreak at %s if %s\n", *str, conditional->param.str, conditional->code);
|
||||
break;
|
||||
|
||||
case METHOD_PARAM:
|
||||
fprintf(handle,
|
||||
"break at %s::%s if %s\n",
|
||||
phpdbg_asprintf(&new_str,
|
||||
"%sbreak at %s::%s if %s\n", *str,
|
||||
conditional->param.method.class, conditional->param.method.name,
|
||||
conditional->code);
|
||||
break;
|
||||
|
||||
case FILE_PARAM:
|
||||
fprintf(handle,
|
||||
"break at %s:%lu if %s\n",
|
||||
phpdbg_asprintf(&new_str,
|
||||
"%sbreak at %s:%lu if %s\n", *str,
|
||||
conditional->param.file.name, conditional->param.file.line,
|
||||
conditional->code);
|
||||
break;
|
||||
@ -205,15 +216,23 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
|
||||
default: { /* do nothing */ } break;
|
||||
}
|
||||
} else {
|
||||
fprintf(
|
||||
handle, "break if %s\n", conditional->code);
|
||||
phpdbg_asprintf(&new_str, "%sbreak if %s\n", str, conditional->code);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
if ((*str)[0]) {
|
||||
efree(*str);
|
||||
}
|
||||
*str = new_str;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(*str)[0]) {
|
||||
*str = NULL;
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRMLS_DC) /* {{{ */
|
||||
|
@ -157,6 +157,7 @@ PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase(zend_ulong id TSRMLS_DC);
|
||||
PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable ***table, HashPosition *position TSRMLS_DC); /* }}} */
|
||||
|
||||
/* {{{ Breakpoint Exportation API */
|
||||
PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC); /* }}} */
|
||||
PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC);
|
||||
PHPDBG_API void phpdbg_export_breakpoints_to_string(char **str TSRMLS_DC); /* }}} */
|
||||
|
||||
#endif /* PHPDBG_BP_H */
|
||||
|
@ -208,6 +208,110 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ *
|
||||
return FAILURE;
|
||||
} /* }}} */
|
||||
|
||||
struct phpdbg_init_state {
|
||||
int line;
|
||||
zend_bool in_code;
|
||||
char *code;
|
||||
size_t code_len;
|
||||
const char *init_file;
|
||||
};
|
||||
|
||||
static void phpdbg_line_init(char *cmd, struct phpdbg_init_state *state TSRMLS_DC) {
|
||||
size_t cmd_len = strlen(cmd);
|
||||
|
||||
state->line++;
|
||||
|
||||
while (cmd_len > 0L && isspace(cmd[cmd_len-1])) {
|
||||
cmd_len--;
|
||||
}
|
||||
|
||||
cmd[cmd_len] = '\0';
|
||||
|
||||
if (*cmd && cmd_len > 0L && cmd[0] != '#') {
|
||||
if (cmd_len == 2) {
|
||||
if (memcmp(cmd, "<:", sizeof("<:")-1) == SUCCESS) {
|
||||
state->in_code = 1;
|
||||
return;
|
||||
} else {
|
||||
if (memcmp(cmd, ":>", sizeof(":>")-1) == SUCCESS) {
|
||||
state->in_code = 0;
|
||||
state->code[state->code_len] = '\0';
|
||||
zend_eval_stringl(state->code, state->code_len, NULL, "phpdbginit code" TSRMLS_CC);
|
||||
free(state->code);
|
||||
state->code = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state->in_code) {
|
||||
if (state->code == NULL) {
|
||||
state->code = malloc(cmd_len + 1);
|
||||
} else {
|
||||
state->code = realloc(state->code, state->code_len + cmd_len + 1);
|
||||
}
|
||||
|
||||
if (state->code) {
|
||||
memcpy(&state->code[state->code_len], cmd, cmd_len);
|
||||
state->code_len += cmd_len;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
zend_try {
|
||||
char *input = phpdbg_read_input(cmd TSRMLS_CC);
|
||||
phpdbg_param_t stack;
|
||||
|
||||
phpdbg_init_param(&stack, STACK_PARAM);
|
||||
|
||||
phpdbg_activate_err_buf(1 TSRMLS_CC);
|
||||
|
||||
if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) {
|
||||
switch (phpdbg_stack_execute(&stack, 1 /* allow_async_unsafe == 1 */ TSRMLS_CC)) {
|
||||
case FAILURE:
|
||||
phpdbg_activate_err_buf(0 TSRMLS_CC);
|
||||
if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) {
|
||||
if (state->init_file) {
|
||||
phpdbg_output_err_buf("initfailure", "%b file=\"%s\" line=\"%d\" input=\"%s\"", "Unrecognized command in %s:%d: %s, %b!" TSRMLS_CC, state->init_file, state->line, input);
|
||||
} else {
|
||||
phpdbg_output_err_buf("initfailure", "%b line=\"%d\" input=\"%s\"", "Unrecognized command on line %d: %s, %b!" TSRMLS_CC, state->line, input);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
phpdbg_activate_err_buf(0 TSRMLS_CC);
|
||||
phpdbg_free_err_buf(TSRMLS_C);
|
||||
|
||||
phpdbg_stack_free(&stack);
|
||||
phpdbg_destroy_input(&input TSRMLS_CC);
|
||||
} zend_catch {
|
||||
PHPDBG_G(flags) &= ~(PHPDBG_IS_RUNNING | PHPDBG_IS_CLEANING);
|
||||
if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) {
|
||||
zend_bailout();
|
||||
}
|
||||
} zend_end_try();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void phpdbg_string_init(char *buffer TSRMLS_DC) {
|
||||
struct phpdbg_init_state state = {0};
|
||||
char *str = strtok(buffer, "\n");
|
||||
|
||||
while (str) {
|
||||
phpdbg_line_init(str, &state TSRMLS_CC);
|
||||
|
||||
str = strtok(NULL, "\n");
|
||||
}
|
||||
|
||||
if (state.code) {
|
||||
free(state.code);
|
||||
}
|
||||
}
|
||||
|
||||
void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
struct stat sb;
|
||||
@ -215,91 +319,17 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_
|
||||
if (init_file && VCWD_STAT(init_file, &sb) != -1) {
|
||||
FILE *fp = fopen(init_file, "r");
|
||||
if (fp) {
|
||||
int line = 1;
|
||||
|
||||
char cmd[PHPDBG_MAX_CMD];
|
||||
size_t cmd_len = 0L;
|
||||
char *code = NULL;
|
||||
size_t code_len = 0L;
|
||||
zend_bool in_code = 0;
|
||||
struct phpdbg_init_state state = {0};
|
||||
|
||||
state.init_file = init_file;
|
||||
|
||||
while (fgets(cmd, PHPDBG_MAX_CMD, fp) != NULL) {
|
||||
cmd_len = strlen(cmd)-1;
|
||||
|
||||
while (cmd_len > 0L && isspace(cmd[cmd_len-1]))
|
||||
cmd_len--;
|
||||
|
||||
cmd[cmd_len] = '\0';
|
||||
|
||||
if (*cmd && cmd_len > 0L && cmd[0] != '#') {
|
||||
if (cmd_len == 2) {
|
||||
if (memcmp(cmd, "<:", sizeof("<:")-1) == SUCCESS) {
|
||||
in_code = 1;
|
||||
goto next_line;
|
||||
} else {
|
||||
if (memcmp(cmd, ":>", sizeof(":>")-1) == SUCCESS) {
|
||||
in_code = 0;
|
||||
code[code_len] = '\0';
|
||||
{
|
||||
zend_eval_stringl(code, code_len, NULL, "phpdbginit code" TSRMLS_CC);
|
||||
}
|
||||
free(code);
|
||||
code = NULL;
|
||||
goto next_line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (in_code) {
|
||||
if (code == NULL) {
|
||||
code = malloc(cmd_len + 1);
|
||||
} else code = realloc(code, code_len + cmd_len + 1);
|
||||
|
||||
if (code) {
|
||||
memcpy(
|
||||
&code[code_len], cmd, cmd_len);
|
||||
code_len += cmd_len;
|
||||
}
|
||||
goto next_line;
|
||||
}
|
||||
|
||||
zend_try {
|
||||
char *input = phpdbg_read_input(cmd TSRMLS_CC);
|
||||
phpdbg_param_t stack;
|
||||
|
||||
phpdbg_init_param(&stack, STACK_PARAM);
|
||||
|
||||
phpdbg_activate_err_buf(1 TSRMLS_CC);
|
||||
|
||||
if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) {
|
||||
switch (phpdbg_stack_execute(&stack, 1 /* allow_async_unsafe == 1 */ TSRMLS_CC)) {
|
||||
case FAILURE:
|
||||
phpdbg_activate_err_buf(0 TSRMLS_CC);
|
||||
if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) {
|
||||
phpdbg_output_err_buf("initfailure", "%b file=\"%s\" line=\"%d\" input=\"%s\"", "Unrecognized command in %s:%d: %s, %b!" TSRMLS_CC, init_file, line, input);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
phpdbg_activate_err_buf(0 TSRMLS_CC);
|
||||
phpdbg_free_err_buf(TSRMLS_C);
|
||||
|
||||
phpdbg_stack_free(&stack);
|
||||
phpdbg_destroy_input(&input TSRMLS_CC);
|
||||
} zend_catch {
|
||||
PHPDBG_G(flags) &= ~(PHPDBG_IS_RUNNING | PHPDBG_IS_CLEANING);
|
||||
if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) {
|
||||
zend_bailout();
|
||||
}
|
||||
} zend_end_try();
|
||||
}
|
||||
next_line:
|
||||
line++;
|
||||
phpdbg_line_init(cmd, &state TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (code) {
|
||||
free(code);
|
||||
if (state.code) {
|
||||
free(state.code);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#define PHPDBG_PROMPT_H
|
||||
|
||||
/* {{{ */
|
||||
void phpdbg_string_init(char *buffer TSRMLS_DC);
|
||||
void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TSRMLS_DC);
|
||||
void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC);
|
||||
int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC);
|
||||
|
Loading…
Reference in New Issue
Block a user