Fix memory leak in add_symbol_file_command

I happened to notice that add_symbol_file_command leaks "sect_opts".
This patch fixes the leak by changing sect_opts to be a std::vector.

I had to change the logic in the loop a little bit.  Previously, it
was incrementing section_index after completing an entry; but this
changes it to push a new entry when the name is seen.

I believe the argument parsing here is mildly incorrect, in that
nothing checks whether the -s option actually had any arguments.
Maybe gdb can crash if "-s NAME" is given without an argument.  I
didn't try to fix this in this patch, but I do have another patch I
can send later that fixes it up.

Regression tested on the buildbot.

ChangeLog
2017-08-11  Tom Tromey  <tom@tromey.com>

	* symfile.c (add_symbol_file_command): Use std::vector.
This commit is contained in:
Tom Tromey 2017-08-03 17:07:06 -06:00
parent 2f5404b358
commit f978cb06db
2 changed files with 15 additions and 32 deletions

View File

@ -1,3 +1,7 @@
2017-08-11 Tom Tromey <tom@tromey.com>
* symfile.c (add_symbol_file_command): Use std::vector.
2017-08-14 Tom Tromey <tom@tromey.com> 2017-08-14 Tom Tromey <tom@tromey.com>
* break-catch-throw.c (handle_gnu_v3_exceptions): Use std::move. * break-catch-throw.c (handle_gnu_v3_exceptions): Use std::move.

View File

@ -2205,10 +2205,8 @@ add_symbol_file_command (char *args, int from_tty)
struct gdbarch *gdbarch = get_current_arch (); struct gdbarch *gdbarch = get_current_arch ();
gdb::unique_xmalloc_ptr<char> filename; gdb::unique_xmalloc_ptr<char> filename;
char *arg; char *arg;
int section_index = 0;
int argcnt = 0; int argcnt = 0;
int sec_num = 0; int sec_num = 0;
int i;
int expecting_sec_name = 0; int expecting_sec_name = 0;
int expecting_sec_addr = 0; int expecting_sec_addr = 0;
struct objfile *objf; struct objfile *objf;
@ -2225,13 +2223,9 @@ add_symbol_file_command (char *args, int from_tty)
}; };
struct section_addr_info *section_addrs; struct section_addr_info *section_addrs;
struct sect_opt *sect_opts = NULL; std::vector<sect_opt> sect_opts;
size_t num_sect_opts = 0;
struct cleanup *my_cleanups = make_cleanup (null_cleanup, NULL); struct cleanup *my_cleanups = make_cleanup (null_cleanup, NULL);
num_sect_opts = 16;
sect_opts = XNEWVEC (struct sect_opt, num_sect_opts);
dont_repeat (); dont_repeat ();
if (args == NULL) if (args == NULL)
@ -2251,16 +2245,8 @@ add_symbol_file_command (char *args, int from_tty)
{ {
/* The second argument is always the text address at which /* The second argument is always the text address at which
to load the program. */ to load the program. */
sect_opts[section_index].name = ".text"; sect_opt sect = { ".text", arg };
sect_opts[section_index].value = arg; sect_opts.push_back (sect);
if (++section_index >= num_sect_opts)
{
num_sect_opts *= 2;
sect_opts = ((struct sect_opt *)
xrealloc (sect_opts,
num_sect_opts
* sizeof (struct sect_opt)));
}
} }
else else
{ {
@ -2268,21 +2254,14 @@ add_symbol_file_command (char *args, int from_tty)
to an option. */ to an option. */
if (expecting_sec_name) if (expecting_sec_name)
{ {
sect_opts[section_index].name = arg; sect_opt sect = { arg, NULL };
sect_opts.push_back (sect);
expecting_sec_name = 0; expecting_sec_name = 0;
} }
else if (expecting_sec_addr) else if (expecting_sec_addr)
{ {
sect_opts[section_index].value = arg; sect_opts.back ().value = arg;
expecting_sec_addr = 0; expecting_sec_addr = 0;
if (++section_index >= num_sect_opts)
{
num_sect_opts *= 2;
sect_opts = ((struct sect_opt *)
xrealloc (sect_opts,
num_sect_opts
* sizeof (struct sect_opt)));
}
} }
else if (strcmp (arg, "-readnow") == 0) else if (strcmp (arg, "-readnow") == 0)
flags |= OBJF_READNOW; flags |= OBJF_READNOW;
@ -2301,7 +2280,7 @@ add_symbol_file_command (char *args, int from_tty)
filename, and the second is the address where this file has been filename, and the second is the address where this file has been
loaded. Abort now if this address hasn't been provided by the loaded. Abort now if this address hasn't been provided by the
user. */ user. */
if (section_index < 1) if (sect_opts.empty ())
error (_("The address where %s has been loaded is missing"), error (_("The address where %s has been loaded is missing"),
filename.get ()); filename.get ());
@ -2313,13 +2292,13 @@ add_symbol_file_command (char *args, int from_tty)
printf_unfiltered (_("add symbol table from file \"%s\" at\n"), printf_unfiltered (_("add symbol table from file \"%s\" at\n"),
filename.get ()); filename.get ());
section_addrs = alloc_section_addr_info (section_index); section_addrs = alloc_section_addr_info (sect_opts.size ());
make_cleanup (xfree, section_addrs); make_cleanup (xfree, section_addrs);
for (i = 0; i < section_index; i++) for (sect_opt &sect : sect_opts)
{ {
CORE_ADDR addr; CORE_ADDR addr;
const char *val = sect_opts[i].value; const char *val = sect.value;
const char *sec = sect_opts[i].name; const char *sec = sect.name;
addr = parse_and_eval_address (val); addr = parse_and_eval_address (val);