From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mailsec104.isp.belgacom.be (mailsec104.isp.belgacom.be [195.238.20.100]) by sourceware.org (Postfix) with ESMTPS id 217833858024 for ; Sat, 22 May 2021 16:34:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 217833858024 IronPort-SDR: pT+VQPPmFPoX+XoGWU3jwQ1S7RbZGbzuB3CMAcoBphljaDIFoxb52sJrk+NaHRT/oaXPWW7n7g x/CpEfou4iJFInI9tET01vi//opGo1GY4YnQkceFSeL5rUnKUMfnpNeJtEqlD1KfPbtvi+ExTE YZ7QpYGs1yymUH/OomExxi7ET19EUfJ8/o+YbMNk8M4GbZBt+Va7k8uk2yFcE45mXar3ySh7EM o2JKIVnOpuWk9T3cjzvl9We5OtaHPXYyZoiKiCT6c/EDl4kM8Jez5AsaV3uOmnUoly54z2AnzF iow= X-IPAS-Result: =?us-ascii?q?A2DsBwB1Malg/yFRiNlagRKBToMiVmuIfIRQhkyCHzsBm?= =?us-ascii?q?nSBfAsBAQEBAQEBAQEJNQkBAgQBAYRQggEmNgcOAgQBAQEBAwIDAQEBAQUBA?= =?us-ascii?q?QYBAQEBAQEFBAGBA4UvOQ2COCKEGAsBIyNPgRwBglYBgwsLqh8zgQGDSwGBG?= =?us-ascii?q?INfgT4GgTqIdoRuN4FVRIEVhkEDARiHQASCQAYBARUXED4TCx8CBIEcFIERk?= =?us-ascii?q?SYEi3eeLiwHgxqBJgYLiFOTPhQppUsBoU2TJ1WENoFbA4IKbVMNEYJLUBkOj?= =?us-ascii?q?isWFYhNhUkDQi84AgYKAQEDCVcBIgGITgEB?= IronPort-PHdr: A9a23:azJXMBGH7WjzTLBviJv2zZ1Gf6RMhN3EVzX9CrIZgr5DOp6u447ld BSGo6k03RmTAtiQu6oMotGVmpioYXYH75eFvSJKW713fDhBt/8rmRc9CtWOE0zxIa2iRSU7G MNfSA0tpCnjYgBaF8nkelLdvGC54yIMFRXjLwp1Ifn+FpLPg8it2O2+5pnebx9WiDe/Yb5+I xa7oRnMvcQKnIVuLbo8xAHUqXVSYeRWwm1oJVOXnxni48q74YBu/SdNtf8/7sBMSar1cbg2Q rxeFzQmLns65Nb3uhnZTAuA/WUTX2MLmRdVGQfF7RX6XpDssivms+d2xSeXMdHqQb0yRD+v6 bpgRh31hycdLzM38H/ZhNF+gqxYpxyuqBNxzpXIbIyWLvdyYrnQcc8GSWdHQ81fVzZBAoS5b 4YXFeQBPedYr438p1sWtRuxGxSnC+P1xT9SgX/2xLA60+U/HgHcxwwrAtUDsGzUrNX0MKcSU Pi1zLHWwjnZYfJZwy396I/RchA8oPGDQ6hwcdHKxEk0FAPEjlOQppL5Pz+PzesCrXGW4ux9X u2gl2ApsRt+oiSzxsgykInJgJoYx1HY+Ct33Yo4O922RVB1bNK5HpVdtT2XOoV1T80iTG9mt zg3x7MHtJOnfiUHx5QqyhrCZvGHbYWF4g/vWeeNLDp+mXlrdrW/hxOo/kihzO3xTtK00FFXr ipfjtbDqH4M2AbJ6seZUPd9+V2h2TmJ2gvO6e9EOVg5mbTGJ5Mj2LI8i5QevEXZEiL1hUn6l qGbe0si9+O18eroeK/mqYWZN4JsjwH+NbkhldKnDOQjNwgOQ3Cb+eOh1L3/5UH5QKtFjvkxk qTBtZDVON4Xpq6+Aw9QzIkv8xe/DzG439QEhXQLMk9JdRCdg4T0NVzDIer0APSij1i2njpmy ejKPrj7DZXMKnjDnq3hfbF460NE0AozzdFf55ZVCrEZOPL8RFX9tdLCAR8jNAy02vvnCNRj2 YMEQmKCGbSZMKDSsF+O+O0vP/OAa5QLtzrlMfgq++bujWMlmV8aZaSp0oYYZ2uhEvR+OUqZf WbjgtcfHmcRpQc+V+vqiECYUTFPeXmzUbgz5islB468CofDXI+tiqSb3CinBp1WenxGCleUH Hfwd4WEWvMMaCOKIs95jDMIT7agRJU71RGprQ/61rtnIfTO+i0Drp/jz9t15u3VlR4s6Tx4F d+S3H/eB11zy2wETXou1bx0oUFm4kyEzLJzjuNRD9EV4OlGASkgMpuJ9+x7D9HqQg+JQd6TT 0+7Q9i8GnllVtIwx94We0s7BNy4iQne3iewGJcOlK2NCYBy+K+KjCu5HNp013uTjPpptFIhW MYabQWb IronPort-Data: A9a23:6dDTMaAj/T62rhVW/5Phw5YqxClBgxIJ4kV8jS/XYbTApDskhmBSz DAeUW+EOf3bZDf9e4wiYdy0p0wG7cTUyYRlOVdlrnsFo1CmCSbm6XV1Cm+qYkt+++WaFBoPA /3z6bAsFehsJpPmjk7F3oPJ8D8sj8lkepKmULSdYn0rHFc9IMscoUsLd9AR09YAbeeRXlvlV ePa+6Uz73f8hlaYmkpNg06ygEsHUMba4Vv0jXRiDRx/h2IyolFOZH4pyQ5dGFOjKmVcNrbSq +8uV9hV9EuBl/smIovNfroW7iTmT5aKVTVihEa6VICJsgN9pCcA6pwld/kZTm1LhCmMtvBun YAlWZyYEW/FP4XJlKIdVBxVe818Ffcfp/meeib54ZXVlBaun3jEmp2CCGkuPYwc+/5vDCdR/ OYfMS0MYwqYr/m10bS2Vq9mi6zPKeGyZNJD4is/k2yx4fAOcLroeYbF5Nlj7ghhl5hNJvD6N +dJUG86BPjHS1gVUrsNM7oxkO3tnnDjeD1Vs3qOorct6GXMxRZ8lr/3P7L9YtyLQcRNhkveu Wvc+H3kAxwAL/SEyiuD/27qjOKnoM/gcNlJUu3hs6cx3hjJnzNVARENUR63sP//i1WmHdhSL 0Md8S0r66I/nKC2cuTAs9SDiCbslnYhtxB4SoXWNCnlJmHoD8p1y4TKovOtqDDriSPueQEX6 w== IronPort-HdrOrdr: A9a23:76Og56rhPOEMSf/5HwDqxn4aV5o8eYIsimQD101hICG9E/bo8v xG+c5x6faaslgssR0b9OxoW5PwI080l6Qe3WB5B97LYOCBggqVxepZgrcKrQeNJ8X5ntQttp uJd8BFaOHNMQ== X-IronPort-Anti-Spam-Filtered: true Received: from 33.81-136-217.adsl-dyn.isp.belgacom.be (HELO md.home) ([217.136.81.33]) by relay.proximus.be with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 May 2021 18:34:37 +0200 From: Philippe Waroquiers To: gdb-patches@sourceware.org Subject: [RFC] Implement 'set|show error-handling abort-execution|print-and-continue|silently-ignore Date: Sat, 22 May 2021 18:34:31 +0200 Message-Id: <20210522163431.10584-1-philippe.waroquiers@skynet.be> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-13.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 22 May 2021 16:34:42 -0000 This is an RFC of an alternative approach to the 'ignore-errors' command proposed by Tom de Vries (see e.g. https://sourceware.org/pipermail/gdb-patches/2021-May/178944.html). FTR, a more elaborate try-catch solution was posted here ( https://sourceware.org/bugzilla/show_bug.cgi?id=8487 ). It is still missing NEWS, documentation and tests. This implements a new setting 'error-handling': (gdb) help set error-handling Set error handling for command sequences. Indicates how GDB handles an error when executing a sequence of commands (such as when sourcing command file or executing a user-defined command). When set to "abort-execution" (the default), GDB reports the error and aborts the execution of the command sequence. When set to "print-and-continue", GDB reports the error and continues the execution of the command sequence. When set to "silently-ignore", GDB silently handles the error and continues the execution of the command sequence. (gdb) Some usage examples: Assuming you define a user command: define problem1 echo coucou\n make-some-error echo bidule\n end (gdb) problem1 coucou Undefined command: "make-some-error". Try "help". (gdb) with error-handling print-and-continue -- problem1 coucou Undefined command: "make-some-error". Try "help". bidule (gdb) with error-handling silently-ignore -- problem1 coucou bidule (gdb) alias S = with error-handling silently-ignore -- (gdb) alias C = with error-handling print-and-continue -- (gdb) S problem1 coucou bidule (gdb) C problem1 coucou Undefined command: "make-some-error". Try "help". bidule (gdb) S source some_command_file_with_errors (gdb) Inside a script, you can control error handling for individual commands, e.g.: (gdb) shell cat runproblem1.gdb echo coucou\n with error-handling print-and-continue -- make-some-error echo bidule\n make-some-other-error echo machin\n (gdb) source runproblem1.gdb coucou Undefined command: "make-some-error". Try "help". bidule runproblem1.gdb:4: Error in sourced command file: Undefined command: "make-some-other-error". Try "help". (gdb) It can also be used to ignore errors or continue on errors in .gdbinit: $ gdb -eiex 'set error-handling print-and-continue' GNU gdb (GDB) 11.0.50.20210522-git ... coucou Undefined command: "make-some-error". Try "help". bidule (gdb) --- gdb/top.c | 247 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 141 insertions(+), 106 deletions(-) diff --git a/gdb/top.c b/gdb/top.c index b9635368cac..2e968ea9b8e 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -142,6 +142,10 @@ show_confirm (struct ui_file *file, int from_tty, value); } +/* How to handle errors when executing a sequence of GDB commands (i.e. a + command not from_tty). */ +static const char *error_handling; + /* Current working directory. */ char *current_directory; @@ -578,113 +582,125 @@ execute_command (const char *p, int from_tty) while (*p == ' ' || *p == '\t') p++; if (*p) - { - const char *cmd = p; - const char *arg; - std::string default_args; - std::string default_args_and_arg; - int was_sync = current_ui->prompt_state == PROMPT_BLOCKED; - - line = p; - - /* If trace-commands is set then this will print this command. */ - print_command_trace ("%s", p); - - c = lookup_cmd (&cmd, cmdlist, "", &default_args, 0, 1); - p = cmd; - - scoped_restore save_repeat_args - = make_scoped_restore (&repeat_arguments, nullptr); - const char *args_pointer = p; - - if (!default_args.empty ()) - { - if (*p != '\0') - default_args_and_arg = default_args + ' ' + p; - else - default_args_and_arg = default_args; - arg = default_args_and_arg.c_str (); - } - else - { - /* Pass null arg rather than an empty one. */ - arg = *p == '\0' ? nullptr : p; - } - - /* FIXME: cagney/2002-02-02: The c->type test is pretty dodgy - while the is_complete_command(cfunc) test is just plain - bogus. They should both be replaced by a test of the form - c->strip_trailing_white_space_p. */ - /* NOTE: cagney/2002-02-02: The function.cfunc in the below - can't be replaced with func. This is because it is the - cfunc, and not the func, that has the value that the - is_complete_command hack is testing for. */ - /* Clear off trailing whitespace, except for set and complete - command. */ - std::string without_whitespace; - if (arg - && c->type != set_cmd - && !is_complete_command (c)) - { - const char *old_end = arg + strlen (arg) - 1; - p = old_end; - while (p >= arg && (*p == ' ' || *p == '\t')) - p--; - if (p != old_end) - { - without_whitespace = std::string (arg, p + 1); - arg = without_whitespace.c_str (); - } - } - - /* If this command has been pre-hooked, run the hook first. */ - execute_cmd_pre_hook (c); - - if (c->deprecated_warn_user) - deprecated_cmd_warning (line, cmdlist); - - /* c->user_commands would be NULL in the case of a python command. */ - if (c->theclass == class_user && c->user_commands) - execute_user_command (c, arg); - else if (c->theclass == class_user - && c->is_prefix () && !c->allow_unknown) - /* If this is a user defined prefix that does not allow unknown - (in other words, C is a prefix command and not a command - that can be followed by its args), report the list of - subcommands. */ - { - std::string prefixname = c->prefixname (); - std::string prefixname_no_space - = prefixname.substr (0, prefixname.length () - 1); - printf_unfiltered - ("\"%s\" must be followed by the name of a subcommand.\n", - prefixname_no_space.c_str ()); - help_list (*c->subcommands, prefixname.c_str (), all_commands, - gdb_stdout); - } - else if (c->type == set_cmd) - do_set_command (arg, from_tty, c); - else if (c->type == show_cmd) - do_show_command (arg, from_tty, c); - else if (c->is_command_class_help ()) - error (_("That is not a command, just a help topic.")); - else if (deprecated_call_command_hook) - deprecated_call_command_hook (c, arg, from_tty); - else - cmd_func (c, arg, from_tty); - - maybe_wait_sync_command_done (was_sync); - - /* If this command has been post-hooked, run the hook last. */ - execute_cmd_post_hook (c); + try + { + const char *cmd = p; + const char *arg; + std::string default_args; + std::string default_args_and_arg; + int was_sync = current_ui->prompt_state == PROMPT_BLOCKED; + + line = p; + + /* If trace-commands is set then this will print this command. */ + print_command_trace ("%s", p); + + c = lookup_cmd (&cmd, cmdlist, "", &default_args, 0, 1); + p = cmd; + + scoped_restore save_repeat_args + = make_scoped_restore (&repeat_arguments, nullptr); + const char *args_pointer = p; + + if (!default_args.empty ()) + { + if (*p != '\0') + default_args_and_arg = default_args + ' ' + p; + else + default_args_and_arg = default_args; + arg = default_args_and_arg.c_str (); + } + else + { + /* Pass null arg rather than an empty one. */ + arg = *p == '\0' ? nullptr : p; + } + + /* FIXME: cagney/2002-02-02: The c->type test is pretty dodgy + while the is_complete_command(cfunc) test is just plain + bogus. They should both be replaced by a test of the form + c->strip_trailing_white_space_p. */ + /* NOTE: cagney/2002-02-02: The function.cfunc in the below + can't be replaced with func. This is because it is the + cfunc, and not the func, that has the value that the + is_complete_command hack is testing for. */ + /* Clear off trailing whitespace, except for set and complete + command. */ + std::string without_whitespace; + if (arg + && c->type != set_cmd + && !is_complete_command (c)) + { + const char *old_end = arg + strlen (arg) - 1; + p = old_end; + while (p >= arg && (*p == ' ' || *p == '\t')) + p--; + if (p != old_end) + { + without_whitespace = std::string (arg, p + 1); + arg = without_whitespace.c_str (); + } + } + + /* If this command has been pre-hooked, run the hook first. */ + execute_cmd_pre_hook (c); + + if (c->deprecated_warn_user) + deprecated_cmd_warning (line, cmdlist); + + /* c->user_commands would be NULL in the case of a python command. */ + if (c->theclass == class_user && c->user_commands) + execute_user_command (c, arg); + else if (c->theclass == class_user + && c->is_prefix () && !c->allow_unknown) + /* If this is a user defined prefix that does not allow unknown + (in other words, C is a prefix command and not a command + that can be followed by its args), report the list of + subcommands. */ + { + std::string prefixname = c->prefixname (); + std::string prefixname_no_space + = prefixname.substr (0, prefixname.length () - 1); + printf_unfiltered + ("\"%s\" must be followed by the name of a subcommand.\n", + prefixname_no_space.c_str ()); + help_list (*c->subcommands, prefixname.c_str (), all_commands, + gdb_stdout); + } + else if (c->type == set_cmd) + do_set_command (arg, from_tty, c); + else if (c->type == show_cmd) + do_show_command (arg, from_tty, c); + else if (c->is_command_class_help ()) + error (_("That is not a command, just a help topic.")); + else if (deprecated_call_command_hook) + deprecated_call_command_hook (c, arg, from_tty); + else + cmd_func (c, arg, from_tty); + + maybe_wait_sync_command_done (was_sync); + + /* If this command has been post-hooked, run the hook last. */ + execute_cmd_post_hook (c); + + if (repeat_arguments != NULL && cmd_start == saved_command_line) + { + gdb_assert (strlen (args_pointer) >= strlen (repeat_arguments)); + strcpy (saved_command_line + (args_pointer - cmd_start), + repeat_arguments); + } + } + catch (const gdb_exception &ex) + { + if (from_tty || strcmp (error_handling, "abort-execution") == 0) + throw; + else if (strcmp (error_handling, "print-and-continue") == 0) + exception_print (gdb_stderr, ex); + /* else silently-ignore. */ - if (repeat_arguments != NULL && cmd_start == saved_command_line) - { - gdb_assert (strlen (args_pointer) >= strlen (repeat_arguments)); - strcpy (saved_command_line + (args_pointer - cmd_start), - repeat_arguments); - } - } + /* See also execute_gdb_command. */ + async_enable_stdin (); + } /* Only perform the frame-language-change check if the command we just finished executing did not resume the inferior's execution. @@ -2203,6 +2219,9 @@ init_gdb_version_vars (void) static void init_main (void) { + static const char *const error_handling_names[] + = { "abort-execution", "print-and-continue", "silently-ignore", NULL }; + struct cmd_list_element *c; /* Initialize the prompt to a simple "(gdb) " prompt or to whatever @@ -2356,6 +2375,22 @@ affect future GDB sessions."), show_startup_quiet, &setlist, &showlist); + add_setshow_enum_cmd ("error-handling", class_support, error_handling_names, + &error_handling, + _("Set error handling for command sequences."), + _("Show error handling for command sequences."), + _("Indicates how GDB handles an error when executing a sequence of commands\n\ +(such as when sourcing command file or executing a user-defined command).\n\ +When set to \"abort-execution\" (the default), GDB reports the error and aborts\n\ +the execution of the command sequence. When set to \"print-and-continue\",\n\ +GDB reports the error and continues the execution of the command sequence.\n\ +When set to \"silently-ignore\", GDB silently handles the error and continues\n\ +the execution of the command sequence."), + NULL, + NULL, + &setlist, &showlist); + error_handling = "abort-execution"; + c = add_cmd ("new-ui", class_support, new_ui_command, _("\ Create a new UI.\n\ Usage: new-ui INTERPRETER TTY\n\ -- 2.20.1