[xdebug-dev] xdebug xdebug/php_xdebug.h xdebug/xdebug.c xdebug/xdebug_handler_dbgp.c xdebug/xdebug_handler_dbgp.h xdebug/xdebug_var.c - magic_cookie is not necessary for remote debugging

From: Shane Caraveo <shane[@]caraveo.com>
Date: Tue, 20 Apr 2004 23:51:56 +0200

Date: Tue Apr 20 23:51:55 CEST 2004
User: Shane Caraveo
Directory: xdebug

Log Message:
[7:00]
- magic_cookie is not necessary for remote debugging
- implement property_set based on eval
# todo's are left on this
- implement property_value based on property_get code
# needs more work, see comments in code
- property_get now uses eval as last resort to get a value
- implement stdout redirection
# only works in copy mode, not full redirection mode
# this is one way to do it, but we might also consider
# using filters so we can deal with stderr and stdin
- fix stderr command to return success=0
- factor the eval function so we have some common eval code
- fix CMD_OPTION to work with -- args
- fix fullname attribute to be real php syntax
- fix last response for stop and detach commands (identified by valgrind)

Modified files:
           xdebug/php_xdebug.h (version: 1.73)
           xdebug/xdebug.c (version: 1.211)
           xdebug/xdebug_handler_dbgp.c (version: 1.40)
           xdebug/xdebug_handler_dbgp.h (version: 1.10)
           xdebug/xdebug_var.c (version: 1.45)

[FILE: /xdebug/php_xdebug.h]

===================================================================
RCS file: cvstemp,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -r1.72 -r1.73
--- xdebug/php_xdebug.h:1.72 Sun Apr 11 12:22:08 2004 GMT
+++ xdebug/php_xdebug.h Tue Apr 20 19:51:55 2004 GMT
@@ -157,6 +157,13 @@
         /* DBGp globals */
         char *lastcmd;
         char *lasttransid;
+
+ /* output redirection */
+ php_output_globals stdio;
+ int stdout_redirected;
+ int stderr_redirected;
+ int stdin_redirected;
+
 ZEND_END_MODULE_GLOBALS(xdebug)
 
 #ifdef ZTS

[FILE: /xdebug/xdebug.c]

===================================================================
RCS file: cvstemp,v
retrieving revision 1.210
retrieving revision 1.211
diff -u -r1.210 -r1.211
--- xdebug/xdebug.c:1.210 Mon Apr 19 23:52:04 2004 GMT
+++ xdebug/xdebug.c Tue Apr 20 19:51:55 2004 GMT
@@ -872,7 +872,6 @@
 
                 /* Start remote context if requested */
                 if (
- magic_cookie &&
                         !XG(remote_enabled) &&
                         XG(remote_enable) &&
                         (XG(remote_mode) == XDEBUG_REQ)

[FILE: /xdebug/xdebug_handler_dbgp.c]

===================================================================
RCS file: cvstemp,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- xdebug/xdebug_handler_dbgp.c:1.39 Mon Apr 19 23:52:04 2004 GMT
+++ xdebug/xdebug_handler_dbgp.c Tue Apr 20 19:51:55 2004 GMT
@@ -218,26 +218,38 @@
 /*****************************************************************************
 ** Data returning functions
 */
-static xdebug_xml_node* get_symbol_contents(char* name, int name_length TSRMLS_DC)
+static zval* get_symbol_contents_zval(char* name, int name_length TSRMLS_DC)
 {
         HashTable *st = NULL;
         zval **retval;
 
         st = XG(active_symbol_table);
         if (st && zend_hash_find(st, name, name_length, (void **) &retval) == SUCCESS) {
- return get_zval_value_xml_node(name, *retval);
+ return *retval;
         }
 
         st = EG(active_op_array)->static_variables;
         if (st) {
                 if (zend_hash_find(st, name, name_length, (void **) &retval) == SUCCESS) {
- return get_zval_value_xml_node(name, *retval);
+ return *retval;
                 }
         }
         
         st = &EG(symbol_table);
         if (zend_hash_find(st, name, name_length, (void **) &retval) == SUCCESS) {
- return get_zval_value_xml_node(name, *retval);
+ return *retval;
+ }
+
+ return NULL;
+}
+
+static xdebug_xml_node* get_symbol_contents(char* name, int name_length TSRMLS_DC)
+{
+ zval *retval;
+
+ retval = get_symbol_contents_zval(name, name_length TSRMLS_CC);
+ if (retval) {
+ return get_zval_value_xml_node(name, retval);
         }
 
         return NULL;
@@ -709,10 +721,28 @@
         xdebug_xml_add_attribute_ex(*retval, "id", xdebug_sprintf("%d", brk_id), 0, 1);
 }
 
-DBGP_FUNC(eval)
+static int _xdebug_do_eval(unsigned char *eval_string, zval *ret_zval TSRMLS_DC)
 {
         int old_error_reporting;
- char *eval_string;
+ int res;
+
+ /* Remember error reporting level */
+ old_error_reporting = EG(error_reporting);
+ EG(error_reporting) = 0;
+ /* Do evaluation */
+ XG(breakpoints_allowed) = 0;
+ res = zend_eval_string(eval_string, ret_zval, "xdebug eval" TSRMLS_CC);
+
+ /* Clean up */
+ EG(error_reporting) = old_error_reporting;
+ XG(breakpoints_allowed) = 1;
+
+ return res;
+}
+
+DBGP_FUNC(eval)
+{
+ unsigned char *eval_string;
         xdebug_xml_node *ret_xml;
         zval ret_zval;
         int new_length;
@@ -722,20 +752,11 @@
                 RETURN_RESULT(XG(status), XG(reason), XDEBUG_ERROR_INVALID_ARGS);
         }
 
- /* Remember error reporting level */
- old_error_reporting = EG(error_reporting);
- EG(error_reporting) = 0;
-
         /* base64 decode eval string */
         eval_string = xdebug_base64_decode(CMD_OPTION('-'), strlen(CMD_OPTION('-')), &new_length);
 
- /* Do evaluation */
- XG(breakpoints_allowed) = 0;
- res = zend_eval_string(eval_string, &ret_zval, "xdebug eval" TSRMLS_CC);
+ res = _xdebug_do_eval(eval_string, &ret_zval TSRMLS_CC);
 
- /* Clean up */
- EG(error_reporting) = old_error_reporting;
- XG(breakpoints_allowed) = 1;
         efree(eval_string);
 
         /* Handle result */
@@ -748,20 +769,95 @@
         }
 }
 
