This is an automated email from Gerrit.

"Mark Goncharov <mark.goncha...@syntacore.com>" just uploaded a new patch set 
to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7200

-- gerrit

commit 6f6023358a680b8f1847d3de25cc339b9222f33d
Author: mga-sc <mark.goncha...@syntacore.com>
Date:   Mon Sep 19 13:14:21 2022 +0300

    src/server/tcl_server.c: Logs override command messages
    
    LOG_<smth> data overrides command_print messages, thus openocd
    doesn't show command output.
    
    //---------------------------------------------------
    
    Structure of communication between openocd and device
    using tcl connection:
    
    1) LOG_<smth> = fprintf(to openocd) -> call log_callback function
    
    2) command_run = command_print(call Jim_AppendString) ->
    command_output_text(call Get_JimString -> call output_handler)
    
    These log_callback and output_handler functions can be
    overwritten by specific server connection (like gdb and telnet do).
    
    The target of log_callback is to retranslate
    log messages to end device.
    The target of output_handler is to retranslate
    command messages to end device.
    
    //---------------------------------------------------
    
    Bug was found using tcl connection like: printf
    " capture { reset halt }\u001a capture { bp 0x8000007c 4 }\u001a "
    | nc localhost <tcl connection port>.
    During processing breakpoint LOG_WARNING occures and
    overwrites breakpoint set message.
    
    Signed-off-by: mga-sc <mark.goncha...@syntacore.com>
    Change-Id: I77173057b4618e151e05353873d958e1c07d09dd

diff --git a/src/helper/command.c b/src/helper/command.c
index 6898e2d7c6..20ffdac5cf 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -61,13 +61,6 @@ void *jimcmd_privdata(Jim_Cmd *cmd)
        return cmd->isproc ? NULL : cmd->u.native.privData;
 }
 
-static void tcl_output(void *privData, const char *file, unsigned line,
-       const char *function, const char *string)
-{
-       struct log_capture_state *state = privData;
-       Jim_AppendString(state->interp, state->output, string, strlen(string));
-}
-
 static struct log_capture_state *command_log_capture_start(Jim_Interp *interp)
 {
        /* capture log output and return it. A garbage collect can
@@ -88,8 +81,6 @@ static struct log_capture_state 
*command_log_capture_start(Jim_Interp *interp)
        state->interp = interp;
        state->output = jim_output;
 
-       log_add_callback(tcl_output, state);
-
        return state;
 }
 
@@ -110,8 +101,6 @@ static void command_log_capture_finish(struct 
log_capture_state *state)
        if (!state)
                return;
 
-       log_remove_callback(tcl_output, state);
-
        int length;
        Jim_GetString(state->output, &length);
 
diff --git a/src/server/tcl_server.c b/src/server/tcl_server.c
index 16cbedc76c..0bf281d333 100644
--- a/src/server/tcl_server.c
+++ b/src/server/tcl_server.c
@@ -36,6 +36,19 @@ static int tcl_input(struct connection *connection);
 static int tcl_output(struct connection *connection, const void *buf, ssize_t 
len);
 static int tcl_closed(struct connection *connection);
 
+static int tcl_command_callback(struct command_context *cmd_ctx, const char 
*buf)
+{
+       struct connection *connection = cmd_ctx->output_handler_priv;
+       return tcl_output(connection, buf, strlen(buf));
+}
+
+static void tcl_log_callback(void *priv, const char *file, unsigned int line,
+                                                        const char *function, 
const char *string)
+{
+       struct connection *con = priv;
+       tcl_output(con, string, strlen(string));
+}
+
 static int tcl_target_callback_event_handler(struct target *target,
                enum target_event event, void *priv)
 {
@@ -153,21 +166,21 @@ static int tcl_new_connection(struct connection 
*connection)
        /* store the connection object on cmd_ctx so we can access it from 
command handlers */
        connection->cmd_ctx->output_handler_priv = connection;
 
+
+       command_set_output_handler(connection->cmd_ctx, tcl_command_callback, 
connection);
        target_register_event_callback(tcl_target_callback_event_handler, 
connection);
        target_register_reset_callback(tcl_target_callback_reset_handler, 
connection);
        target_register_trace_callback(tcl_target_callback_trace_handler, 
connection);
+       log_add_callback(tcl_log_callback, connection);
 
        return ERROR_OK;
 }
 
 static int tcl_input(struct connection *connection)
 {
-       Jim_Interp *interp = (Jim_Interp *)connection->cmd_ctx->interp;
        int retval;
        int i;
        ssize_t rlen;
-       const char *result;
-       int reslen;
        struct tcl_connection *tclc;
        unsigned char in[256];
        char *tc_line_new;
@@ -231,10 +244,6 @@ static int tcl_input(struct connection *connection)
                } else {
                        tclc->tc_line[tclc->tc_lineoffset-1] = '\0';
                        command_run_line(connection->cmd_ctx, tclc->tc_line);
-                       result = Jim_GetString(Jim_GetResult(interp), &reslen);
-                       retval = tcl_output(connection, result, reslen);
-                       if (retval != ERROR_OK)
-                               return retval;
                        /* Always output ctrl-z as end of line to allow 
multiline results */
                        tcl_output(connection, "\x1a", 1);
                }
@@ -261,6 +270,7 @@ static int tcl_closed(struct connection *connection)
        target_unregister_event_callback(tcl_target_callback_event_handler, 
connection);
        target_unregister_reset_callback(tcl_target_callback_reset_handler, 
connection);
        target_unregister_trace_callback(tcl_target_callback_trace_handler, 
connection);
+       log_remove_callback(tcl_log_callback, connection);
 
        return ERROR_OK;
 }

-- 

Reply via email to