Modified: xdebug/trunk/config.m4 =================================================================== --- xdebug/trunk/config.m4 2009-12-28 01:02:06 UTC (rev 3164) +++ xdebug/trunk/config.m4 2009-12-28 01:04:10 UTC (rev 3165) @@ -27,7 +27,7 @@ CPPFLAGS=$old_CPPFLAGS - PHP_NEW_EXTENSION(xdebug, xdebug.c xdebug_code_coverage.c xdebug_com.c xdebug_compat.c xdebug_handler_dbgp.c xdebug_handler_gdb.c xdebug_handler_php3.c xdebug_handlers.c xdebug_llist.c xdebug_hash.c xdebug_private.c xdebug_profiler.c xdebug_set.c xdebug_str.c xdebug_superglobals.c xdebug_var.c xdebug_xml.c usefulstuff.c, $ext_shared,,,,yes) + PHP_NEW_EXTENSION(xdebug, xdebug.c xdebug_code_coverage.c xdebug_com.c xdebug_compat.c xdebug_handler_dbgp.c xdebug_handlers.c xdebug_llist.c xdebug_hash.c xdebug_private.c xdebug_profiler.c xdebug_set.c xdebug_str.c xdebug_superglobals.c xdebug_var.c xdebug_xml.c usefulstuff.c, $ext_shared,,,,yes) PHP_SUBST(XDEBUG_SHARED_LIBADD) PHP_ADD_MAKEFILE_FRAGMENT fi Modified: xdebug/trunk/config.w32 =================================================================== --- xdebug/trunk/config.w32 2009-12-28 01:02:06 UTC (rev 3164) +++ xdebug/trunk/config.w32 2009-12-28 01:04:10 UTC (rev 3165) @@ -4,7 +4,7 @@ ARG_WITH("xdebug", "Xdebug support", "no"); if (PHP_XDEBUG == "yes") { - EXTENSION("xdebug", "xdebug.c xdebug_code_coverage.c xdebug_com.c xdebug_compat.c xdebug_handler_dbgp.c xdebug_handler_gdb.c xdebug_handler_php3.c xdebug_handlers.c xdebug_llist.c xdebug_hash.c xdebug_private.c xdebug_profiler.c xdebug_set.c xdebug_str.c xdebug_superglobals.c xdebug_var.c xdebug_xml.c usefulstuff.c"); + EXTENSION("xdebug", "xdebug.c xdebug_code_coverage.c xdebug_com.c xdebug_compat.c xdebug_handler_dbgp.c xdebug_handlers.c xdebug_llist.c xdebug_hash.c xdebug_private.c xdebug_profiler.c xdebug_set.c xdebug_str.c xdebug_superglobals.c xdebug_var.c xdebug_xml.c usefulstuff.c"); AC_DEFINE("HAVE_XDEBUG", 1, "Xdebug support"); AC_DEFINE("HAVE_EXECUTE_DATA_PTR", 1); } Modified: xdebug/trunk/package.xml =================================================================== --- xdebug/trunk/package.xml 2009-12-28 01:02:06 UTC (rev 3164) +++ xdebug/trunk/package.xml 2009-12-28 01:04:10 UTC (rev 3165) @@ -82,10 +82,6 @@ - - - - Modified: xdebug/trunk/package2.xml =================================================================== --- xdebug/trunk/package2.xml 2009-12-28 01:02:06 UTC (rev 3164) +++ xdebug/trunk/package2.xml 2009-12-28 01:04:10 UTC (rev 3165) @@ -129,10 +129,6 @@ - - - - Deleted: xdebug/trunk/xdebug_handler_gdb.c =================================================================== --- xdebug/trunk/xdebug_handler_gdb.c 2009-12-28 01:02:06 UTC (rev 3164) +++ xdebug/trunk/xdebug_handler_gdb.c 2009-12-28 01:04:10 UTC (rev 3165) @@ -1,1495 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Xdebug | - +----------------------------------------------------------------------+ - | Copyright (c) 2002-2009 Derick Rethans | - +----------------------------------------------------------------------+ - | This source file is subject to version 1.0 of the Xdebug license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at | - | http://xdebug.derickrethans.nl/license.php | - | If you did not receive a copy of the Xdebug license and are unable | - | to obtain it through the world-wide-web, please send a note to | - | xdebug@derickrethans.nl so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Derick Rethans | - +----------------------------------------------------------------------+ - */ - -#include "php.h" -#include "ext/standard/php_string.h" -#include "ext/standard/url.h" -#include "TSRM.h" -#include "php_globals.h" -#include "php_xdebug.h" -#include "xdebug_private.h" -#include "xdebug_com.h" -#include "xdebug_llist.h" -#include "xdebug_handler_gdb.h" -#include "xdebug_var.h" - -#ifdef PHP_WIN32 -#include "win32/time.h" -#include -#endif -#include - -ZEND_EXTERN_MODULE_GLOBALS(xdebug) -/***************************************************************************** -** Prototypes for debug command handlers -*/ - -static char *xdebug_handle_backtrace(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_breakpoint(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_cont(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_eval(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_delete(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_finish(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_kill(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_list(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_next(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_option(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_print(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_pwd(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_quit(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_run(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_show(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_show_breakpoints(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_show_local(xdebug_con *context, xdebug_arg *args); -static char *xdebug_handle_step(xdebug_con *context, xdebug_arg *args); - -/***************************************************************************** -** Dispatcher tables for supported debug commands -*/ - -static xdebug_gdb_cmd commands_init[] = { - { "option", 2, "option [setting] [value]", xdebug_handle_option, 1, "Set a debug session option" }, - { "run", 0, "run", xdebug_handle_run, 1, "Start the script" }, - { NULL, 0, NULL, NULL, 0, NULL } -}; - -static xdebug_gdb_cmd commands_breakpoint[] = { - { "break", 1, "bre(ak) [functionname|filename:linenumber]", xdebug_handle_breakpoint, 1, - "Set breakpoint at specified line or function.\n" - " Argument may be filename and linenumber, function name or '{main}'\n" - " for the first PHP line." - }, - { "bre", 1, "bre(ak) [functionname|filename:linenumber]", xdebug_handle_breakpoint, 0, - "Set breakpoint at specified line or function.\n" - " Argument may be filename and linenumber, function name or '{main}'\n" - " for the first PHP line." - }, - { "delete", 1, "del(ete) [functionname|filename:linenumber]", xdebug_handle_delete, 1, - "Removed breakpoint at specified line or function.\n" - " Argument may be filename and linenumber, function name or '{main}'\n" - " for the first PHP line." - }, - { "del", 1, "del(ete) [functionname|filename:linenumber]", xdebug_handle_delete, 0, - "Removed breakpoint at specified line or function.\n" - " Argument may be filename and linenumber, function name or '{main}'\n" - " for the first PHP line." - }, - { "show-breakpoints", 0, "show-breakpoints", xdebug_handle_show_breakpoints, 1, - "Shows a list of all breakpoints and optional conditions." - }, - { NULL, 0, NULL, NULL, 0, NULL } -}; - -static xdebug_gdb_cmd commands_data[] = { - { "eval", 1, "eval [php code to execute]", xdebug_handle_eval, 1, - "Evaluation PHP code" - }, - { "show", 0, "show", xdebug_handle_show, 1, - "Show a list of all variables" - }, - { "show-local", 0, "show-local", xdebug_handle_show_local, 1, - "Show a list of all variables including their contents" - }, - { "print", 1, "print", xdebug_handle_print, 1, - "Prints the contents of the variable" - }, - { NULL, 0, NULL, NULL, 0, NULL } -}; - -static xdebug_gdb_cmd commands_run[] = { - { "kill", 0, "kill", xdebug_handle_kill, 1, "Kill the script" }, - { "quit", 0, "quit", xdebug_handle_quit, 1, "Close the debug session" }, - { NULL, 0, NULL, NULL, 0, NULL } -}; - -static xdebug_gdb_cmd commands_runtime[] = { - { "backtrace", 0, "backtrace [full]", xdebug_handle_backtrace, 0, - "Print backtrace of all stack frames.\n" - " Use of the 'full' qualifier also prints the values of the local\n" - " variables." - }, - { "bt", 0, "bt [full]", xdebug_handle_backtrace, 1, - "Print backtrace of all stack frames.\n" - " Use of the 'full' qualifier also prints the values of the local\n" - " variables." - }, - - { "cont", 0, "cont(inue)", xdebug_handle_cont, 0, - "Continue script being debugged, after error or breakpoint." - }, - { "continue", 0, "cont(inue)", xdebug_handle_cont, 1, - "Continue script being debugged, after error or breakpoint." - }, - - { "finish", 0, "finish", xdebug_handle_finish, 1, - "Continues executing until the current function returned to the\n" - " calling function." - }, - - { "list", 0, "list [[file:]beginline] [endline]", xdebug_handle_list, 1, - "Lists specified line. With no arguments, lists ten more lines\n" - " after or before the previous listing. One argument specifies the\n" - " the line in a file to start, and then lines are listed around that\n" - " line. Two arguments specify starting and ending lines to list." - }, - - { "next", 0, "next", xdebug_handle_next, 1, - "Continues executing until the next statement in the same stack\n" - " frame. Is basically the same as 'step' but does not go into\n" - " function calls if they occur." - }, - - { "pwd", 0, "pwd", xdebug_handle_pwd, 1, - "Prints the current working directory." - }, - - { "step", 0, "step", xdebug_handle_step, 1, - "Continues executing until the next statement." - }, - - { NULL, 0, NULL, NULL, 0, NULL } -}; - -/***************************************************************************** -** Utility functions -*/ - -static xdebug_gdb_cmd* scan_cmd(xdebug_gdb_cmd *ptr, char *line) -{ - while (ptr->name) { - if (strcmp(ptr->name, line) == 0) { - return ptr; - } - ptr++; - } - return NULL; -} - - -static char *make_message(xdebug_con *context, int error_code, char *message) -{ - xdebug_gdb_options *options = (xdebug_gdb_options*) context->options; - char *tmp; - char *ret; - char *type; - int len; - - if ((error_code & XDEBUG_E) == XDEBUG_E) { - type = "error"; - } else { - type = "data"; - } - - switch (options->response_format) { - case XDEBUG_RESPONSE_XML: - /* we ignore binary safety here */ - tmp = xdebug_xmlize(message, strlen(message), &len); - ret = xdebug_sprintf("<%s>%d%s", type, error_code, tmp, type); - efree(tmp); - return ret; - break; - - case XDEBUG_RESPONSE_NORMAL: - default: - return xdebug_sprintf("%d %s", error_code, message); - break; - } -} - -static void send_message(xdebug_con *context, int error_code, char *message) -{ - char *tmp; - - tmp = make_message(context, error_code, message); - SENDMSG(context->socket, xdebug_sprintf("%s\n", tmp)); - xdfree(tmp); -} - - -/***************************************************************************** -** Helpers for looking up commands -*/ - -static inline xdebug_gdb_cmd* lookup_cmd_in_group(char *line, xdebug_gdb_cmd *group, int flag, int test_flag) -{ - xdebug_gdb_cmd *ptr; - - if (flag & test_flag) { - ptr = scan_cmd(group, line); - if (ptr) { - return (ptr); - } - } - return NULL; -} - -static xdebug_gdb_cmd* lookup_cmd(char *line, int flag) -{ - xdebug_gdb_cmd *ptr; - - if ((ptr = lookup_cmd_in_group(line, commands_init, flag, XDEBUG_INIT)) != NULL) return ptr; - if ((ptr = lookup_cmd_in_group(line, commands_breakpoint, flag, XDEBUG_BREAKPOINT)) != NULL) return ptr; - if ((ptr = lookup_cmd_in_group(line, commands_run, flag, XDEBUG_RUN)) != NULL) return ptr; - if ((ptr = lookup_cmd_in_group(line, commands_runtime, flag, XDEBUG_RUNTIME)) != NULL) return ptr; - if ((ptr = lookup_cmd_in_group(line, commands_data, flag, XDEBUG_DATA)) != NULL) return ptr; -#if 0 - if ((ptr = lookup_cmd_in_group(line, commands_status, flag, XDEBUG_STATUS)) != NULL) return ptr; -#endif - return NULL; -} - -/***************************************************************************** -** Helpers for the "help" command -*/ - -static inline void show_available_commands_in_group(xdebug_con *h, int fmt, int flag, int test_flag, xdebug_gdb_cmd *ptr) -{ - char *tmp; - int len; - - if (flag & test_flag ) { - while (ptr->name) { - if (ptr->show && ptr->help) { - switch (fmt) { - case XDEBUG_RESPONSE_XML: - /* we ignore binary safety here */ - tmp = xdebug_xmlize(ptr->help, strlen(ptr->help), &len); - SENDMSG(h->socket, xdebug_sprintf("%s%s", ptr->name, tmp)); - efree(tmp); - break; - default: - SENDMSG(h->socket, xdebug_sprintf("%-12s %s\n", ptr->name, ptr->help)); - break; - } - } - ptr++; - } - } -} - -static void show_available_commands(xdebug_con *h, int flag) -{ - xdebug_gdb_options* o = (xdebug_gdb_options*) h->options; - - if (o->response_format == XDEBUG_RESPONSE_XML) { - SENDMSG(h->socket, xdebug_sprintf("")); - } - show_available_commands_in_group(h, o->response_format, flag, XDEBUG_INIT, commands_init); - show_available_commands_in_group(h, o->response_format, flag, XDEBUG_BREAKPOINT, commands_breakpoint); - show_available_commands_in_group(h, o->response_format, flag, XDEBUG_RUN, commands_run); - show_available_commands_in_group(h, o->response_format, flag, XDEBUG_RUNTIME, commands_runtime); - show_available_commands_in_group(h, o->response_format, flag, XDEBUG_DATA, commands_data); -#if 0 - show_available_commands_in_group(h, o->response_format, flag, XDEBUG_STATUS, commands_status); -#endif - if (o->response_format == XDEBUG_RESPONSE_XML) { - SENDMSG(h->socket, xdebug_sprintf("\n")); - } -} - -static void show_command_info(xdebug_con *h, xdebug_gdb_cmd* cmd) -{ - xdebug_gdb_options *o = (xdebug_gdb_options*) h->options; - char *t1, *t2; - int len; - - if (cmd) { - if (o->response_format == XDEBUG_RESPONSE_XML) { - /* we ignore binary safety here */ - t1 = xdebug_xmlize(cmd->description, strlen(cmd->description), &len); - t2 = xdebug_xmlize(cmd->help, strlen(cmd->help), &len); - SENDMSG(h->socket, xdebug_sprintf("%s%s\n", t1, t2)); - efree(t1); - efree(t2); - } else { - SENDMSG(h->socket, xdebug_sprintf("Syntax: %s\n%12s %s\n", cmd->description, " ", cmd->help)); - } - } else { - send_message(h, XDEBUG_E_NO_INFO, "No information available for this command."); - } -} - -/***************************************************************************** -** Data printing functions -*/ -static char *return_printable_symbol(xdebug_con *context, char *name, zval *val) -{ - xdebug_gdb_options* options = (xdebug_gdb_options*) context->options; - char *str_rep, *ret; - TSRMLS_FETCH(); - - switch (options->response_format) { - case XDEBUG_RESPONSE_NORMAL: - if (val) { - str_rep = xdebug_get_zval_value(val, 0, xdebug_var_get_nolimit_options(TSRMLS_C)); - } else { - str_rep = xdstrdup("*uninitialized*"); - } - if (name) { - ret = xdebug_sprintf("$%s = %s\n", name, str_rep); - } else { - ret = xdebug_sprintf("%s\n", str_rep); - } - xdfree(str_rep); - return ret; - break; - - case XDEBUG_RESPONSE_XML: - default: - return xdebug_get_zval_value_xml(name, val); - } -} - -static void dump_used_var(void *context, xdebug_hash_element* he) -{ - char *name = (char*) he->ptr; - xdebug_con *h = (xdebug_con*) context; - xdebug_gdb_options *options = (xdebug_gdb_options*) h->options; - - if (!options->dump_superglobals) { - if ((strcmp(name, "GLOBALS") == 0) || - (strcmp(name, "_GET") == 0) || - (strcmp(name, "_POST") == 0) || - (strcmp(name, "_COOKIE") == 0) || - (strcmp(name, "_REQUEST") == 0) || - (strcmp(name, "_SERVER") == 0) || - (strcmp(name, "_ENV") == 0) || - (strcmp(name, "_SESSION") == 0)) - { - return; - } - } - if (options->response_format == XDEBUG_RESPONSE_XML) { - SENDMSG(h->socket, xdebug_sprintf("", name)); - } else { - SENDMSG(h->socket, xdebug_sprintf("$%s\n", name)); - } -} - - -static void dump_used_var_with_contents(void *context, xdebug_hash_element* he) -{ - char *name = (char*) he->ptr; - xdebug_con *h = (xdebug_con*) context; - xdebug_gdb_options *options = (xdebug_gdb_options*) h->options; - char *contents; - zval *zval_var; - - if (!options->dump_superglobals) { - if ((strcmp(name, "GLOBALS") == 0) || - (strcmp(name, "_GET") == 0) || - (strcmp(name, "_POST") == 0) || - (strcmp(name, "_COOKIE") == 0) || - (strcmp(name, "_REQUEST") == 0) || - (strcmp(name, "_SERVER") == 0) || - (strcmp(name, "_ENV") == 0) || - (strcmp(name, "_SESSION") == 0)) - { - return; - } - } - zval_var = xdebug_get_php_symbol(name, strlen(name) + 1); - contents = return_printable_symbol(context, name, zval_var); - if (contents) { - if (options->response_format == XDEBUG_RESPONSE_XML) { - SENDMSG(h->socket, contents); - } else { - SENDMSG(h->socket, xdebug_sprintf("%s", contents)); - xdfree(contents); - } - } else { - if (options->response_format == XDEBUG_RESPONSE_XML) { - SENDMSG(h->socket, xdebug_sprintf("", name)); - } else { - SENDMSG(h->socket, xdebug_sprintf("$%s = *uninitialized*\n", name)); - } - } -} - -static void print_sourceline(xdebug_con *h, const char *file, int begin, int end, int offset, int response_format TSRMLS_DC) -{ - int fd; - fd_buf fd_buffer = { NULL, 0 }; - int i = begin; - char *line = NULL; - int update = 0, len; - char *tmp; - - if (i < 0) { - begin = 0; - i = 0; - } - - /* Read until the "begin" line has been read */ - if ((fd = open(file, 0)) == -1) { - SENDMSG(h->socket, xdebug_sprintf("The file '%s' could not be opened.\n", file)); - return; - } - - while (i > 0) { - if (line) { - free(line); - line = NULL; - } - line = xdebug_fd_read_line(fd, &fd_buffer, FD_RL_FILE); - i--; - } - /* Read until the "end" line has been read */ - do { - if (line) { - update = 1; - if (response_format == XDEBUG_RESPONSE_XML) { - /* we ignore binary safety here */ - tmp = xdebug_xmlize(line, strlen(line), &len); - SENDMSG(h->socket, xdebug_sprintf("%s", file, begin + i, tmp)); - efree(tmp); - } else { - SENDMSG(h->socket, xdebug_sprintf("%d\t%s\n", begin + i, line)); - } - free(line); - line = NULL; - } - line = xdebug_fd_read_line(fd, &fd_buffer, FD_RL_FILE); - i++; - } while (i < end + 1 - begin); - - /* Print last line */ - if (line) { - update = 1; - free(line); - line = NULL; - } - - /* Update "last" info */ - if (update) { - if (XG(context).list.last_file && XG(context).list.last_file != file) { - xdfree(XG(context).list.last_file); - } - if (XG(context).list.last_file != file) { - XG(context).list.last_file = xdstrdup(file); - } - XG(context).list.last_line = end + 1 + offset; - } - close(fd); -} - -static void print_breakpoint(xdebug_con *h, function_stack_entry *i, int response_format) -{ - int c = 0; /* Comma flag */ - int j = 0; /* Counter */ - char *tmp_fname; - char *tmp; - char *tmp_value; - int xml = (response_format == XDEBUG_RESPONSE_XML); - int len; - TSRMLS_FETCH(); -/* -* Breakpoint 2, xdebug_execute (op_array=0x82caf50) -* at /dat/dev/php/xdebug/xdebug.c:361 -*/ - tmp_fname = xdebug_show_fname(i->function, 0, 0 TSRMLS_CC); - if (xml) { - SENDMSG(h->socket, xdebug_sprintf("%s", tmp_fname)); - } else { - SENDMSG(h->socket, xdebug_sprintf("Breakpoint, %s(", tmp_fname)); - } - xdfree(tmp_fname); - - /* Printing vars */ - for (j = 0; j < i->varc; j++) { - if (c) { - SSEND(h->socket, ", "); - } else { - c = 1; - } - - if (i->var[j].name) { - SENDMSG(h->socket, xdebug_sprintf("$%s = ", i->var[j].name)); - } - tmp_value = xdebug_get_zval_value(i->var[j].addr, 0, xdebug_var_get_nolimit_options(TSRMLS_C)); - /* we ignore binary safety here */ - tmp = xdebug_xmlize(tmp_value, strlen(tmp_value), &len); - SSENDL(h->socket, tmp, len); - xdfree(tmp_value); - efree(tmp); - } - - if (xml) { - SENDMSG(h->socket, xdebug_sprintf("%s%d", i->filename, i->lineno)); - } else { - SENDMSG(h->socket, xdebug_sprintf(")\n\tat %s:%d\n", i->filename, i->lineno)); - } -} - -static void print_stackframe(xdebug_con *h, int nr, function_stack_entry *i, int response_format, int flags) -{ - int c = 0; /* Comma flag */ - int j = 0; /* Counter */ - char *tmp_fname; - char *tmp; - char *tmp_value; - int len; - xdebug_hash *tmp_hash; - TSRMLS_FETCH(); - -/* -* 0x4001af2e in xdebug_compile_file (file_handle=0xbffff960, type=2) -* at /dat/dev/php/xdebug/xdebug.c:901 -* -*/ - tmp_fname = xdebug_show_fname(i->function, 0, 0 TSRMLS_CC); - if (response_format == XDEBUG_RESPONSE_XML) { - if (nr) { - SENDMSG(h->socket, xdebug_sprintf("%d%s", nr, tmp_fname)); - } else { - SENDMSG(h->socket, xdebug_sprintf("%s", tmp_fname)); - } - } else { - if (nr) { - SENDMSG(h->socket, xdebug_sprintf("#%-2d %s (", nr, tmp_fname)); - } else { - SENDMSG(h->socket, xdebug_sprintf("%s (", tmp_fname)); - } - } - xdfree(tmp_fname); - - /* Printing vars */ - for (j = 0; j < i->varc; j++) { - if (c) { - SSEND(h->socket, ", "); - } else { - c = 1; - } - - if (i->var[j].name) { - SENDMSG(h->socket, xdebug_sprintf("$%s = ", i->var[j].name)); - } - tmp_value = xdebug_get_zval_value(i->var[j].addr, 0, xdebug_var_get_nolimit_options(TSRMLS_C)); - /* we ignore binary safety here */ - tmp = xdebug_xmlize(tmp_value, strlen(tmp_value), &len); - SSENDL(h->socket, tmp, len); - xdfree(tmp_value); - efree(tmp); - } - - XG(active_symbol_table) = i->symbol_table; - if (response_format == XDEBUG_RESPONSE_XML) { - SENDMSG(h->socket, xdebug_sprintf("%s%d", i->filename, i->lineno)); - if (flags & XDEBUG_FRAME_FULL && i->used_vars) { - SSEND(h->socket, ""); - tmp_hash = xdebug_used_var_hash_from_llist(i->used_vars); - xdebug_hash_apply(tmp_hash, (void *) h, dump_used_var_with_contents); - xdebug_hash_destroy(tmp_hash); - SSEND(h->socket, ""); - } - SSEND(h->socket, ""); - } else { - SENDMSG(h->socket, xdebug_sprintf(")\n at %s:%d\n", i->filename, i->lineno)); - if (flags & XDEBUG_FRAME_FULL && i->used_vars) { - tmp_hash = xdebug_used_var_hash_from_llist(i->used_vars); - xdebug_hash_apply(tmp_hash, (void *) h, dump_used_var_with_contents); - xdebug_hash_destroy(tmp_hash); - SSEND(h->socket, "\n"); - } - } - XG(active_symbol_table) = NULL; -} - -/***************************************************************************** -** Client command handlers -*/ - -char *xdebug_handle_backtrace(xdebug_con *context, xdebug_arg *args) -{ - xdebug_llist_element *le; - int counter = 1; - int full = XDEBUG_FRAME_NORMAL; - xdebug_gdb_options *options = (xdebug_gdb_options*) context->options; - int xml = (options->response_format == XDEBUG_RESPONSE_XML); - TSRMLS_FETCH(); - - if (args->c == 1 && strcmp(args->args[0], "full") == 0) { - full = XDEBUG_FRAME_FULL; - } - - SSEND(context->socket, xml ? "" : ""); - for (le = XDEBUG_LLIST_TAIL(XG(stack)); le != NULL; le = XDEBUG_LLIST_PREV(le)) { - print_stackframe(context, counter++, XDEBUG_LLIST_VALP(le), options->response_format, full); - } - SSEND(context->socket, xml ? "\n" : "\n"); - - return NULL; -} - -char *xdebug_handle_breakpoint(xdebug_con *context, xdebug_arg *args) -{ - xdebug_arg *method = (xdebug_arg*) xdmalloc(sizeof(xdebug_arg)); - char *tmp_name; - xdebug_brk_info *extra_brk_info; - xdebug_str eval = {0, 0, NULL}; - int i = 0; - - xdebug_arg_init(method); - - extra_brk_info = xdmalloc(sizeof(xdebug_brk_info)); - extra_brk_info->type = NULL; - extra_brk_info->file = NULL; - extra_brk_info->condition = NULL; - extra_brk_info->classname = NULL; - extra_brk_info->functionname = NULL; - extra_brk_info->disabled = 0; - extra_brk_info->temporary = 0; - extra_brk_info->hit_count = 0; - extra_brk_info->hit_value = 0; - extra_brk_info->hit_condition = XDEBUG_HIT_DISABLED; - extra_brk_info->function_break_type = XDEBUG_BRK_FUNC_CALL; - - if (strstr(args->args[0], "::")) { /* class::method */ - xdebug_explode("::", args->args[0], method, -1); - extra_brk_info->classname = xdstrdup(method->args[0]); - extra_brk_info->functionname = xdstrdup(method->args[1]); - - if (method->c != 2) { - xdebug_arg_dtor(method); - xdebug_brk_info_dtor(extra_brk_info); - return make_message(context, XDEBUG_E_INVALID_FORMAT, "Invalid format for class/method combination."); - } else { - if (!xdebug_hash_add(context->class_breakpoints, args->args[0], strlen(args->args[0]), (void*) extra_brk_info)) { - xdebug_arg_dtor(method); - xdebug_brk_info_dtor(extra_brk_info); - return make_message(context, XDEBUG_E_BREAKPOINT_NOT_SET, "Breakpoint could not be set."); - } else { - send_message(context, XDEBUG_D_BREAKPOINT_SET, "Breakpoint set on class/method combination."); - xdebug_arg_dtor(method); - } - } - } else if (strstr(args->args[0], "->")) { /* class->method */ - xdebug_explode("->", args->args[0], method, -1); - extra_brk_info->classname = xdstrdup(method->args[0]); - extra_brk_info->functionname = xdstrdup(method->args[1]); - - if (method->c != 2) { - xdebug_arg_dtor(method); - xdebug_brk_info_dtor(extra_brk_info); - return make_message(context, XDEBUG_E_INVALID_FORMAT, "Invalid format for class/method combination."); - } else { - if (!xdebug_hash_add(context->class_breakpoints, args->args[0], strlen(args->args[0]), (void*) extra_brk_info)) { - xdebug_arg_dtor(method); - xdebug_brk_info_dtor(extra_brk_info); - return make_message(context, XDEBUG_E_BREAKPOINT_NOT_SET, "Breakpoint could not be set."); - } else { - send_message(context, XDEBUG_D_BREAKPOINT_SET, "Breakpoint set on class/method combination."); - xdebug_arg_dtor(method); - } - } - } else if (strstr(args->args[0], ":")) { /* file:line */ - xdebug_explode(":", args->args[0], method, -1); /* 0 = filename, 1 = linenumer */ - if (method->c != 2) { - xdebug_arg_dtor(method); - return make_message(context, XDEBUG_E_INVALID_FORMAT, "Invalid format for file:line combination."); - } else { - /* Make search key */ - if (method->args[0][0] != '/') { -#if WIN32|WINNT - if (strlen(method->args[0]) > 3 - && method->args[0][1] != '|') - { - tmp_name = xdebug_sprintf("/%s", method->args[0]); - } else { - tmp_name = xdebug_sprintf("%s", method->args[0]); - } -#else - tmp_name = xdebug_sprintf("/%s", method->args[0]); -#endif - } else { - tmp_name = xdebug_sprintf("%s", method->args[0]); - } - - /* Set line number in extra structure */ - extra_brk_info->lineno = atoi(method->args[1]); - extra_brk_info->file = tmp_name; - extra_brk_info->file_len = strlen(tmp_name); - - /* If there are more second parameters to the "break" command, then we - * concat them and use it as a conditional statement */ - if (args->c > 1) { - xdebug_str_add(&eval, args->args[1], 0); - - for (i = 2; i < args->c; i++) { - xdebug_str_add(&eval, " ", 0); - xdebug_str_add(&eval, args->args[i], 0); - } - extra_brk_info->condition = xdstrdup(eval.d); - xdebug_str_free(&eval); - } - - /* Add breakpoint to the list */ - xdebug_llist_insert_next(context->line_breakpoints, XDEBUG_LLIST_TAIL(context->line_breakpoints), (void*) extra_brk_info); - send_message(context, XDEBUG_D_BREAKPOINT_SET, "Breakpoint set on file:line combination."); - xdebug_arg_dtor(method); - } - } else { /* function */ - extra_brk_info->functionname = xdstrdup(args->args[0]); - - if (!xdebug_hash_add(context->function_breakpoints, args->args[0], strlen(args->args[0]), (void*) extra_brk_info)) { - xdebug_arg_dtor(method); - xdebug_brk_info_dtor(extra_brk_info); - return make_message(context, XDEBUG_E_BREAKPOINT_NOT_SET, "Breakpoint could not be set."); - } else { - send_message(context, XDEBUG_D_BREAKPOINT_SET, "Breakpoint set on function."); - xdebug_arg_dtor(method); - } - } - return NULL; -} - -char *xdebug_handle_cont(xdebug_con *context, xdebug_arg *args) -{ - SSEND(context->socket, "Continuing.\n"); - return NULL; -} - -char *xdebug_handle_delete(xdebug_con *context, xdebug_arg *args) -{ - xdebug_arg *method = (xdebug_arg*) xdmalloc(sizeof(xdebug_arg)); - char *tmp_name; - xdebug_llist_element *le; - xdebug_brk_info *brk; - TSRMLS_FETCH(); - - xdebug_arg_init(method); - - if (strstr(args->args[0], "::")) { /* class::method */ - xdebug_explode("::", args->args[0], method, -1); - if (method->c != 2) { - xdebug_arg_dtor(method); - return make_message(context, XDEBUG_E_INVALID_FORMAT, "Invalid format for class/method combination."); - } else { - if (!xdebug_hash_delete(context->class_breakpoints, args->args[0], strlen(args->args[0]))) { - xdebug_arg_dtor(method); - return make_message(context, XDEBUG_E_BREAKPOINT_NOT_REMOVED, "Breakpoint could not be removed."); - } else { - send_message(context, XDEBUG_D_BREAKPOINT_REMOVED, "Breakpoint removed."); - xdebug_arg_dtor(method); - } - } - } else if (strstr(args->args[0], "->")) { /* class->method */ - xdebug_explode("->", args->args[0], method, -1); - if (method->c != 2) { - xdebug_arg_dtor(method); - return make_message(context, XDEBUG_E_INVALID_FORMAT, "Invalid format for class/method combination."); - } else { - if (!xdebug_hash_delete(context->class_breakpoints, args->args[0], strlen(args->args[0]))) { - xdebug_arg_dtor(method); - return make_message(context, XDEBUG_E_BREAKPOINT_NOT_REMOVED, "Breakpoint could not be removed."); - } else { - send_message(context, XDEBUG_D_BREAKPOINT_REMOVED, "Breakpoint removed."); - xdebug_arg_dtor(method); - } - } - } else if (strstr(args->args[0], ":")) { /* file:line */ - xdebug_explode(":", args->args[0], method, -1); /* 0 = filename, 1 = linenumer */ - if (method->c != 2) { - xdebug_arg_dtor(method); - return make_message(context, XDEBUG_E_INVALID_FORMAT, "Invalid format for file:line combination."); - } else { - /* Make search key */ - if (method->args[0][0] != '/') { -#if WIN32|WINNT - if (strlen(method->args[0]) > 3 - && method->args[0][1] != '|') - { - tmp_name = xdebug_sprintf("/%s", method->args[0]); - } else { - tmp_name = xdebug_sprintf("%s", method->args[0]); - } -#else - tmp_name = xdebug_sprintf("/%s", method->args[0]); -#endif - } else { - tmp_name = xdebug_sprintf("%s", method->args[0]); - } - - /* Add breakpoint to the list */ - for (le = XDEBUG_LLIST_HEAD(XG(context).line_breakpoints); le != NULL; le = XDEBUG_LLIST_NEXT(le)) { - brk = XDEBUG_LLIST_VALP(le); - - if (atoi(method->args[1]) == brk->lineno && strcmp(tmp_name, brk->file) == 0) { - xdebug_llist_remove(context->line_breakpoints, le, NULL); - send_message(context, XDEBUG_D_BREAKPOINT_REMOVED, "Breakpoint removed."); - xdebug_arg_dtor(method); - xdfree(tmp_name); - return NULL; - } - } - xdfree(tmp_name); - xdebug_arg_dtor(method); - } - } else { /* function */ - if (!xdebug_hash_delete(context->function_breakpoints, args->args[0], strlen(args->args[0]))) { - xdebug_arg_dtor(method); - return make_message(context, XDEBUG_E_BREAKPOINT_NOT_REMOVED, "Breakpoint could not be removed."); - } else { - send_message(context, XDEBUG_D_BREAKPOINT_REMOVED, "Breakpoint removed."); - xdebug_arg_dtor(method); - } - } - return NULL; -} - -char *xdebug_handle_eval(xdebug_con *context, xdebug_arg *args) -{ - int i; - xdebug_str buffer = {0, 0, NULL}; - zval retval; - char *ret_value; - int old_error_reporting; - int eval_status; - - TSRMLS_FETCH(); - - /* Remember error reporting level and debug session state */ - old_error_reporting = EG(error_reporting); - EG(error_reporting) = 0; - XG(breakpoints_allowed) = 0; - XG(remote_enabled) = 0; - XG(remote_enable) = 0; - - /* Concat all arguments back together */ - xdebug_str_add(&buffer, args->args[0], 0); - - for (i = 1; i < args->c; i++) { - xdebug_str_add(&buffer, " ", 0); - xdebug_str_add(&buffer, args->args[i], 0); - } - - /* Run eval statement */ - eval_status = zend_eval_string(buffer.d, &retval, "xdebug eval" TSRMLS_CC); - xdebug_str_free(&buffer); - - /* Restore error reporting level and debug session state */ - EG(error_reporting) = old_error_reporting; - XG(breakpoints_allowed) = 1; - XG(remote_enabled) = 1; - XG(remote_enable) = 1; - - /* Return error message */ - if (eval_status == FAILURE) { - return make_message(context, XDEBUG_E_EVAL, "Error evaluating code"); - } - - /* Return data */ - ret_value = return_printable_symbol(context, NULL, &retval); - SENDMSG(context->socket, xdebug_sprintf("%s\n", ret_value)); - zval_dtor(&retval); - xdfree(ret_value); - return NULL; -} - -char *xdebug_handle_finish(xdebug_con *context, xdebug_arg *args) -{ - xdebug_llist_element *le; - function_stack_entry *fse; - TSRMLS_FETCH(); - - XG(context).do_next = 0; - XG(context).do_step = 0; - XG(context).do_finish = 1; - - if (XG(stack)) { - le = XDEBUG_LLIST_TAIL(XG(stack)); - fse = XDEBUG_LLIST_VALP(le); - XG(context).next_level = fse->level - 1; - } else { - XG(context).next_level = -1; - } - - return NULL; -} - -char *xdebug_handle_kill(xdebug_con *context, xdebug_arg *args) -{ - zend_bailout(); - return NULL; -} - -char *xdebug_handle_list(xdebug_con *context, xdebug_arg *args) -{ - char *tmp_file = NULL; - int tmp_begin = 0; - int tmp_end = 0; - xdebug_arg *parts = (xdebug_arg*) xdmalloc(sizeof(xdebug_arg)); - xdebug_gdb_options *options = (xdebug_gdb_options*) context->options; - int xml = (options->response_format == XDEBUG_RESPONSE_XML); - TSRMLS_FETCH(); - - xdebug_arg_init(parts); - - switch (args->c) { - case 0: - if (XG(context).list.last_file) { - tmp_file = XG(context).list.last_file; - tmp_begin = XG(context).list.last_line; - } else { - tmp_file = XG(context).program_name; - tmp_begin = 1; - } - tmp_end = tmp_begin + 9; - break; - case 1: - case 2: - xdebug_explode(":", args->args[0], parts, -1); - tmp_begin = parts->c == 1 ? atoi(parts->args[0]) : atoi(parts->args[1]); - if (tmp_begin <= 0) { - tmp_begin = 1; - } - - if (parts->c == 1) { /* Only line is given */ - if (XG(context).list.last_file) { - tmp_file = XG(context).list.last_file; - } else { - tmp_file = XG(context).program_name; - } - } else if (parts->c == 2) { /* File:line is given */ - tmp_file = parts->args[0]; - } - - if (args->c == 1) { - tmp_end = tmp_begin + 9; - } else { - tmp_end = atoi(args->args[1]); - } - break; - default: - return make_message(context, XDEBUG_E_TOO_MANY_ARGUMENTS, "Too many arguments."); - break; - } - SSEND(context->socket, xml ? "" : ""); - print_sourceline(context, tmp_file, tmp_begin, tmp_end, 0, options->response_format TSRMLS_CC); - SSEND(context->socket, xml ? "\n" : "\n"); - - xdebug_arg_dtor(parts); - return NULL; -} - -char *xdebug_handle_next(xdebug_con *context, xdebug_arg *args) -{ - xdebug_llist_element *le; - function_stack_entry *fse; - TSRMLS_FETCH(); - - XG(context).do_next = 1; - XG(context).do_step = 0; - XG(context).do_finish = 0; - - if (XG(stack)) { - le = XDEBUG_LLIST_TAIL(XG(stack)); - fse = XDEBUG_LLIST_VALP(le); - XG(context).next_level = fse->level; - } else { - XG(context).next_level = 0; - } - - return NULL; -} - -char *xdebug_handle_option(xdebug_con *context, xdebug_arg *args) -{ - xdebug_gdb_options *options = (xdebug_gdb_options*)context->options; - - if (strcmp(args->args[0], "response_format") == 0) { - options->response_format = atoi(args->args[1]); - } else if (strcmp(args->args[0], "dump_superglobals") == 0) { - options->dump_superglobals = atoi(args->args[1]); - } else { - return make_message(context, XDEBUG_E_UNKNOWN_OPTION, "Unknown option."); - } - - return NULL; -} - -char *xdebug_handle_print(xdebug_con *context, xdebug_arg *args) -{ - xdebug_gdb_options *options = (xdebug_gdb_options*)context->options; - int xml = (options->response_format == XDEBUG_RESPONSE_XML); - char *var_data; - zval *zvar; - TSRMLS_FETCH(); - - XG(active_symbol_table) = EG(active_symbol_table); - zvar = xdebug_get_php_symbol(args->args[0], strlen(args->args[0]) + 1); - if (zvar) { - var_data = return_printable_symbol(context, args->args[0], zvar); - XG(active_symbol_table) = NULL; - - if (var_data) { - SSEND(context->socket, xml ? "" : ""); - SENDMSG(context->socket, var_data); - SSEND(context->socket, xml ? "\n" : "\n"); - return NULL; - } - } - - return make_message(context, XDEBUG_E_SYMBOL_NOT_FOUND, "This symbol does not exist or is not yet initialized."); -} - -char *xdebug_handle_pwd(xdebug_con *context, xdebug_arg *args) -{ - char buffer[256 + 1]; - xdebug_gdb_options *options = (xdebug_gdb_options*) context->options; - - if (getcwd(buffer, 256)) { - if (options->response_format == XDEBUG_RESPONSE_XML) { - SENDMSG(context->socket, xdebug_sprintf("%s\n", buffer)); - } else { - SENDMSG(context->socket, xdebug_sprintf("Working directory %s.\n", buffer)); - } - } - return NULL; -} - -char *xdebug_handle_quit(xdebug_con *context, xdebug_arg *args) -{ - return NULL; -} - -char *xdebug_handle_run(xdebug_con *context, xdebug_arg *args) -{ - xdebug_gdb_options *options = (xdebug_gdb_options*) context->options; - - if (options->response_format == XDEBUG_RESPONSE_XML) { - SENDMSG(context->socket, xdebug_sprintf("%s\n", context->program_name)); - } else { - SENDMSG(context->socket, xdebug_sprintf("Starting program: %s\n", context->program_name)); - } - return NULL; -} - - -static void dump_class_breakpoint(void *context, xdebug_hash_element* he) -{ - xdebug_con *h = (xdebug_con*) context; - xdebug_gdb_options *options = (xdebug_gdb_options*) h->options; - xdebug_brk_info *brk_info = (xdebug_brk_info*) he->ptr; - - if (options->response_format == XDEBUG_RESPONSE_XML) { - SENDMSG( - h->socket, - xdebug_sprintf("%s%s", - brk_info->classname, brk_info->functionname)); - } else { - SENDMSG( - h->socket, - xdebug_sprintf("Method breakpoint: %s::%s\n", - brk_info->classname, brk_info->functionname)); - } -} - -static void dump_function_breakpoint(void *context, xdebug_hash_element* he) -{ - xdebug_con *h = (xdebug_con*) context; - xdebug_gdb_options *options = (xdebug_gdb_options*) h->options; - xdebug_brk_info *brk_info = (xdebug_brk_info*) he->ptr; - - if (options->response_format == XDEBUG_RESPONSE_XML) { - SENDMSG(h->socket, xdebug_sprintf("%s", brk_info->functionname)); - } else { - SENDMSG(h->socket, xdebug_sprintf("Function breakpoint: %s\n", brk_info->functionname)); - } -} - -static void dump_line_breakpoint(xdebug_con *h, xdebug_gdb_options *options, xdebug_brk_info* brk_info) -{ - char *condition = NULL; - int len; - - if (options->response_format == XDEBUG_RESPONSE_XML) { - if (condition) { - /* we ignore binary safety here */ - condition = xdebug_xmlize(brk_info->condition, strlen(brk_info->condition), &len); - SENDMSG(h->socket, - xdebug_sprintf("%s%d", - condition, - brk_info->file, - brk_info->lineno)); - xdfree(condition); - } else { - SENDMSG(h->socket, xdebug_sprintf("%s%d", - brk_info->file, - brk_info->lineno)); - } - } else { - if (condition) { - SENDMSG(h->socket, - xdebug_sprintf("Location breakpoint: %s:%d (condition= %s)\n", - brk_info->file, - brk_info->lineno, - brk_info->condition)); - } else { - SENDMSG(h->socket, - xdebug_sprintf("Location breakpoint: %s:%d\n", - brk_info->file, - brk_info->lineno)); - } - } -} - - -char *xdebug_handle_show_breakpoints(xdebug_con *context, xdebug_arg *args) -{ - xdebug_gdb_options *options = (xdebug_gdb_options*) context->options; - xdebug_llist_element *le; - - if (options->response_format == XDEBUG_RESPONSE_XML) { - SSEND(context->socket, ""); - } - - xdebug_hash_apply(context->function_breakpoints, (void *) context, dump_function_breakpoint); - xdebug_hash_apply(context->class_breakpoints, (void *) context, dump_class_breakpoint); - - for (le = XDEBUG_LLIST_TAIL(context->line_breakpoints); le != NULL; le = XDEBUG_LLIST_PREV(le)) { - dump_line_breakpoint(context, options, XDEBUG_LLIST_VALP(le)); - } - - if (options->response_format == XDEBUG_RESPONSE_XML) { - SSEND(context->socket, "\n"); - } - return NULL; -} - - -static char* show_local_vars(xdebug_con *context, xdebug_arg *args, void (*func)(void *, xdebug_hash_element*)) -{ - function_stack_entry *i; - xdebug_hash *tmp_hash; - xdebug_gdb_options *options = (xdebug_gdb_options*) context->options; - TSRMLS_FETCH(); - - - if (XDEBUG_LLIST_TAIL(XG(stack))) { - i = XDEBUG_LLIST_VALP(XDEBUG_LLIST_TAIL(XG(stack))); - - /* Only show vars when they are scanned */ - if (i->used_vars) { - if (options->response_format == XDEBUG_RESPONSE_XML) { - SSEND(context->socket, ""); - } - - tmp_hash = xdebug_used_var_hash_from_llist(i->used_vars); - xdebug_hash_apply(tmp_hash, (void *) context, func); - xdebug_hash_destroy(tmp_hash); - - if (options->response_format == XDEBUG_RESPONSE_XML) { - SSEND(context->socket, "\n"); - } - } else { - return make_message(context, XDEBUG_E_NOT_USER_DEFINED, "You can not show variables in functions not defined in your script."); - } - } - - return NULL; -} - -char *xdebug_handle_show(xdebug_con *context, xdebug_arg *args) -{ - return show_local_vars(context, args, dump_used_var); -} - - -char *xdebug_handle_show_local(xdebug_con *context, xdebug_arg *args) -{ - char *tmp; - TSRMLS_FETCH(); - - XG(active_symbol_table) = EG(active_symbol_table); - tmp = show_local_vars(context, args, dump_used_var_with_contents); - XG(active_symbol_table) = NULL; - return tmp; -} - - -char *xdebug_handle_step(xdebug_con *context, xdebug_arg *args) -{ - TSRMLS_FETCH(); - XG(context).do_step = 1; - XG(context).do_next = 0; - XG(context).do_finish = 0; - - return NULL; -} - - -/***************************************************************************** -** Parsing functions -*/ - -static int xdebug_gdb_parse_option(xdebug_con *context, char* line, int flags, char *end_cmd, char **error) -{ - char *ptr; - xdebug_gdb_cmd *cmd; - int retval; - char *ret_err = NULL; - int i; - - xdebug_arg *args = (xdebug_arg*) xdmalloc(sizeof(xdebug_arg)); - xdebug_arg *endcmds = (xdebug_arg*) xdmalloc(sizeof(xdebug_arg)); - xdebug_arg_init(args); - xdebug_arg_init(endcmds); - - xdebug_explode(",", end_cmd, endcmds, -1); - - *error = NULL; - - /* Try to find command */ - ptr = strchr(line, ' '); - if (!ptr) { /* No separator found */ - /* Check for the special case "help" */ - if (strcmp(line, "help") == 0) { - show_available_commands(context, flags); - retval = 0; - goto cleanup; - } - if (!(cmd = lookup_cmd(line, flags))) { - *error = make_message(context, XDEBUG_E_UNDEFINED_COMMAND, "Undefined command, try \"help\"."); - retval = -1; - goto cleanup; - } - } else { - char *tmp = (char*) xdmalloc(ptr - line + 1); - memcpy(tmp, line, ptr - line); - tmp[ptr - line] = '\0'; - - /* Check for the special case "help [command]" */ - if (strcmp(tmp, "help") == 0) { - xdebug_explode(" ", ptr + 1, args, -1); - if (args->c > 0) { - show_command_info(context, lookup_cmd(args->args[0], XDEBUG_ALL)); - retval = 0; - } else { - *error = make_message(context, XDEBUG_E_UNDEFINED_COMMAND, "Undefined command, try \"help\"."); - retval = -1; - } - xdfree(tmp); - goto cleanup; - } - - /* Scan for valid commands */ - if ((cmd = lookup_cmd(tmp, flags))) { - xdfree(tmp); - xdebug_explode(" ", ptr + 1, args, -1); - } else { - *error = make_message(context, XDEBUG_E_UNDEFINED_COMMAND, "Undefined command, try \"help\"."); - xdfree(tmp); - retval = -1; - goto cleanup; - } - } - - retval = 0; - - /* Default in continue mode */ - if (args->c >= cmd->args) { - ret_err = cmd->handler(context, args); - if (ret_err) { - *error = xdstrdup(ret_err); - xdfree(ret_err); - retval = -1; - goto cleanup; - } - } else { - *error = xdstrdup(cmd->description); - /* Oopsie, error */ - retval = -1; - goto cleanup; - } - /* If the end command is reached, or the command is quit, set the return - * value to 1 (continue) */ - for (i = 0; i < endcmds->c; i++) { - if (strcmp(cmd->name, endcmds->args[i]) == 0) { - retval = 1; - goto cleanup; - } - } -cleanup: - xdebug_arg_dtor(args); - xdebug_arg_dtor(endcmds); - return retval; -} - -static void xdebug_gdb_option_result(xdebug_con *context, int ret, char *error) -{ - if (error || ret == -1) { - SSEND(context->socket, "-ERROR"); - if (error) { - SSEND(context->socket, ": "); - SSEND(context->socket, error); - } - SSEND(context->socket, "\n"); - } else { - SSEND(context->socket, "+OK\n"); - } -} - -/***************************************************************************** -** Handlers for debug functions -*/ - -char *xdebug_gdb_get_revision(void) -{ - return "$Revision: 1.92 $"; -} - -int xdebug_gdb_init(xdebug_con *context, int mode) -{ - char *option; - int ret; - char *error = NULL; - xdebug_gdb_options *options; - TSRMLS_FETCH(); - - SENDMSG(context->socket, xdebug_sprintf("This is Xdebug version %s.\n", XDEBUG_VERSION)); - SSEND(context->socket, "Copyright 2002-2009 by Derick Rethans,\n"); - context->buffer = xdmalloc(sizeof(fd_buf)); - context->buffer->buffer = NULL; - context->buffer->buffer_size = 0; - - context->options = xdmalloc(sizeof(xdebug_gdb_options)); - options = (xdebug_gdb_options*) context->options; - options->response_format = XDEBUG_RESPONSE_NORMAL; - options->dump_superglobals = 1; - - /* Initialize auto globals in Zend Engine 2 */ - zend_is_auto_global("_ENV", sizeof("_ENV")-1 TSRMLS_CC); - zend_is_auto_global("_GET", sizeof("_GET")-1 TSRMLS_CC); - zend_is_auto_global("_POST", sizeof("_POST")-1 TSRMLS_CC); - zend_is_auto_global("_COOKIE", sizeof("_COOKIE")-1 TSRMLS_CC); - zend_is_auto_global("_REQUEST", sizeof("_REQUEST")-1 TSRMLS_CC); - zend_is_auto_global("_FILES", sizeof("_FILES")-1 TSRMLS_CC); - zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC); - - context->function_breakpoints = xdebug_hash_alloc(64, (xdebug_hash_dtor) xdebug_hash_brk_dtor); - context->exception_breakpoints = xdebug_hash_alloc(64, (xdebug_hash_dtor) xdebug_hash_brk_dtor); - context->class_breakpoints = xdebug_hash_alloc(64, (xdebug_hash_dtor) xdebug_hash_brk_dtor); - context->line_breakpoints = xdebug_llist_alloc((xdebug_llist_dtor) xdebug_llist_brk_dtor); - do { - SENDMSG(context->socket, xdebug_sprintf("?init %s\n", context->program_name)); - option = xdebug_fd_read_line(context->socket, context->buffer, FD_RL_SOCKET); - if (!option) { - return 0; - } - ret = xdebug_gdb_parse_option(context, option, XDEBUG_INIT | XDEBUG_DATA | XDEBUG_BREAKPOINT | XDEBUG_RUN | XDEBUG_STATUS, "run", (char**) &error); - xdebug_gdb_option_result(context, ret, error); - free(option); - } while (1 != ret); - - return 1; -} - -int xdebug_gdb_deinit(xdebug_con *context) -{ - xdfree(context->options); - xdebug_hash_destroy(context->function_breakpoints); - xdebug_hash_destroy(context->exception_breakpoints); - xdebug_hash_destroy(context->class_breakpoints); - xdebug_llist_destroy(context->line_breakpoints, NULL); - xdfree(context->buffer); - - return 1; -} - -int xdebug_gdb_error(xdebug_con *context, int type, char *exception_type, char *message, const char *file, const uint lineno, xdebug_llist *stack) -{ - char *errortype; - int ret; - char *option; - char *error = NULL; - int runtime_allowed; - xdebug_gdb_options *options = (xdebug_gdb_options*) context->options; - - if (exception_type) { - errortype = exception_type; - } else { - errortype = xdebug_error_type(type); - } - - runtime_allowed = ( - (type != E_ERROR) && - (type != E_CORE_ERROR) && - (type != E_COMPILE_ERROR) && - (type != E_USER_ERROR) - ) ? XDEBUG_BREAKPOINT | XDEBUG_RUNTIME : 0; - - if (options->response_format == XDEBUG_RESPONSE_XML) { - SENDMSG(context->socket, xdebug_sprintf("%d%s%s%s%lu", type, errortype, message, file, lineno)); - print_stackframe(context, 0, XDEBUG_LLIST_VALP(XDEBUG_LLIST_TAIL(stack)), options->response_format, XDEBUG_FRAME_NORMAL); - SENDMSG(context->socket, xdebug_sprintf("\n")); - } else { - SENDMSG(context->socket, xdebug_sprintf("\nProgram received signal %s: %s.\n", errortype, message)); - print_stackframe(context, 0, XDEBUG_LLIST_VALP(XDEBUG_LLIST_TAIL(stack)), options->response_format, XDEBUG_FRAME_NORMAL); - } - - if (!exception_type) { - xdfree(errortype); - } - - do { - SSEND(context->socket, "?cmd\n"); - option = xdebug_fd_read_line(context->socket, context->buffer, FD_RL_SOCKET); - if (!option) { - return 0; - } - ret = xdebug_gdb_parse_option(context, option, XDEBUG_DATA | XDEBUG_RUN | runtime_allowed | XDEBUG_STATUS, "cont,continue", (char**) &error); - xdebug_gdb_option_result(context, ret, error); - free(option); - } while (1 != ret); - - return 1; -} - -int xdebug_gdb_breakpoint(xdebug_con *context, xdebug_llist *stack, char *file, long lineno, int type, char *exception_type, char *message) -{ - function_stack_entry *i; - int ret; - char *option; - char *error = NULL; - xdebug_gdb_options *options = (xdebug_gdb_options*) context->options; - int xml = (options->response_format == XDEBUG_RESPONSE_XML); - TSRMLS_FETCH(); - - i = XDEBUG_LLIST_VALP(XDEBUG_LLIST_TAIL(stack)); - - SSEND(context->socket, xml ? "" : ""); - if (type == XDEBUG_BREAK) { - print_breakpoint(context, i, options->response_format); - } - print_sourceline(context, file, lineno, lineno, -1, options->response_format TSRMLS_CC); - SSEND(context->socket, xml ? "\n" : "\n"); - - do { - SSEND(context->socket, "?cmd\n"); - option = xdebug_fd_read_line(context->socket, context->buffer, FD_RL_SOCKET); - if (!option) { - return 0; - } - ret = xdebug_gdb_parse_option(context, option, XDEBUG_BREAKPOINT | XDEBUG_DATA | XDEBUG_RUN | XDEBUG_RUNTIME | XDEBUG_STATUS, "cont,continue,step,next,finish", (char**) &error); - xdebug_gdb_option_result(context, ret, error); - free(option); - } while (1 != ret); - - return 1; -} Deleted: xdebug/trunk/xdebug_handler_gdb.h =================================================================== --- xdebug/trunk/xdebug_handler_gdb.h 2009-12-28 01:02:06 UTC (rev 3164) +++ xdebug/trunk/xdebug_handler_gdb.h 2009-12-28 01:04:10 UTC (rev 3165) @@ -1,90 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Xdebug | - +----------------------------------------------------------------------+ - | Copyright (c) 2002-2009 Derick Rethans | - +----------------------------------------------------------------------+ - | This source file is subject to version 1.0 of the Xdebug license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at | - | http://xdebug.derickrethans.nl/license.php | - | If you did not receive a copy of the Xdebug license and are unable | - | to obtain it through the world-wide-web, please send a note to | - | xdebug@derickrethans.nl so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Derick Rethans | - +----------------------------------------------------------------------+ - */ - -#ifndef __HAVE_XDEBUG_HANDLER_GDB_H__ -#define __HAVE_XDEBUG_HANDLER_GDB_H__ - -#include -#include "xdebug_handlers.h" -#include "xdebug_mm.h" - -#define XDEBUG_INIT 1 -#define XDEBUG_BREAKPOINT 2 -#define XDEBUG_RUN 4 -#define XDEBUG_RUNTIME 8 -#define XDEBUG_DATA 16 -#define XDEBUG_STATUS 32 - -#define XDEBUG_ALL 63 - -typedef struct xdebug_gdb_cmd { - char *name; - int args; - char *description; - char *(*handler)(xdebug_con *context, xdebug_arg *args); - int show; - char *help; -} xdebug_gdb_cmd; - - -#define XDEBUG_D 0 -#define XDEBUG_D_BREAKPOINT_SET XDEBUG_D | 1 -#define XDEBUG_D_BREAKPOINT_REMOVED XDEBUG_D | 2 - -#define XDEBUG_E 1024 -#define XDEBUG_E_INVALID_FORMAT XDEBUG_E | 1 -#define XDEBUG_E_BREAKPOINT_NOT_SET XDEBUG_E | 2 -#define XDEBUG_E_BREAKPOINT_NOT_REMOVED XDEBUG_E | 3 -#define XDEBUG_E_EVAL XDEBUG_E | 4 -#define XDEBUG_E_TOO_MANY_ARGUMENTS XDEBUG_E | 5 -#define XDEBUG_E_NO_INFO XDEBUG_E | 6 -#define XDEBUG_E_UNDEFINED_COMMAND XDEBUG_E | 7 -#define XDEBUG_E_SYMBOL_NOT_FOUND XDEBUG_E | 8 -#define XDEBUG_E_NOT_USER_DEFINED XDEBUG_E | 9 -#define XDEBUG_E_UNKNOWN_OPTION XDEBUG_E | 10 - -#define XDEBUG_RESPONSE_NORMAL 0 -#define XDEBUG_RESPONSE_XML 1 - -#define XDEBUG_FRAME_NORMAL 0 -#define XDEBUG_FRAME_FULL 1 - -typedef struct xdebug_gdb_options { - int response_format; - int dump_superglobals; -} xdebug_gdb_options; - - -int xdebug_gdb_init(xdebug_con *context, int mode); -int xdebug_gdb_deinit(xdebug_con *context); -int xdebug_gdb_error(xdebug_con *context, int type, char *exception_type, char *message, const char *file, const uint lineno, xdebug_llist *stack); -int xdebug_gdb_breakpoint(xdebug_con *context, xdebug_llist *stack, char *file, long lineno, int type, char *exception_type, char *message); -char *xdebug_gdb_get_revision(void); - -#define xdebug_handler_gdb { \ - xdebug_gdb_init, \ - xdebug_gdb_deinit, \ - xdebug_gdb_error, \ - xdebug_gdb_breakpoint, \ - NULL, \ - NULL, \ - xdebug_gdb_get_revision \ -} - -#endif - Deleted: xdebug/trunk/xdebug_handler_php3.c =================================================================== --- xdebug/trunk/xdebug_handler_php3.c 2009-12-28 01:02:06 UTC (rev 3164) +++ xdebug/trunk/xdebug_handler_php3.c 2009-12-28 01:04:10 UTC (rev 3165) @@ -1,152 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Xdebug | - +----------------------------------------------------------------------+ - | Copyright (c) 2002-2009 Derick Rethans | - +----------------------------------------------------------------------+ - | This source file is subject to version 1.0 of the Xdebug license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at | - | http://xdebug.derickrethans.nl/license.php | - | If you did not receive a copy of the Xdebug license and are unable | - | to obtain it through the world-wide-web, please send a note to | - | xdebug@derickrethans.nl so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Derick Rethans | - +----------------------------------------------------------------------+ - */ - -#include "php.h" -#include "TSRM.h" -#include "php_globals.h" -#include "php_xdebug.h" -#include "xdebug_private.h" -#include "xdebug_com.h" -#include "xdebug_handler_php3.h" -#include "xdebug_llist.h" -#include "xdebug_mm.h" -#include "xdebug_var.h" - -#ifdef PHP_WIN32 -#include "win32/time.h" -#include -#endif - - -static char *find_hostname(void) -{ - char tmpname[33]; - int err; - - memset(tmpname, 0, sizeof(tmpname)); - err = gethostname(tmpname, sizeof(tmpname) - 1); - if (err == -1) { - return NULL; - } - return (char *) xdstrdup(tmpname); -} - - -static char *get_current_time(void) -{ - static char debug_timebuf[50]; - char microbuf[10]; -#if HAVE_GETTIMEOFDAY - struct timeval tv; - struct timezone tz; -#endif - const struct tm *tm; - size_t len; - time_t t; - - memset(debug_timebuf, 0, sizeof(debug_timebuf)); - t = time(NULL); - tm = localtime((const time_t *) &t); - len = strftime(debug_timebuf, (sizeof(debug_timebuf) - sizeof(microbuf) - 1), "%Y-%m-%d %H:%M", tm); - -#if HAVE_GETTIMEOFDAY - gettimeofday(&tv, &tz); - snprintf(microbuf, sizeof(microbuf) - 1, ":%06lu", (long) tv.tv_usec); - strcat(debug_timebuf, microbuf); -#endif - return debug_timebuf; -} - -char *xdebug_php3_get_revision(void) -{ - return "$Revision: 1.23 $"; -} - -int xdebug_php3_init(xdebug_con *context, int mode) -{ - return 1; -} - -int xdebug_php3_deinit(xdebug_con *context) -{ - return 1; -} - -#define SENDMSG(socket, str) { \ - char *message_buffer; \ - \ - message_buffer = str; \ - SSEND(socket, message_buffer); \ - xdfree(message_buffer); \ -} - -int xdebug_php3_error(xdebug_con *h, int type, char *exception_type, char *message, const char *location, const uint line, xdebug_llist *stack) -{ - char *time_buffer; - char *hostname; - char *prefix; - char *errortype; - xdebug_llist_element *le; - TSRMLS_FETCH(); - - time_buffer = get_current_time(); - hostname = find_hostname(); - if (!hostname) { - hostname = estrdup("{unknown}"); - } - prefix = xdebug_sprintf("%s %s(%lu) ", time_buffer, hostname, getpid()); - if (exception_type) { - errortype = exception_type; - } else { - errortype = xdebug_error_type(type); - } - - /* start */ - SENDMSG(h->socket, xdebug_sprintf("%sstart: %s\n", prefix, errortype)); - - /* header */ - SENDMSG(h->socket, xdebug_sprintf("%smessage: %s\n", prefix, message)); - SENDMSG(h->socket, xdebug_sprintf("%slocation: %s:%d\n", prefix, location, line)); - SENDMSG(h->socket, xdebug_sprintf("%sframes: %d\n", prefix, stack->size)); - - /* stack elements */ - if (stack) { - for (le = XDEBUG_LLIST_HEAD(stack); le != NULL; le = XDEBUG_LLIST_NEXT(le)) - { - function_stack_entry *i = XDEBUG_LLIST_VALP(le); - char *tmp_name; - - tmp_name = xdebug_show_fname(i->function, 0, 0 TSRMLS_CC); - SENDMSG(h->socket, xdebug_sprintf("%sfunction: %s\n", prefix, tmp_name)); - xdfree(tmp_name); - - SENDMSG(h->socket, xdebug_sprintf("%slocation: %s:%d\n", prefix, i->filename, i->lineno)); - } - } - - /* stop */ - SENDMSG(h->socket, xdebug_sprintf("%sstop: %s\n", prefix, errortype)); - - if (!exception_type) { - xdfree(errortype); - } - xdfree(prefix); - xdfree(hostname); - - return 1; -} Deleted: xdebug/trunk/xdebug_handler_php3.h =================================================================== --- xdebug/trunk/xdebug_handler_php3.h 2009-12-28 01:02:06 UTC (rev 3164) +++ xdebug/trunk/xdebug_handler_php3.h 2009-12-28 01:04:10 UTC (rev 3165) @@ -1,41 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Xdebug | - +----------------------------------------------------------------------+ - | Copyright (c) 2002-2009 Derick Rethans | - +----------------------------------------------------------------------+ - | This source file is subject to version 1.0 of the Xdebug license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at | - | http://xdebug.derickrethans.nl/license.php | - | If you did not receive a copy of the Xdebug license and are unable | - | to obtain it through the world-wide-web, please send a note to | - | xdebug@derickrethans.nl so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Derick Rethans | - +----------------------------------------------------------------------+ - */ - -#ifndef __HAVE_XDEBUG_HANDLER_PHP3_H__ -#define __HAVE_XDEBUG_HANDLER_PHP3_H__ - -#include "xdebug_handlers.h" - - -int xdebug_php3_init(xdebug_con *context, int mode); -int xdebug_php3_deinit(xdebug_con *context); -int xdebug_php3_error(xdebug_con *context, int type, char *exception_type, char *message, const char *location, const uint line, xdebug_llist *stack); -char *xdebug_php3_get_revision(void); - -#define xdebug_handler_php3 { \ - xdebug_php3_init, \ - xdebug_php3_deinit, \ - xdebug_php3_error, \ - NULL, \ - NULL, \ - NULL, \ - xdebug_php3_get_revision \ -} - -#endif - Modified: xdebug/trunk/xdebug_handlers.c =================================================================== --- xdebug/trunk/xdebug_handlers.c 2009-12-28 01:02:06 UTC (rev 3164) +++ xdebug/trunk/xdebug_handlers.c 2009-12-28 01:04:10 UTC (rev 3165) @@ -20,14 +20,10 @@ #include "xdebug_com.h" #include "xdebug_handlers.h" #include "xdebug_handler_dbgp.h" -#include "xdebug_handler_gdb.h" -#include "xdebug_handler_php3.h" #include "xdebug_mm.h" xdebug_remote_handler_info handlers[] = { { "dbgp", "DBGp - Common DeBuGger Protocol", xdebug_handler_dbgp }, - { "gdb", "GDB - GNU Debugger protocol", xdebug_handler_gdb }, - { "php3", "PHP3 - PHP 3 Debugger protocol", xdebug_handler_php3 }, { 0, NULL, { NULL } } };