+/* these functions interupt PHP's output functions, so we can
+ redirect to our remote debugger! */
+static int _xdebug_send_stream(const char *name, const char *str, uint str_length TSRMLS_DC)
+{
+ /* create an xml document to send as the stream */
+ xdebug_xml_node *message;
+ int new_len;
+ char *encoded_source;
+
+ message = xdebug_xml_node_init("stream");
+ xdebug_xml_add_attribute_ex(message, "type", (char *)name, 0, 0);
+ xdebug_xml_add_attribute_ex(message, "encoding", "base64", 0, 0);
+ encoded_source = xdebug_base64_encode(str, str_length, &new_len);
+ xdebug_xml_add_text(message, xdstrdup(encoded_source));
+ send_message(&XG(context), message);
+ xdebug_xml_node_dtor(message);
+
+ efree(encoded_source);
+ return 0;
+}
+
+static int _xdebug_body_write(const char *str, uint str_length TSRMLS_DC)
+{
+ zend_unset_timeout(TSRMLS_C);
+ if (XG(stdout_redirected) != 0) {
+ _xdebug_send_stream("stdout", str, str_length TSRMLS_CC);
+ }
+
+ /* let PHP also send it out, as it may be needed */
+ zend_set_timeout(EG(timeout_seconds));
+ return XG(stdio).php_body_write(str, str_length TSRMLS_CC);
+}
+
+static int _xdebug_header_write(const char *str, uint str_length TSRMLS_DC)
+{
+ zend_unset_timeout(TSRMLS_C);
+ if (XG(stdout_redirected) != 0) {
+ _xdebug_send_stream("stdout", str, str_length TSRMLS_CC);
+ }
+
+ /* let PHP also send it out, as it may be needed */
+ zend_set_timeout(EG(timeout_seconds));
+ return XG(stdio).php_header_write(str, str_length TSRMLS_CC);
+}
 
 DBGP_FUNC(stderr)
 {
- RETURN_RESULT(XG(status), XG(reason), XDEBUG_ERROR_UNIMPLEMENTED);
+ xdebug_xml_add_attribute(*retval, "success", "0");
 }
 
 DBGP_FUNC(stdout)
 {
- RETURN_RESULT(XG(status), XG(reason), XDEBUG_ERROR_UNIMPLEMENTED);
+ int mode = 0;
+ char *success = "0";
+
+ if (!CMD_OPTION('c')) {
+ RETURN_RESULT(XG(status), XG(reason), XDEBUG_ERROR_INVALID_ARGS);
+ }
+
+ mode = strtol(CMD_OPTION('c'), NULL, 10);
+
+ if (mode == 0 && XG(stdout_redirected) != 0) {
+ if (XG(stdio).php_body_write != NULL && OG(php_body_write)) {
+ OG(php_body_write) = XG(stdio).php_body_write;
+ OG(php_header_write) = XG(stdio).php_header_write;
+
+ XG(stdio).php_body_write = NULL;
+ XG(stdio).php_header_write = NULL;
+ success = "1";
+ }
+ } else if (mode != 0 && XG(stdout_redirected) == 0) {
+ if (XG(stdio).php_body_write == NULL && OG(php_body_write)) {
+ XG(stdio).php_body_write = OG(php_body_write);
+ OG(php_body_write) = _xdebug_body_write;
+ XG(stdio).php_header_write = OG(php_header_write);
+ OG(php_header_write) = _xdebug_header_write;
+ success = "1";
+ }
+ }
+
+ XG(stdout_redirected) = mode;
+
+ xdebug_xml_add_attribute_ex(*retval, "success", xdstrdup(success), 0, 1);
 }
 
 
 DBGP_FUNC(stop)
 {
+ XG(status) = DBGP_STATUS_STOPPING;
         zend_bailout();
 }
 
