From patchwork Wed May 3 22:46:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 20264 Received: (qmail 54232 invoked by alias); 3 May 2017 22:46:56 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 53478 invoked by uid 89); 3 May 2017 22:46:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: gproxy4.mail.unifiedlayer.com Received: from gproxy4-pub.mail.unifiedlayer.com (HELO gproxy4.mail.unifiedlayer.com) (69.89.23.142) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 03 May 2017 22:46:40 +0000 Received: from cmgw3 (unknown [10.0.90.84]) by gproxy4.mail.unifiedlayer.com (Postfix) with ESMTP id 33D60175A73 for ; Wed, 3 May 2017 16:46:41 -0600 (MDT) Received: from box522.bluehost.com ([74.220.219.122]) by cmgw3 with id Fyme1v0082f2jeq01ymhMD; Wed, 03 May 2017 16:46:41 -0600 X-Authority-Analysis: v=2.2 cv=VKStp5HX c=1 sm=1 tr=0 a=GsOEXm/OWkKvwdLVJsfwcA==:117 a=GsOEXm/OWkKvwdLVJsfwcA==:17 a=tJ8p9aeEuA8A:10 a=zstS-IiYAAAA:8 a=rk-UOlt6Rn7K1ws558kA:9 a=tIzgP8nG6oXZrBQg:21 a=qadNI8pP3n2CV1Hn:21 a=4G6NA9xxw8l3yy4pmD5M:22 Received: from 75-166-63-71.hlrn.qwest.net ([75.166.63.71]:53090 helo=bapiya.Home) by box522.bluehost.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.87) (envelope-from ) id 1d632b-00051x-Qu; Wed, 03 May 2017 16:46:38 -0600 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [RFA 22/23] Make gdb_buildargv return a unique pointer Date: Wed, 3 May 2017 16:46:25 -0600 Message-Id: <20170503224626.2818-23-tom@tromey.com> In-Reply-To: <20170503224626.2818-1-tom@tromey.com> References: <20170503224626.2818-1-tom@tromey.com> X-BWhitelist: no X-Exim-ID: 1d632b-00051x-Qu X-Source-Sender: 75-166-63-71.hlrn.qwest.net (bapiya.Home) [75.166.63.71]:53090 X-Source-Auth: tom+tromey.com X-Email-Count: 29 X-Source-Cap: ZWx5bnJvYmk7ZWx5bnJvYmk7Ym94NTIyLmJsdWVob3N0LmNvbQ== This introduces gdb_argv_up, a unique pointer wrapping an "argv" pointer; that is, a pointer to a NULL-terminated array of char*, where both the array and each non-NULL element in the array are xmalloc'd. This patch then changes gdb_buildargv to return a gdb_argv_up and fixes all the users. It also changes skip.c to use gdb_buildargv (previously it was the only direct caller of buildargv, other than gdb_buildargv itself). One future change that might make sense would be to add begin and end functions, so that an argv could be iterated over. I didn't look into this too much; and perhaps replacing some uses with std::vector would be even better. 2017-05-02 Tom Tromey * utils.h (struct gdb_argv_deleter): New. (gdb_argv_up): New typedef. (gdb_buildargv): Change return type. * utils.c (gdb_buildargv): Return gdb_argv_up. * tracepoint.c (delete_trace_variable_command): Update. * tracefile.c (tsave_command): Update. * top.c (new_ui_command): Update. * symmisc.c (maintenance_print_symbols) (maintenance_print_msymbols, maintenance_expand_symtabs): Update. * symfile.c (symbol_file_command, generic_load) (remove_symbol_file_command): Update. * stack.c (backtrace_command): Update. * source.c (add_path, show_substitute_path_command) (unset_substitute_path_command, set_substitute_path_command): Update. * skip.c (skip_command): Update. Use gdb_buildargv. * ser-mingw.c (pipe_windows_open): Update. * remote.c (extended_remote_run, remote_put_command) (remote_get_command, remote_delete_command): Update. * remote-sim.c (gdbsim_load, gdbsim_create_inferior) (gdbsim_open): Update. * python/py-cmd.c (gdbpy_string_to_argv): Update. * psymtab.c (maintenance_print_psymbols): Update. * procfs.c (procfs_info_proc): Update. * interps.c (interpreter_exec_cmd): Update. * infrun.c (handle_command): Update. * inferior.c (add_inferior_command, clone_inferior_command): Update. * guile/scm-string.c (gdbscm_string_to_argv): Update. * exec.c (exec_file_command): Update. * compile/compile.c (build_argc_argv): Update. * cli/cli-cmds.c (alias_command): Update. --- gdb/ChangeLog | 35 +++++++++++++++++++++++++++++++++++ gdb/cli/cli-cmds.c | 31 +++++++++++++------------------ gdb/compile/compile.c | 2 +- gdb/exec.c | 14 ++++---------- gdb/guile/scm-string.c | 4 +--- gdb/inferior.c | 26 ++++++++------------------ gdb/infrun.c | 8 ++------ gdb/interps.c | 13 ++----------- gdb/procfs.c | 5 +++-- gdb/psymtab.c | 5 ++--- gdb/python/py-cmd.c | 9 ++------- gdb/remote-sim.c | 10 +++++----- gdb/remote.c | 30 ++++-------------------------- gdb/ser-mingw.c | 2 +- gdb/skip.c | 8 +------- gdb/source.c | 28 ++++++---------------------- gdb/stack.c | 2 +- gdb/symfile.c | 22 ++++++++-------------- gdb/symmisc.c | 17 +++++------------ gdb/top.c | 10 ++-------- gdb/tracefile.c | 6 +++--- gdb/tracepoint.c | 7 +------ gdb/utils.c | 4 ++-- gdb/utils.h | 19 ++++++++++++++++++- 24 files changed, 130 insertions(+), 187 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 286d414..4dc3bb4 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,40 @@ 2017-05-02 Tom Tromey + * utils.h (struct gdb_argv_deleter): New. + (gdb_argv_up): New typedef. + (gdb_buildargv): Change return type. + * utils.c (gdb_buildargv): Return gdb_argv_up. + * tracepoint.c (delete_trace_variable_command): Update. + * tracefile.c (tsave_command): Update. + * top.c (new_ui_command): Update. + * symmisc.c (maintenance_print_symbols) + (maintenance_print_msymbols, maintenance_expand_symtabs): Update. + * symfile.c (symbol_file_command, generic_load) + (remove_symbol_file_command): Update. + * stack.c (backtrace_command): Update. + * source.c (add_path, show_substitute_path_command) + (unset_substitute_path_command, set_substitute_path_command): + Update. + * skip.c (skip_command): Update. Use gdb_buildargv. + * ser-mingw.c (pipe_windows_open): Update. + * remote.c (extended_remote_run, remote_put_command) + (remote_get_command, remote_delete_command): Update. + * remote-sim.c (gdbsim_load, gdbsim_create_inferior) + (gdbsim_open): Update. + * python/py-cmd.c (gdbpy_string_to_argv): Update. + * psymtab.c (maintenance_print_psymbols): Update. + * procfs.c (procfs_info_proc): Update. + * interps.c (interpreter_exec_cmd): Update. + * infrun.c (handle_command): Update. + * inferior.c (add_inferior_command, clone_inferior_command): + Update. + * guile/scm-string.c (gdbscm_string_to_argv): Update. + * exec.c (exec_file_command): Update. + * compile/compile.c (build_argc_argv): Update. + * cli/cli-cmds.c (alias_command): Update. + +2017-05-02 Tom Tromey + * python/python.c (gdbpy_decode_line): Use unique_xmalloc_ptr. 2017-05-02 Tom Tromey diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c index 3dc8b9c..5ba0922 100644 --- a/gdb/cli/cli-cmds.c +++ b/gdb/cli/cli-cmds.c @@ -1403,31 +1403,27 @@ alias_command (char *args, int from_tty) { int i, alias_argc, command_argc; int abbrev_flag = 0; - char *args2, *equals; + char *equals; const char *alias, *command; - char **alias_argv, **command_argv; - struct cleanup *cleanup; if (args == NULL || strchr (args, '=') == NULL) alias_usage_error (); - args2 = xstrdup (args); - cleanup = make_cleanup (xfree, args2); - equals = strchr (args2, '='); - *equals = '\0'; - alias_argv = gdb_buildargv (args2); - make_cleanup_freeargv (alias_argv); - command_argv = gdb_buildargv (equals + 1); - make_cleanup_freeargv (command_argv); + equals = strchr (args, '='); + std::string args2 (args, equals - args); + + gdb_argv_up built_alias_argv = gdb_buildargv (args2.c_str ()); + gdb_argv_up command_argv = gdb_buildargv (equals + 1); - for (i = 0; alias_argv[i] != NULL; ) + char **alias_argv = built_alias_argv.get (); + while (alias_argv[0] != NULL) { - if (strcmp (alias_argv[i], "-a") == 0) + if (strcmp (alias_argv[0], "-a") == 0) { ++alias_argv; abbrev_flag = 1; } - else if (strcmp (alias_argv[i], "--") == 0) + else if (strcmp (alias_argv[0], "--") == 0) { ++alias_argv; break; @@ -1452,12 +1448,13 @@ alias_command (char *args, int from_tty) } alias_argc = countargv (alias_argv); - command_argc = countargv (command_argv); + command_argc = countargv (command_argv.get ()); /* COMMAND must exist. Reconstruct the command to remove any extraneous spaces, for better error messages. */ - std::string command_string (argv_to_string (command_argv, command_argc)); + std::string command_string (argv_to_string (command_argv.get (), + command_argc)); command = command_string.c_str (); if (! valid_command_p (command)) error (_("Invalid command to alias to: %s"), command); @@ -1514,8 +1511,6 @@ alias_command (char *args, int from_tty) command_argv[command_argc - 1], class_alias, abbrev_flag, c_command->prefixlist); } - - do_cleanups (cleanup); } /* Print a list of files and line numbers which a user may choose from diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c index 5269aaf..4994219 100644 --- a/gdb/compile/compile.c +++ b/gdb/compile/compile.c @@ -292,7 +292,7 @@ get_expr_block_and_pc (CORE_ADDR *pc) static void build_argc_argv (const char *s, int *argcp, char ***argvp) { - *argvp = gdb_buildargv (s); + *argvp = gdb_buildargv (s).release (); *argcp = countargv (*argvp); } diff --git a/gdb/exec.c b/gdb/exec.c index 2c9a74b..8fba0a1 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -410,7 +410,6 @@ exec_file_attach (const char *filename, int from_tty) static void exec_file_command (char *args, int from_tty) { - char **argv; char *filename; if (from_tty && target_has_execution @@ -420,13 +419,11 @@ exec_file_command (char *args, int from_tty) if (args) { - struct cleanup *cleanups; - /* Scan through the args and pick up the first non option arg as the filename. */ - argv = gdb_buildargv (args); - cleanups = make_cleanup_freeargv (argv); + gdb_argv_up built_argv = gdb_buildargv (args); + char **argv = built_argv.get (); for (; (*argv != NULL) && (**argv == '-'); argv++) {; @@ -434,11 +431,8 @@ exec_file_command (char *args, int from_tty) if (*argv == NULL) error (_("No executable file name was specified")); - filename = tilde_expand (*argv); - make_cleanup (xfree, filename); - exec_file_attach (filename, from_tty); - - do_cleanups (cleanups); + gdb::unique_xmalloc_ptr filename (tilde_expand (*argv)); + exec_file_attach (filename.get (), from_tty); } else exec_file_attach (NULL, from_tty); diff --git a/gdb/guile/scm-string.c b/gdb/guile/scm-string.c index d97f583..c6432c1 100644 --- a/gdb/guile/scm-string.c +++ b/gdb/guile/scm-string.c @@ -241,7 +241,6 @@ static SCM gdbscm_string_to_argv (SCM string_scm) { char *string; - char **c_argv; int i; SCM result = SCM_EOL; @@ -254,11 +253,10 @@ gdbscm_string_to_argv (SCM string_scm) return SCM_EOL; } - c_argv = gdb_buildargv (string); + gdb_argv_up c_argv = gdb_buildargv (string); for (i = 0; c_argv[i] != NULL; ++i) result = scm_cons (gdbscm_scm_from_c_string (c_argv[i]), result); - freeargv (c_argv); xfree (string); return scm_reverse_x (result, SCM_EOL); diff --git a/gdb/inferior.c b/gdb/inferior.c index 002296f..1b467884 100644 --- a/gdb/inferior.c +++ b/gdb/inferior.c @@ -820,20 +820,17 @@ static void add_inferior_command (char *args, int from_tty) { int i, copies = 1; - char *exec = NULL; - char **argv; + gdb::unique_xmalloc_ptr exec; symfile_add_flags add_flags = 0; - struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); if (from_tty) add_flags |= SYMFILE_VERBOSE; if (args) { - argv = gdb_buildargv (args); - make_cleanup_freeargv (argv); + gdb_argv_up built_argv = gdb_buildargv (args); - for (; *argv != NULL; argv++) + for (char **argv = built_argv.get (); *argv != NULL; argv++) { if (**argv == '-') { @@ -849,8 +846,7 @@ add_inferior_command (char *args, int from_tty) ++argv; if (!*argv) error (_("No argument to -exec")); - exec = tilde_expand (*argv); - make_cleanup (xfree, exec); + exec.reset (tilde_expand (*argv)); } } else @@ -874,12 +870,10 @@ add_inferior_command (char *args, int from_tty) set_current_inferior (inf); switch_to_thread (null_ptid); - exec_file_attach (exec, from_tty); - symbol_file_add_main (exec, add_flags); + exec_file_attach (exec.get (), from_tty); + symbol_file_add_main (exec.get (), add_flags); } } - - do_cleanups (old_chain); } /* clone-inferior [-copies N] [ID] */ @@ -888,15 +882,13 @@ static void clone_inferior_command (char *args, int from_tty) { int i, copies = 1; - char **argv; struct inferior *orginf = NULL; - struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); if (args) { - argv = gdb_buildargv (args); - make_cleanup_freeargv (argv); + gdb_argv_up built_argv = gdb_buildargv (args); + char **argv = built_argv.get (); for (; *argv != NULL; argv++) { if (**argv == '-') @@ -967,8 +959,6 @@ clone_inferior_command (char *args, int from_tty) switch_to_thread (null_ptid); clone_program_space (pspace, orginf->pspace); } - - do_cleanups (old_chain); } /* Print notices when new inferiors are created and die. */ diff --git a/gdb/infrun.c b/gdb/infrun.c index fcafdc1..03aad38 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -8506,14 +8506,12 @@ sig_print_info (enum gdb_signal oursig) static void handle_command (char *args, int from_tty) { - char **argv; int digits, wordlen; int sigfirst, signum, siglast; enum gdb_signal oursig; int allsigs; int nsigs; unsigned char *sigs; - struct cleanup *old_chain; if (args == NULL) { @@ -8528,8 +8526,8 @@ handle_command (char *args, int from_tty) /* Break the command line up into args. */ - argv = gdb_buildargv (args); - old_chain = make_cleanup_freeargv (argv); + gdb_argv_up built_argv = gdb_buildargv (args); + char **argv = built_argv.get (); /* Walk through the args, looking for signal oursigs, signal names, and actions. Signal numbers and signal names may be interspersed with @@ -8680,8 +8678,6 @@ Are you sure you want to change it? "), break; } - - do_cleanups (old_chain); } /* Complete the "handle" command. */ diff --git a/gdb/interps.c b/gdb/interps.c index af86390..0512b38 100644 --- a/gdb/interps.c +++ b/gdb/interps.c @@ -407,21 +407,14 @@ interpreter_exec_cmd (char *args, int from_tty) { struct ui_interp_info *ui_interp = get_current_interp_info (); struct interp *old_interp, *interp_to_use; - char **prules = NULL; - char **trule = NULL; unsigned int nrules; unsigned int i; - struct cleanup *cleanup; if (args == NULL) error_no_arg (_("interpreter-exec command")); - prules = gdb_buildargv (args); - cleanup = make_cleanup_freeargv (prules); - - nrules = 0; - for (trule = prules; *trule != NULL; trule++) - nrules++; + gdb_argv_up prules = gdb_buildargv (args); + nrules = countargv (prules.get ()); if (nrules < 2) error (_("usage: interpreter-exec [ ... ]")); @@ -446,8 +439,6 @@ interpreter_exec_cmd (char *args, int from_tty) } interp_set (old_interp, 0); - - do_cleanups (cleanup); } /* See interps.h. */ diff --git a/gdb/procfs.c b/gdb/procfs.c index 2aaee07..fa4fa1a 100644 --- a/gdb/procfs.c +++ b/gdb/procfs.c @@ -5108,10 +5108,11 @@ procfs_info_proc (struct target_ops *ops, const char *args, } old_chain = make_cleanup (null_cleanup, 0); + gdb_argv_up built_argv; if (args) { - argv = gdb_buildargv (args); - make_cleanup_freeargv (argv); + built_argv.reset (gdb_buildargv (args)); + argv = built_argv.get (); } while (argv != NULL && *argv != NULL) { diff --git a/gdb/psymtab.c b/gdb/psymtab.c index bb482ee..a85e512 100644 --- a/gdb/psymtab.c +++ b/gdb/psymtab.c @@ -1905,7 +1905,6 @@ dump_psymtab_addrmap (struct objfile *objfile, struct partial_symtab *psymtab, static void maintenance_print_psymbols (char *args, int from_tty) { - char **argv; struct ui_file *outfile = gdb_stdout; struct cleanup *cleanups; char *address_arg = NULL, *source_arg = NULL, *objfile_arg = NULL; @@ -1917,8 +1916,8 @@ maintenance_print_psymbols (char *args, int from_tty) dont_repeat (); - argv = gdb_buildargv (args); - cleanups = make_cleanup_freeargv (argv); + gdb_argv_up argv = gdb_buildargv (args); + cleanups = make_cleanup (null_cleanup, NULL); for (i = 0; argv != NULL && argv[i] != NULL; ++i) { diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c index 6203211..7bd25b4 100644 --- a/gdb/python/py-cmd.c +++ b/gdb/python/py-cmd.c @@ -763,7 +763,7 @@ gdbpy_string_to_argv (PyObject *self, PyObject *args) if (*input != '\0') { - char **c_argv = gdb_buildargv (input); + gdb_argv_up c_argv = gdb_buildargv (input); int i; for (i = 0; c_argv[i] != NULL; ++i) @@ -772,13 +772,8 @@ gdbpy_string_to_argv (PyObject *self, PyObject *args) if (argp == NULL || PyList_Append (py_argv.get (), argp.get ()) < 0) - { - freeargv (c_argv); - return NULL; - } + return NULL; } - - freeargv (c_argv); } return py_argv.release (); diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c index fd1bc66..e932e87 100644 --- a/gdb/remote-sim.c +++ b/gdb/remote-sim.c @@ -574,8 +574,7 @@ gdbsim_load (struct target_ops *self, const char *args, int fromtty) if (args == NULL) error_no_arg (_("program to load")); - argv = gdb_buildargv (args); - make_cleanup_freeargv (argv); + gdb_argv_up argv = gdb_buildargv (args); prog = tilde_expand (argv[0]); @@ -632,6 +631,7 @@ gdbsim_create_inferior (struct target_ops *target, const char *exec_file, remove_breakpoints (); init_wait_for_inferior (); + gdb_argv_up built_argv; if (exec_file != NULL) { len = strlen (exec_file) + 1 + allargs.size () + 1 + /*slop */ 10; @@ -640,8 +640,8 @@ gdbsim_create_inferior (struct target_ops *target, const char *exec_file, strcat (arg_buf, exec_file); strcat (arg_buf, " "); strcat (arg_buf, args); - argv = gdb_buildargv (arg_buf); - make_cleanup_freeargv (argv); + built_argv.reset (gdb_buildargv (arg_buf)); + argv = built_argv.get (); } else argv = NULL; @@ -732,7 +732,7 @@ gdbsim_open (const char *args, int from_tty) strcat (arg_buf, " "); /* 1 */ strcat (arg_buf, args); } - sim_argv = gdb_buildargv (arg_buf); + sim_argv = gdb_buildargv (arg_buf).release (); init_callbacks (); gdbsim_desc = sim_open (SIM_OPEN_DEBUG, &gdb_callback, exec_bfd, sim_argv); diff --git a/gdb/remote.c b/gdb/remote.c index ecd0ce0..a699387 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -9525,12 +9525,9 @@ extended_remote_run (const std::string &args) if (!args.empty ()) { - struct cleanup *back_to; int i; - char **argv; - argv = gdb_buildargv (args.c_str ()); - back_to = make_cleanup_freeargv (argv); + gdb_argv_up argv = gdb_buildargv (args.c_str ()); for (i = 0; argv[i] != NULL; i++) { if (strlen (argv[i]) * 2 + 1 + len >= get_remote_packet_size ()) @@ -9539,7 +9536,6 @@ extended_remote_run (const std::string &args) len += 2 * bin2hex ((gdb_byte *) argv[i], rs->buf + len, strlen (argv[i])); } - do_cleanups (back_to); } rs->buf[len++] = '\0'; @@ -12035,58 +12031,40 @@ remote_file_delete (const char *remote_file, int from_tty) static void remote_put_command (char *args, int from_tty) { - struct cleanup *back_to; - char **argv; - if (args == NULL) error_no_arg (_("file to put")); - argv = gdb_buildargv (args); - back_to = make_cleanup_freeargv (argv); + gdb_argv_up argv = gdb_buildargv (args); if (argv[0] == NULL || argv[1] == NULL || argv[2] != NULL) error (_("Invalid parameters to remote put")); remote_file_put (argv[0], argv[1], from_tty); - - do_cleanups (back_to); } static void remote_get_command (char *args, int from_tty) { - struct cleanup *back_to; - char **argv; - if (args == NULL) error_no_arg (_("file to get")); - argv = gdb_buildargv (args); - back_to = make_cleanup_freeargv (argv); + gdb_argv_up argv = gdb_buildargv (args); if (argv[0] == NULL || argv[1] == NULL || argv[2] != NULL) error (_("Invalid parameters to remote get")); remote_file_get (argv[0], argv[1], from_tty); - - do_cleanups (back_to); } static void remote_delete_command (char *args, int from_tty) { - struct cleanup *back_to; - char **argv; - if (args == NULL) error_no_arg (_("file to delete")); - argv = gdb_buildargv (args); - back_to = make_cleanup_freeargv (argv); + gdb_argv_up argv = gdb_buildargv (args); if (argv[0] == NULL || argv[1] != NULL) error (_("Invalid parameters to remote delete")); remote_file_delete (argv[0], from_tty); - - do_cleanups (back_to); } static void diff --git a/gdb/ser-mingw.c b/gdb/ser-mingw.c index 3f12458..429f89f 100644 --- a/gdb/ser-mingw.c +++ b/gdb/ser-mingw.c @@ -869,7 +869,7 @@ pipe_windows_open (struct serial *scb, const char *name) if (name == NULL) error_no_arg (_("child command")); - argv = gdb_buildargv (name); + argv = gdb_buildargv (name).release (); back_to = make_cleanup_freeargv (argv); if (! argv[0] || argv[0][0] == '\0') diff --git a/gdb/skip.c b/gdb/skip.c index 33ed8d8..b830c6f 100644 --- a/gdb/skip.c +++ b/gdb/skip.c @@ -231,8 +231,6 @@ skip_command (char *arg, int from_tty) const char *gfile = NULL; const char *function = NULL; const char *rfunction = NULL; - char **argv; - struct cleanup *cleanups; struct skiplist_entry *e; int i; @@ -242,8 +240,7 @@ skip_command (char *arg, int from_tty) return; } - argv = buildargv (arg); - cleanups = make_cleanup_freeargv (argv); + gdb_argv_up argv = gdb_buildargv (arg); for (i = 0; argv[i] != NULL; ++i) { @@ -290,7 +287,6 @@ skip_command (char *arg, int from_tty) FUNCTION-NAME may be `foo (int)', and therefore we pass the complete original arg to skip_function command as if the user typed "skip function arg". */ - do_cleanups (cleanups); skip_function_command (arg, from_tty); return; } @@ -350,8 +346,6 @@ skip_command (char *arg, int from_tty) lower_file_text, file_to_print); } } - - do_cleanups (cleanups); } static void diff --git a/gdb/source.c b/gdb/source.c index 3d477ad..7eef86c 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -484,16 +484,14 @@ add_path (char *dirname, char **which_path, int parse_separators) if (parse_separators) { - char **argv, **argvp; + char **argvp; /* This will properly parse the space and tab separators and any quotes that may exist. */ - argv = gdb_buildargv (dirname); + gdb_argv_up argv = gdb_buildargv (dirname); - for (argvp = argv; *argvp; argvp++) + for (argvp = argv.get (); *argvp; argvp++) dirnames_to_char_ptr_vec_append (&dir_vec, *argvp); - - freeargv (argv); } else VEC_safe_push (char_ptr, dir_vec, xstrdup (dirname)); @@ -1882,12 +1880,9 @@ static void show_substitute_path_command (char *args, int from_tty) { struct substitute_path_rule *rule = substitute_path_rules; - char **argv; char *from = NULL; - struct cleanup *cleanup; - argv = gdb_buildargv (args); - cleanup = make_cleanup_freeargv (argv); + gdb_argv_up argv = gdb_buildargv (args); /* We expect zero or one argument. */ @@ -1911,8 +1906,6 @@ show_substitute_path_command (char *args, int from_tty) printf_filtered (" `%s' -> `%s'.\n", rule->from, rule->to); rule = rule->next; } - - do_cleanups (cleanup); } /* Implement the "unset substitute-path" command. */ @@ -1921,14 +1914,12 @@ static void unset_substitute_path_command (char *args, int from_tty) { struct substitute_path_rule *rule = substitute_path_rules; - char **argv = gdb_buildargv (args); + gdb_argv_up argv = gdb_buildargv (args); char *from = NULL; int rule_found = 0; - struct cleanup *cleanup; /* This function takes either 0 or 1 argument. */ - cleanup = make_cleanup_freeargv (argv); if (argv != NULL && argv[0] != NULL && argv[1] != NULL) error (_("Incorrect usage, too many arguments in command")); @@ -1966,8 +1957,6 @@ unset_substitute_path_command (char *args, int from_tty) error (_("No substitution rule defined for `%s'"), from); forget_cached_source_info (); - - do_cleanups (cleanup); } /* Add a new source path substitution rule. */ @@ -1975,12 +1964,9 @@ unset_substitute_path_command (char *args, int from_tty) static void set_substitute_path_command (char *args, int from_tty) { - char **argv; struct substitute_path_rule *rule; - struct cleanup *cleanup; - argv = gdb_buildargv (args); - cleanup = make_cleanup_freeargv (argv); + gdb_argv_up argv = gdb_buildargv (args); if (argv == NULL || argv[0] == NULL || argv [1] == NULL) error (_("Incorrect usage, too few arguments in command")); @@ -2007,8 +1993,6 @@ set_substitute_path_command (char *args, int from_tty) add_substitute_path_rule (argv[0], argv[1]); forget_cached_source_info (); - - do_cleanups (cleanup); } diff --git a/gdb/stack.c b/gdb/stack.c index 7f8a51c..34e8aa5 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -1877,7 +1877,7 @@ backtrace_command (char *arg, int from_tty) char **argv; int i; - argv = gdb_buildargv (arg); + argv = gdb_buildargv (arg).release (); make_cleanup_freeargv (argv); argc = 0; for (i = 0; argv[i]; i++) diff --git a/gdb/symfile.c b/gdb/symfile.c index 846aabe..9482ddc 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -1628,7 +1628,7 @@ symbol_file_command (char *args, int from_tty) } else { - char **argv = gdb_buildargv (args); + char **argv; objfile_flags flags = OBJF_USERLOADED; symfile_add_flags add_flags = 0; struct cleanup *cleanups; @@ -1637,7 +1637,8 @@ symbol_file_command (char *args, int from_tty) if (from_tty) add_flags |= SYMFILE_VERBOSE; - cleanups = make_cleanup_freeargv (argv); + gdb_argv_up built_argv = gdb_buildargv (args); + argv = built_argv.get (); while (*argv != NULL) { if (strcmp (*argv, "-readnow") == 0) @@ -1655,8 +1656,6 @@ symbol_file_command (char *args, int from_tty) if (name == NULL) error (_("no symbol file name was specified")); - - do_cleanups (cleanups); } } @@ -2050,25 +2049,23 @@ void generic_load (const char *args, int from_tty) { char *filename; - struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0); + struct cleanup *old_cleanups; struct load_section_data cbdata; struct load_progress_data total_progress; struct ui_out *uiout = current_uiout; CORE_ADDR entry; - char **argv; memset (&cbdata, 0, sizeof (cbdata)); memset (&total_progress, 0, sizeof (total_progress)); cbdata.progress_data = &total_progress; - make_cleanup (clear_memory_write_data, &cbdata.requests); + old_cleanups = make_cleanup (clear_memory_write_data, &cbdata.requests); if (args == NULL) error_no_arg (_("file to load")); - argv = gdb_buildargv (args); - make_cleanup_freeargv (argv); + gdb_argv_up argv = gdb_buildargv (args); filename = tilde_expand (argv[0]); make_cleanup (xfree, filename); @@ -2216,7 +2213,6 @@ add_symbol_file_command (char *args, int from_tty) int i; int expecting_sec_name = 0; int expecting_sec_addr = 0; - char **argv; struct objfile *objf; objfile_flags flags = OBJF_USERLOADED | OBJF_SHARED; symfile_add_flags add_flags = 0; @@ -2243,8 +2239,7 @@ add_symbol_file_command (char *args, int from_tty) if (args == NULL) error (_("add-symbol-file takes a file name and an address")); - argv = gdb_buildargv (args); - make_cleanup_freeargv (argv); + gdb_argv_up argv = gdb_buildargv (args); for (arg = argv[0], argcnt = 0; arg != NULL; arg = argv[++argcnt]) { @@ -2364,7 +2359,6 @@ add_symbol_file_command (char *args, int from_tty) static void remove_symbol_file_command (char *args, int from_tty) { - char **argv; struct objfile *objf = NULL; struct cleanup *my_cleanups; struct program_space *pspace = current_program_space; @@ -2376,7 +2370,7 @@ remove_symbol_file_command (char *args, int from_tty) my_cleanups = make_cleanup (null_cleanup, NULL); - argv = gdb_buildargv (args); + gdb_argv_up argv = gdb_buildargv (args); if (strcmp (argv[0], "-a") == 0) { diff --git a/gdb/symmisc.c b/gdb/symmisc.c index 32a5331..e3a512e 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -407,7 +407,6 @@ dump_symtab (struct symtab *symtab, struct ui_file *outfile) static void maintenance_print_symbols (char *args, int from_tty) { - char **argv; struct ui_file *outfile = gdb_stdout; struct cleanup *cleanups; char *address_arg = NULL, *source_arg = NULL, *objfile_arg = NULL; @@ -415,8 +414,8 @@ maintenance_print_symbols (char *args, int from_tty) dont_repeat (); - argv = gdb_buildargv (args); - cleanups = make_cleanup_freeargv (argv); + gdb_argv_up argv = gdb_buildargv (args); + cleanups = make_cleanup (null_cleanup, NULL); for (i = 0; argv != NULL && argv[i] != NULL; ++i) { @@ -709,7 +708,6 @@ print_symbol (void *args) static void maintenance_print_msymbols (char *args, int from_tty) { - char **argv; struct ui_file *outfile = gdb_stdout; struct cleanup *cleanups; char *objfile_arg = NULL; @@ -718,8 +716,8 @@ maintenance_print_msymbols (char *args, int from_tty) dont_repeat (); - argv = gdb_buildargv (args); - cleanups = make_cleanup_freeargv (argv); + gdb_argv_up argv = gdb_buildargv (args); + cleanups = make_cleanup (null_cleanup, NULL); for (i = 0; argv != NULL && argv[i] != NULL; ++i) { @@ -944,14 +942,11 @@ maintenance_expand_symtabs (char *args, int from_tty) { struct program_space *pspace; struct objfile *objfile; - struct cleanup *cleanups; - char **argv; char *regexp = NULL; /* We use buildargv here so that we handle spaces in the regexp in a way that allows adding more arguments later. */ - argv = gdb_buildargv (args); - cleanups = make_cleanup_freeargv (argv); + gdb_argv_up argv = gdb_buildargv (args); if (argv != NULL) { @@ -988,8 +983,6 @@ maintenance_expand_symtabs (char *args, int from_tty) ALL_DOMAIN); } } - - do_cleanups (cleanups); } diff --git a/gdb/top.c b/gdb/top.c index 6038366..a51b59f 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -364,17 +364,14 @@ new_ui_command (char *args, int from_tty) int i; int res; int argc; - char **argv; const char *interpreter_name; const char *tty_name; - struct cleanup *success_chain; struct cleanup *failure_chain; dont_repeat (); - argv = gdb_buildargv (args); - success_chain = make_cleanup_freeargv (argv); - argc = countargv (argv); + gdb_argv_up argv = gdb_buildargv (args); + argc = countargv (argv.get ()); if (argc < 2) error (_("usage: new-ui ")); @@ -407,9 +404,6 @@ new_ui_command (char *args, int from_tty) stream[2].release (); discard_cleanups (failure_chain); - - /* This restores the previous UI and frees argv. */ - do_cleanups (success_chain); } printf_unfiltered ("New UI allocated\n"); diff --git a/gdb/tracefile.c b/gdb/tracefile.c index cc90945..2dce0d9 100644 --- a/gdb/tracefile.c +++ b/gdb/tracefile.c @@ -318,8 +318,8 @@ tsave_command (char *args, int from_tty) if (args == NULL) error_no_arg (_("file in which to save trace data")); - argv = gdb_buildargv (args); - back_to = make_cleanup_freeargv (argv); + gdb_argv_up built_argv = gdb_buildargv (args); + argv = built_argv.get (); for (; *argv; ++argv) { @@ -341,7 +341,7 @@ tsave_command (char *args, int from_tty) else writer = tfile_trace_file_writer_new (); - make_cleanup (trace_file_writer_xfree, writer); + back_to = make_cleanup (trace_file_writer_xfree, writer); trace_save (filename, writer, target_does_save); diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index 3a39ebc..f569c86 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -448,8 +448,6 @@ static void delete_trace_variable_command (char *args, int from_tty) { int ix; - char **argv; - struct cleanup *back_to; if (args == NULL) { @@ -460,8 +458,7 @@ delete_trace_variable_command (char *args, int from_tty) return; } - argv = gdb_buildargv (args); - back_to = make_cleanup_freeargv (argv); + gdb_argv_up argv = gdb_buildargv (args); for (ix = 0; argv[ix] != NULL; ix++) { @@ -471,8 +468,6 @@ delete_trace_variable_command (char *args, int from_tty) warning (_("Name \"%s\" not prefixed with '$', ignoring"), argv[ix]); } - do_cleanups (back_to); - dont_repeat (); } diff --git a/gdb/utils.c b/gdb/utils.c index 7d0b5f4..b631ed0 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -2914,14 +2914,14 @@ ldirname (const char *filename) Therefore, the returned value is guaranteed to be non-NULL, unless the parameter itself is NULL. */ -char ** +gdb_argv_up gdb_buildargv (const char *s) { char **argv = buildargv (s); if (s != NULL && argv == NULL) malloc_failure (0); - return argv; + return gdb_argv_up (argv); } int diff --git a/gdb/utils.h b/gdb/utils.h index 8f545c6..dd7c75e7 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -60,7 +60,24 @@ extern int parse_pid_to_attach (const char *args); extern int parse_escape (struct gdbarch *, const char **); -char **gdb_buildargv (const char *); +/* A deleter for an argv array. This is an array where each element, + up to the first NULL, is xmalloc'd, and the array itself is + xmalloc'd. */ +struct gdb_argv_deleter +{ + void operator() (char **argv) const + { + freeargv (argv); + } +}; + +/* A unique pointer to an argv array. */ +typedef std::unique_ptr gdb_argv_up; + +/* A wrapper for libiberty's buildargv that handles memory allocation + failures in the gdb style. */ +gdb_argv_up gdb_buildargv (const char *); + /* Cleanup utilities. */