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; } --