@@ -809,6 +905,7 @@
 
 DBGP_FUNC(detach)
 {
+ XG(status) = DBGP_STATUS_STOPPING;
         XG(remote_enabled) = 0;
 }
 
@@ -988,6 +1085,9 @@
 DBGP_FUNC(property_get)
 {
         xdebug_xml_node *var_data;
+ zval ret_zval;
+ int res;
+ xdebug_xml_node *ret_xml;
 
         if (!CMD_OPTION('n')) {
                 RETURN_RESULT(XG(status), XG(reason), XDEBUG_ERROR_INVALID_ARGS);
@@ -1000,18 +1100,126 @@
         if (var_data) {
                 xdebug_xml_add_child(*retval, var_data);
         } else {
- RETURN_RESULT(XG(status), XG(reason), XDEBUG_ERROR_PROPERTY_NON_EXISTANT);
+ /* if we cannot get the value directly, then try eval */
+ res = _xdebug_do_eval(CMD_OPTION('n'), &ret_zval TSRMLS_CC);
+ if (res == FAILURE) {
+ RETURN_RESULT(XG(status), XG(reason), XDEBUG_ERROR_PROPERTY_NON_EXISTANT);
+ } else {
+ ret_xml = get_zval_value_xml_node(CMD_OPTION('n'), &ret_zval);
+ xdebug_xml_add_child(*retval, ret_xml);
+ zval_dtor(&ret_zval);
+ }
         }
 }
 
 DBGP_FUNC(property_set)
 {
- RETURN_RESULT(XG(status), XG(reason), XDEBUG_ERROR_UNIMPLEMENTED);
+ xdebug_xml_node *var_data;
+ int depth = 0;
+ int context_id = 0;
+ char *new_value;
+ char *eval_string;
+ xdebug_xml_node *ret_xml;
+ zval ret_zval;
+ int new_length;
+ int res;
+ int address = 0;
+ char *key = CMD_OPTION('k'); /* property key */
+ char *name = CMD_OPTION('n');
+ char *data = CMD_OPTION('-');
+
+ /* XXX TODO
+ if the key or the address are returned, they can be used to more efficiently
+ retrieve the value from the variables list. Otherwise we use EVAL to set
+ the property which works great, but is slower.
+
+ handle the depth value and set the property at a specific stack depth
+
+ handle the context_id value and set the property in the correct context
+ */
+
+ if (!name) { /* name */
+ RETURN_RESULT(XG(status), XG(reason), XDEBUG_ERROR_INVALID_ARGS);
+ }
+ if (!data) {
+ RETURN_RESULT(XG(status), XG(reason), XDEBUG_ERROR_INVALID_ARGS);
+ }
+ if (CMD_OPTION('d')) { /* depth */
+ depth = strtol(CMD_OPTION('d'), NULL, 10);
+ }
+ if (CMD_OPTION('c')) { /* context_id */
+ context_id = strtol(CMD_OPTION('c'), NULL, 10);
+ }
+ if (CMD_OPTION('a')) { /* address */
+ address = strtol(CMD_OPTION('a'), NULL, 10);
+ }
+
+ /* base64 decode eval string */
+ new_value = xdebug_base64_decode(data, strlen(data), &new_length);
+ eval_string = xdebug_sprintf("%s = %s", name, new_value);
+ res = _xdebug_do_eval(eval_string, &ret_zval TSRMLS_CC);
+
+
+ efree(new_value);
+ xdfree(eval_string);
+ /* Handle result */
+ if (res == FAILURE) {
+ /* don't send an error, send success = zero */
+ xdebug_xml_add_attribute(*retval, "success", "0");
+ } else {
+ xdebug_xml_add_attribute(*retval, "success", "1");
+ /*
+ It is not spec to return the property element
+ ret_xml = get_zval_value_xml_node(name, &ret_zval);
+ xdebug_xml_add_child(*retval, ret_xml);
+ */
+ zval_dtor(&ret_zval);
+ }
 }
 
 DBGP_FUNC(property_value)
 {
- RETURN_RESULT(XG(status), XG(reason), XDEBUG_ERROR_UNIMPLEMENTED);
+ zval *var_data;
+ zval ret_zval;
+ int res;
+ xdebug_xml_node *ret_xml;
+ char *name = CMD_OPTION('n');
+
+ /* XXX TODO
+ handle the depth value and set the property at a specific stack depth
+
+ handle the context_id value and set the property in the correct context
+
+ if (CMD_OPTION('d')) {
+ depth = strtol(CMD_OPTION('d'), NULL, 10);
+ }
+ if (CMD_OPTION('c')) {
+ context_id = strtol(CMD_OPTION('c'), NULL, 10);
+ }
+ */
+
+ if (!name) {
+ RETURN_RESULT(XG(status), XG(reason), XDEBUG_ERROR_INVALID_ARGS);
+ }
+
+ XG(active_symbol_table) = EG(active_symbol_table);
+ var_data = get_symbol_contents_zval(name, strlen(name) + 1 TSRMLS_CC);
+ XG(active_symbol_table) = NULL;
+
+ if (var_data) {
+ /* XXX cheesy and lame, gets more than we want */
+ xdebug_var_export_xml_node(&var_data, name, *retval, 0 TSRMLS_CC);
+ } else {
+ /* if we cannot get the value directly, then try eval */
+ res = _xdebug_do_eval(CMD_OPTION('n'), &ret_zval TSRMLS_CC);
+ if (res == FAILURE) {
+ RETURN_RESULT(XG(status), XG(reason), XDEBUG_ERROR_PROPERTY_NON_EXISTANT);
+ } else {
+ /* XXX cheesy and lame, gets more than we want */
+ xdebug_var_export_xml_node(&var_data, name, *retval, 0 TSRMLS_CC);
+ zval_dtor(&ret_zval);
+ }
+ }
 }
 
 static void attach_used_var_with_contents(void *xml, xdebug_hash_element* he)
@@ -1299,13 +1507,13 @@
                 command = lookup_cmd(cmd);
 
                 if (command) {
- command->handler((xdebug_xml_node**) &retval, context, args TSRMLS_CC);
                         if (command->cont) {
                                 XG(status) = DBGP_STATUS_RUNNING;
                                 XG(reason) = DBGP_REASON_OK;
                                 XG(lastcmd) = command->name;
                                 XG(lasttransid) = xdstrdup(CMD_OPTION('i'));
                         }
+ command->handler((xdebug_xml_node**) &retval, context, args TSRMLS_CC);
 
                         ret = command->cont;
                 } else {
@@ -1328,7 +1536,7 @@
 
 char *xdebug_dbgp_get_revision(void)
 {
- return "$Revision: 1.39 $";
+ return "$Revision: 1.40 $";
 }
 
 int xdebug_dbgp_cmdloop(xdebug_con *context TSRMLS_DC)
@@ -1368,6 +1576,10 @@
         XG(lastcmd) = NULL;
         XG(lasttransid) = NULL;
 
+ XG(stdout_redirected) = 0;
+ XG(stderr_redirected) = 0;
+ XG(stdin_redirected) = 0;
+
         response = xdebug_xml_node_init("init");
 
 /* {{{ XML Init Stuff*/
@@ -1443,15 +1655,22 @@
 
         XG(status) = DBGP_STATUS_STOPPED;
         XG(reason) = DBGP_REASON_OK;
-
         response = xdebug_xml_node_init("response");
         xdebug_xml_add_attribute_ex(response, "command", XG(lastcmd), 0, 0);
- xdebug_xml_add_attribute_ex(response, "transaction_id", XG(lasttransid), 0, 1);
- xdebug_xml_add_attribute(response, "status", xdebug_dbgp_status_strings[XG(status)]);
- xdebug_xml_add_attribute(response, "reason", xdebug_dbgp_reason_strings[XG(reason)]);
+ xdebug_xml_add_attribute_ex(response, "transaction_id", XG(lasttransid), 0, 0);
+ xdebug_xml_add_attribute_ex(response, "status", xdebug_dbgp_status_strings[XG(status)], 0, 0);
+ xdebug_xml_add_attribute_ex(response, "reason", xdebug_dbgp_reason_strings[XG(reason)], 0, 0);
 
         send_message(context, response);
         xdebug_xml_node_dtor(response);
+
+ if (XG(stdio).php_body_write != NULL && OG(php_body_write)) {
+ OG(php_body_write) = XG(stdio).php_body_write;
+ OG(php_header_write) = XG(stdio).php_header_write;
+
+ XG(stdio).php_body_write = NULL;
+ XG(stdio).php_header_write = NULL;
+ }
         
         xdfree(context->options);
         xdebug_hash_destroy(context->function_breakpoints);

[FILE: /xdebug/xdebug_handler_dbgp.h]

===================================================================
RCS file: cvstemp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- xdebug/xdebug_handler_dbgp.h:1.9 Fri Apr 16 21:27:33 2004 GMT
+++ xdebug/xdebug_handler_dbgp.h Tue Apr 20 19:51:55 2004 GMT
@@ -71,7 +71,7 @@
         int cont;
 } xdebug_dbgp_cmd;
 
-#define CMD_OPTION(opt) args->value[(opt) - 'a']
+#define CMD_OPTION(opt) (opt == '-'?args->value[26]:args->value[(opt) - 'a'])
 
 typedef struct xdebug_dbgp_options {
         int max_children;

[FILE: /xdebug/xdebug_var.c]

===================================================================
RCS file: cvstemp,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- xdebug/xdebug_var.c:1.44 Tue Apr 13 18:33:45 2004 GMT
+++ xdebug/xdebug_var.c Tue Apr 20 19:51:55 2004 GMT
@@ -392,10 +392,10 @@
         
         if (hash_key->nKeyLength != 0) {
                 name = xdstrdup(hash_key->arKey);
- full_name = xdebug_sprintf("%s['%s']", parent_name, name);
+ full_name = xdebug_sprintf("$%s['%s']", parent_name, name);
         } else {
                 name = xdebug_sprintf("%ld", hash_key->h);
- full_name = xdebug_sprintf("%s[%s]", parent_name, name);
+ full_name = xdebug_sprintf("$%s[%s]", parent_name, name);
         }
 
         xdebug_xml_add_attribute_ex(node, "name", name, 0, 1);
@@ -426,7 +426,7 @@
                 modifier = xdebug_get_property_info(hash_key->arKey, &prop_name);
                 xdebug_xml_add_attribute(node, "name", prop_name);
                 /* XXX static vars? */
- full_name = xdebug_sprintf("%s->%s", parent_name, prop_name);
+ full_name = xdebug_sprintf("$%s->%s", parent_name, prop_name);
                 xdebug_xml_add_attribute_ex(node, "fullname", full_name, 0, 1);
                 xdebug_xml_add_attribute(node, "facet", modifier);
         }
@@ -509,12 +509,18 @@
 xdebug_xml_node* get_zval_value_xml_node(char *name, zval *val)
 {
         xdebug_xml_node *node;
+ char *full_name = NULL;
         TSRMLS_FETCH();
 
         node = xdebug_xml_node_init("property");
         if (name) {
+ if (name[0] != '$') {
+ full_name = xdebug_sprintf("$%s", name);
+ } else {
+ full_name = xdstrdup(name);
+ }
                 xdebug_xml_add_attribute_ex(node, "name", xdstrdup(name), 0, 1);
- xdebug_xml_add_attribute_ex(node, "fullname", xdstrdup(name), 0, 1);
+ xdebug_xml_add_attribute_ex(node, "fullname", xdstrdup(full_name), 0, 1);
         }
         xdebug_xml_add_attribute_ex(node, "address", xdebug_sprintf("%ld", (long) val), 0, 1);
         xdebug_var_export_xml_node(&val, name, node, 1 TSRMLS_CC);
Received on Tue Apr 20 2004 - 23:51:59 BST

This archive was generated by hypermail 2.2.0 : Sun Jun 24 2018 - 04:00:02 BST