This is an automated email from Gerrit.

"Antonio Borneo <borneo.anto...@gmail.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/6886

-- gerrit

commit 4afd37c23cd5ff99563feaa8e01aa5c8fed21e08
Author: Antonio Borneo <borneo.anto...@gmail.com>
Date:   Wed Mar 30 23:55:04 2022 +0200

    server/gdb: fix return of gdb remote monitor command
    
    Current implementation for gdb remote monitor command uses the
    command_run_line() to execute the command.
    While command_run_line() has several advantages, it unfortunately
    hides the error codes and outputs the result of the command
    through LOG_USER(), which is not what gdb requires. See 'qRcmd' in
    https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html
    
    Replace command_run_line() with Jim_EvalObj() and parse the output
    to provide the proper result to gdb.
    
    Can be tested by defining in OpenOCD:
            proc a {} {return hello}
            proc b {} {return -code 4}
            proc c {} {return -code 4 "This is an error!"}
    then by executing in gdb console:
            monitor a
            monitor b
            monitor c
            monitor foo
    
    Change-Id: I1b85554d59221560e97861a499e16764e70c1172
    Signed-off-by: Antonio Borneo <borneo.anto...@gmail.com>
    Reported-by: Torbjorn Svensson <torbjorn.svens...@st.com>

diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index 82c8ce92b3..fcc87fba1c 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -2761,11 +2761,52 @@ static int gdb_query_packet(struct connection 
*connection,
                        /* some commands need to know the GDB connection, make 
note of current
                         * GDB connection. */
                        current_gdb_connection = gdb_connection;
-                       command_run_line(cmd_ctx, cmd);
+                       struct target *saved_target_override = 
cmd_ctx->current_target_override;
+                       cmd_ctx->current_target_override = target;
+
+                       int retval = Jim_EvalObj(cmd_ctx->interp, 
Jim_NewStringObj(cmd_ctx->interp, cmd, -1));
+
+                       cmd_ctx->current_target_override = 
saved_target_override;
                        current_gdb_connection = NULL;
                        target_call_timer_callbacks_now();
                        gdb_connection->output_flag = GDB_OUTPUT_NO;
                        free(cmd);
+                       if (retval == JIM_RETURN)
+                               retval = cmd_ctx->interp->returnCode;
+                       int lenmsg;
+                       const char *cretmsg = 
Jim_GetString(Jim_GetResult(cmd_ctx->interp), &lenmsg);
+                       char *retmsg;
+                       if (lenmsg && cretmsg[lenmsg - 1] != '\n') {
+                               retmsg = alloc_printf("%s\n", cretmsg);
+                               lenmsg++;
+                       } else {
+                               retmsg = strdup(cretmsg);
+                       }
+                       if (!retmsg)
+                               return ERROR_GDB_BUFFER_TOO_SMALL;
+
+                       if (retval == JIM_OK) {
+                               if (lenmsg) {
+                                       char *hex_buffer = malloc(lenmsg * 2 + 
1);
+                                       if (!hex_buffer) {
+                                               free(retmsg);
+                                               return 
ERROR_GDB_BUFFER_TOO_SMALL;
+                                       }
+
+                                       size_t pkt_len = hexify(hex_buffer, 
(const uint8_t *)retmsg, lenmsg,
+                                                                               
        lenmsg * 2 + 1);
+                                       gdb_put_packet(connection, hex_buffer, 
pkt_len);
+                                       free(hex_buffer);
+                               } else {
+                                       gdb_put_packet(connection, "OK", 2);
+                               }
+                       } else {
+                               if (lenmsg)
+                                       gdb_output_con(connection, retmsg);
+                               gdb_send_error(connection, retval);
+                       }
+                       free(retmsg);
+                       return ERROR_OK;
                }
                gdb_put_packet(connection, "OK", 2);
                return ERROR_OK;

-- 

Reply via email to