public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/6] Avoid manual memory management in gdb/compile/
@ 2020-08-09 13:52 Tom Tromey
  2020-08-09 13:52 ` [PATCH 1/6] Remove some manual memory management from compile interface Tom Tromey
                   ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Tom Tromey @ 2020-08-09 13:52 UTC (permalink / raw)
  To: gdb-patches

I started working on a series to remove the use of
bfd_map_over_sections, but got sucked into cleaning up memory
management in gdb/compile instead.  This series is the result.

Tom



^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/6] Remove some manual memory management from compile interface
  2020-08-09 13:52 [PATCH 0/6] Avoid manual memory management in gdb/compile/ Tom Tromey
@ 2020-08-09 13:52 ` Tom Tromey
  2020-08-09 22:34   ` Simon Marchi
  2020-08-09 13:52 ` [PATCH 2/6] Use new/delete for do_module_cleanup Tom Tromey
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Tom Tromey @ 2020-08-09 13:52 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes gdb's compile code to use std::vector in a couple of
places, rather than manual memory management.

gdb/ChangeLog
2020-08-08  Tom Tromey  <tom@tromey.com>

	* compile/compile-cplus-types.c
	(compile_cplus_convert_struct_or_union): Use std::vector.
	(compile_cplus_convert_func): Likewise.
	* compile/compile-c-types.c (convert_func): Use std::vector.
---
 gdb/ChangeLog                     |  7 ++++++
 gdb/compile/compile-c-types.c     |  4 ++--
 gdb/compile/compile-cplus-types.c | 39 +++++++++++++++----------------
 3 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/gdb/compile/compile-c-types.c b/gdb/compile/compile-c-types.c
index 2b25783bb00..7816ececb25 100644
--- a/gdb/compile/compile-c-types.c
+++ b/gdb/compile/compile-c-types.c
@@ -176,13 +176,13 @@ convert_func (compile_c_instance *context, struct type *type)
   return_type = context->convert_type (target_type);
 
   array.n_elements = type->num_fields ();
-  array.elements = XNEWVEC (gcc_type, type->num_fields ());
+  std::vector<gcc_type> elements (array.n_elements);
+  array.elements = elements.data ();
   for (i = 0; i < type->num_fields (); ++i)
     array.elements[i] = context->convert_type (type->field (i).type ());
 
   result = context->plugin ().build_function_type (return_type,
 						   &array, is_varargs);
-  xfree (array.elements);
 
   return result;
 }
diff --git a/gdb/compile/compile-cplus-types.c b/gdb/compile/compile-cplus-types.c
index 02df7ab90e6..00eaaf3fa68 100644
--- a/gdb/compile/compile-cplus-types.c
+++ b/gdb/compile/compile-cplus-types.c
@@ -848,33 +848,33 @@ compile_cplus_convert_struct_or_union (compile_cplus_instance *instance,
   gcc_type result;
   if (type->code () == TYPE_CODE_STRUCT)
     {
-      struct gcc_vbase_array bases;
       int num_baseclasses = TYPE_N_BASECLASSES (type);
+      std::vector<gcc_type> elements (num_baseclasses);
+      std::vector<enum gcc_cp_symbol_kind> flags (num_baseclasses);
 
-      memset (&bases, 0, sizeof (bases));
+      struct gcc_vbase_array bases {};
+      bases.elements = elements.data ();
 
       if (num_baseclasses > 0)
 	{
-	  bases.elements = XNEWVEC (gcc_type, num_baseclasses);
-	  bases.flags = XNEWVEC (enum gcc_cp_symbol_kind, num_baseclasses);
+	  bases.flags = flags.data ();
 	  bases.n_elements = num_baseclasses;
-	  for (int i = 0; i < num_baseclasses; ++i)
-	    {
-	      struct type *base_type = TYPE_BASECLASS (type, i);
-
-	      bases.flags[i] = GCC_CP_SYMBOL_BASECLASS
-		| get_field_access_flag (type, i)
-		| (BASETYPE_VIA_VIRTUAL (type, i)
-		   ? GCC_CP_FLAG_BASECLASS_VIRTUAL
-		   : GCC_CP_FLAG_BASECLASS_NOFLAG);
-	      bases.elements[i] = instance->convert_type (base_type);
-	    }
+	}
+
+      for (int i = 0; i < num_baseclasses; ++i)
+	{
+	  struct type *base_type = TYPE_BASECLASS (type, i);
+
+	  bases.flags[i] = (GCC_CP_SYMBOL_BASECLASS
+			    | get_field_access_flag (type, i)
+			    | (BASETYPE_VIA_VIRTUAL (type, i)
+			       ? GCC_CP_FLAG_BASECLASS_VIRTUAL
+			       : GCC_CP_FLAG_BASECLASS_NOFLAG));
+	  bases.elements[i] = instance->convert_type (base_type);
 	}
 
       result = instance->plugin ().start_class_type
 	(name.get (), resuld, &bases, filename, line);
-      xfree (bases.flags);
-      xfree (bases.elements);
     }
   else
     {
@@ -985,8 +985,8 @@ compile_cplus_convert_func (compile_cplus_instance *instance,
      types.  Those are impossible in C, though.  */
   gcc_type return_type = instance->convert_type (target_type);
 
-  struct gcc_type_array array =
-    { type->num_fields (), XNEWVEC (gcc_type, type->num_fields ()) };
+  std::vector<gcc_type> elements (type->num_fields ());
+  struct gcc_type_array array = { type->num_fields (), elements.data () };
   int artificials = 0;
   for (int i = 0; i < type->num_fields (); ++i)
     {
@@ -1006,7 +1006,6 @@ compile_cplus_convert_func (compile_cplus_instance *instance,
      with some minsyms like printf (compile-cplus.exp has examples).  */
   gcc_type result = instance->plugin ().build_function_type
     (return_type, &array, is_varargs);
-  xfree (array.elements);
   return result;
 }
 
-- 
2.17.2


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 2/6] Use new/delete for do_module_cleanup
  2020-08-09 13:52 [PATCH 0/6] Avoid manual memory management in gdb/compile/ Tom Tromey
  2020-08-09 13:52 ` [PATCH 1/6] Remove some manual memory management from compile interface Tom Tromey
@ 2020-08-09 13:52 ` Tom Tromey
  2020-08-09 22:45   ` [PP?] " Simon Marchi
  2020-08-09 13:52 ` [PATCH 3/6] Introduce and use compile_module_up Tom Tromey
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Tom Tromey @ 2020-08-09 13:52 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes do_module_cleanup to use new and delete.  It also removes
the use of the struct hack from this object -- this requires more
allocations for now, but this will be removed in a subsequent patch.

gdb/ChangeLog
2020-08-08  Tom Tromey  <tom@tromey.com>

	* compile/compile-object-run.c (struct do_module_cleanup): Add
	constructor, destructor.
	<objfile_name_string>: Don't use struct hack.
	(do_module_cleanup): Use delete.
	(compile_object_run): Use new.
---
 gdb/ChangeLog                    |  8 ++++++++
 gdb/compile/compile-object-run.c | 24 ++++++++++++++++--------
 2 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/gdb/compile/compile-object-run.c b/gdb/compile/compile-object-run.c
index a2f39900053..4a18655d488 100644
--- a/gdb/compile/compile-object-run.c
+++ b/gdb/compile/compile-object-run.c
@@ -32,6 +32,17 @@
 
 struct do_module_cleanup
 {
+  do_module_cleanup () = default;
+
+  ~do_module_cleanup ()
+  {
+    delete munmap_list_head;
+    xfree (source_file);
+    xfree (objfile_name_string);
+  }
+
+  DISABLE_COPY_AND_ASSIGN (do_module_cleanup);
+
   /* Boolean to set true upon a call of do_module_cleanup.
      The pointer may be NULL.  */
   int *executedp;
@@ -51,7 +62,7 @@ struct do_module_cleanup
   struct munmap_list *munmap_list_head;
 
   /* objfile_name of our objfile.  */
-  char objfile_name_string[1];
+  char *objfile_name_string;
 };
 
 /* Cleanup everything after the inferior function dummy frame gets
@@ -96,13 +107,11 @@ do_module_cleanup (void *arg, int registers_valid)
 
   /* Delete the .c file.  */
   unlink (data->source_file);
-  xfree (data->source_file);
-
-  delete data->munmap_list_head;
 
   /* Delete the .o file.  */
   unlink (data->objfile_name_string);
-  xfree (data);
+
+  delete data;
 }
 
 /* Perform inferior call of MODULE.  This function may throw an error.
@@ -122,11 +131,10 @@ compile_object_run (struct compile_module *module)
   CORE_ADDR regs_addr = module->regs_addr;
   struct objfile *objfile = module->objfile;
 
-  data = (struct do_module_cleanup *) xmalloc (sizeof (*data)
-					       + strlen (objfile_name_s));
+  data = new struct do_module_cleanup;
   data->executedp = &executed;
   data->source_file = xstrdup (module->source_file);
-  strcpy (data->objfile_name_string, objfile_name_s);
+  data->objfile_name_string = xstrdup (objfile_name_s);
   data->scope = module->scope;
   data->scope_data = module->scope_data;
   data->out_value_type = module->out_value_type;
-- 
2.17.2


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 3/6] Introduce and use compile_module_up
  2020-08-09 13:52 [PATCH 0/6] Avoid manual memory management in gdb/compile/ Tom Tromey
  2020-08-09 13:52 ` [PATCH 1/6] Remove some manual memory management from compile interface Tom Tromey
  2020-08-09 13:52 ` [PATCH 2/6] Use new/delete for do_module_cleanup Tom Tromey
@ 2020-08-09 13:52 ` Tom Tromey
  2020-08-09 13:52 ` [PATCH 4/6] Transfer module ownership to do_module_cleanup Tom Tromey
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Tom Tromey @ 2020-08-09 13:52 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This introduces compile_module_up, a unique pointer for
compile_module, and changes a few spots to use it.

gdb/ChangeLog
2020-08-08  Tom Tromey  <tom@tromey.com>

	* compile/compile.c (eval_compile_command): Update.
	* compile/compile-object-run.h (compile_object_run): Take a
	compile_module_up.
	* compile/compile-object-run.c (compile_object_run): Take a
	compile_module_up.
	* compile/compile-object-load.h (struct compile_module): Add
	constructor, destructor.
	(compile_module_up): New typedef.
	(compile_object_load): Return compile_object_up.
	* compile/compile-object-load.c (compile_object_load): Return
	compile_module_up.
---
 gdb/ChangeLog                     | 14 ++++++++++++++
 gdb/compile/compile-object-load.c |  5 ++---
 gdb/compile/compile-object-load.h | 12 +++++++++++-
 gdb/compile/compile-object-run.c  |  4 +---
 gdb/compile/compile-object-run.h  |  2 +-
 gdb/compile/compile.c             |  7 +++----
 6 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c
index 2f416079025..dff10fe94f4 100644
--- a/gdb/compile/compile-object-load.c
+++ b/gdb/compile/compile-object-load.c
@@ -582,7 +582,7 @@ store_regs (struct type *regs_type, CORE_ADDR regs_base)
    COMPILE_I_PRINT_ADDRESS_SCOPE when COMPILE_I_PRINT_VALUE_SCOPE
    should have been used instead.  */
 
-struct compile_module *
+compile_module_up
 compile_object_load (const compile_file_names &file_names,
 		     enum compile_i_scope_types scope, void *scope_data)
 {
@@ -594,7 +594,6 @@ compile_object_load (const compile_file_names &file_names,
   long storage_needed;
   asymbol **symbol_table, **symp;
   long number_of_symbols, missing_symbols;
-  struct compile_module *retval;
   struct type *regs_type, *out_value_type = NULL;
   char **matching;
   struct objfile *objfile;
@@ -790,7 +789,7 @@ compile_object_load (const compile_file_names &file_names,
 			    paddress (target_gdbarch (), out_value_addr));
     }
 
-  retval = XNEW (struct compile_module);
+  compile_module_up retval (new struct compile_module);
   retval->objfile = objfile_holder.release ();
   retval->source_file = xstrdup (file_names.source_file ());
   retval->func_sym = func_sym;
diff --git a/gdb/compile/compile-object-load.h b/gdb/compile/compile-object-load.h
index c4adc719141..9def29ebc9b 100644
--- a/gdb/compile/compile-object-load.h
+++ b/gdb/compile/compile-object-load.h
@@ -46,6 +46,13 @@ struct munmap_list
 
 struct compile_module
 {
+  compile_module () = default;
+
+  DISABLE_COPY_AND_ASSIGN (compile_module);
+
+  compile_module &operator= (compile_module &&other) = default;
+  compile_module (compile_module &&other) = default;
+
   /* objfile for the compiled module.  */
   struct objfile *objfile;
 
@@ -77,7 +84,10 @@ struct compile_module
   struct munmap_list *munmap_list_head;
 };
 
-extern struct compile_module *compile_object_load
+/* A unique pointer for a compile_module.  */
+typedef std::unique_ptr<compile_module> compile_module_up;
+
+extern compile_module_up compile_object_load
   (const compile_file_names &fnames,
    enum compile_i_scope_types scope, void *scope_data);
 
diff --git a/gdb/compile/compile-object-run.c b/gdb/compile/compile-object-run.c
index 4a18655d488..5a680a6723f 100644
--- a/gdb/compile/compile-object-run.c
+++ b/gdb/compile/compile-object-run.c
@@ -121,7 +121,7 @@ do_module_cleanup (void *arg, int registers_valid)
    longer touch MODULE's memory after this function has been called.  */
 
 void
-compile_object_run (struct compile_module *module)
+compile_object_run (compile_module_up &&module)
 {
   struct value *func_val;
   struct do_module_cleanup *data;
@@ -142,8 +142,6 @@ compile_object_run (struct compile_module *module)
   data->munmap_list_head = module->munmap_list_head;
 
   xfree (module->source_file);
-  xfree (module);
-  module = NULL;
 
   try
     {
diff --git a/gdb/compile/compile-object-run.h b/gdb/compile/compile-object-run.h
index 9311d02c379..45375db654f 100644
--- a/gdb/compile/compile-object-run.h
+++ b/gdb/compile/compile-object-run.h
@@ -19,6 +19,6 @@
 
 #include "compile-object-load.h"
 
-extern void compile_object_run (struct compile_module *module);
+extern void compile_object_run (compile_module_up &&module);
 
 #endif /* COMPILE_COMPILE_OBJECT_RUN_H */
diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c
index 0c29a0476e7..0f830f6db71 100644
--- a/gdb/compile/compile.c
+++ b/gdb/compile/compile.c
@@ -820,14 +820,13 @@ void
 eval_compile_command (struct command_line *cmd, const char *cmd_string,
 		      enum compile_i_scope_types scope, void *scope_data)
 {
-  struct compile_module *compile_module;
-
   compile_file_names fnames = compile_to_object (cmd, cmd_string, scope);
 
   gdb::unlinker object_remover (fnames.object_file ());
   gdb::unlinker source_remover (fnames.source_file ());
 
-  compile_module = compile_object_load (fnames, scope, scope_data);
+  compile_module_up compile_module = compile_object_load (fnames, scope,
+							  scope_data);
   if (compile_module == NULL)
     {
       gdb_assert (scope == COMPILE_I_PRINT_ADDRESS_SCOPE);
@@ -840,7 +839,7 @@ eval_compile_command (struct command_line *cmd, const char *cmd_string,
   source_remover.keep ();
   object_remover.keep ();
 
-  compile_object_run (compile_module);
+  compile_object_run (std::move (compile_module));
 }
 
 /* See compile/compile-internal.h.  */
-- 
2.17.2


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 4/6] Transfer module ownership to do_module_cleanup
  2020-08-09 13:52 [PATCH 0/6] Avoid manual memory management in gdb/compile/ Tom Tromey
                   ` (2 preceding siblings ...)
  2020-08-09 13:52 ` [PATCH 3/6] Introduce and use compile_module_up Tom Tromey
@ 2020-08-09 13:52 ` Tom Tromey
  2020-08-10  0:48   ` [PP?] " Simon Marchi
  2020-08-09 13:52 ` [PATCH 5/6] Simplify compile_module cleanup Tom Tromey
  2020-08-09 13:52 ` [PATCH 6/6] Avoid manual memory management of argv arrays in gdb/compile Tom Tromey
  5 siblings, 1 reply; 15+ messages in thread
From: Tom Tromey @ 2020-08-09 13:52 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes the do_module_cleanup structure to simply hold on to the
module itself.  This lets us remove most members from
do_module_cleanup.

gdb/ChangeLog
2020-08-08  Tom Tromey  <tom@tromey.com>

	* compile/compile-object-run.c (struct do_module_cleanup): Add
	parameters to constructor.  Update destructor.
	<source_file, scope, scope_data, out_value_type, out_value_addr,
	munmap_list_head, objfile_name_string>: Remove.
	<module>: New member.
	(do_module_cleanup): Update.
	(compile_object_run): Update.
---
 gdb/ChangeLog                    | 10 +++++
 gdb/compile/compile-object-run.c | 67 ++++++++++++--------------------
 2 files changed, 35 insertions(+), 42 deletions(-)

diff --git a/gdb/compile/compile-object-run.c b/gdb/compile/compile-object-run.c
index 5a680a6723f..ac0a995fee9 100644
--- a/gdb/compile/compile-object-run.c
+++ b/gdb/compile/compile-object-run.c
@@ -32,13 +32,16 @@
 
 struct do_module_cleanup
 {
-  do_module_cleanup () = default;
+  do_module_cleanup (int *ptr, compile_module_up &&mod)
+    : executedp (ptr),
+      module (std::move (mod))
+  {
+  }
 
   ~do_module_cleanup ()
   {
-    delete munmap_list_head;
-    xfree (source_file);
-    xfree (objfile_name_string);
+    delete module->munmap_list_head;
+    xfree (module->source_file);
   }
 
   DISABLE_COPY_AND_ASSIGN (do_module_cleanup);
@@ -47,22 +50,8 @@ struct do_module_cleanup
      The pointer may be NULL.  */
   int *executedp;
 
-  /* .c file OBJFILE was built from.  It needs to be xfree-d.  */
-  char *source_file;
-
-  /* Copy from struct compile_module.  */
-  enum compile_i_scope_types scope;
-  void *scope_data;
-
-  /* Copy from struct compile_module.  */
-  struct type *out_value_type;
-  CORE_ADDR out_value_addr;
-
-  /* Copy from struct compile_module.  */
-  struct munmap_list *munmap_list_head;
-
-  /* objfile_name of our objfile.  */
-  char *objfile_name_string;
+  /* The compile module.  */
+  compile_module_up module;
 };
 
 /* Cleanup everything after the inferior function dummy frame gets
@@ -80,22 +69,26 @@ do_module_cleanup (void *arg, int registers_valid)
 
       /* This code cannot be in compile_object_run as OUT_VALUE_TYPE
 	 no longer exists there.  */
-      if (data->scope == COMPILE_I_PRINT_ADDRESS_SCOPE
-	  || data->scope == COMPILE_I_PRINT_VALUE_SCOPE)
+      if (data->module->scope == COMPILE_I_PRINT_ADDRESS_SCOPE
+	  || data->module->scope == COMPILE_I_PRINT_VALUE_SCOPE)
 	{
 	  struct value *addr_value;
-	  struct type *ptr_type = lookup_pointer_type (data->out_value_type);
+	  struct type *ptr_type
+	    = lookup_pointer_type (data->module->out_value_type);
 
-	  addr_value = value_from_pointer (ptr_type, data->out_value_addr);
+	  addr_value = value_from_pointer (ptr_type,
+					   data->module->out_value_addr);
 
 	  /* SCOPE_DATA would be stale unless EXECUTEDP != NULL.  */
-	  compile_print_value (value_ind (addr_value), data->scope_data);
+	  compile_print_value (value_ind (addr_value),
+			       data->module->scope_data);
 	}
     }
 
+  const char *objfile_name_s = objfile_name (data->module->objfile);
   for (objfile *objfile : current_program_space->objfiles ())
     if ((objfile->flags & OBJF_USERLOADED) == 0
-        && (strcmp (objfile_name (objfile), data->objfile_name_string) == 0))
+        && (strcmp (objfile_name (objfile), objfile_name_s) == 0))
       {
 	objfile->unlink ();
 
@@ -106,10 +99,10 @@ do_module_cleanup (void *arg, int registers_valid)
       }
 
   /* Delete the .c file.  */
-  unlink (data->source_file);
+  unlink (data->module->source_file);
 
   /* Delete the .o file.  */
-  unlink (data->objfile_name_string);
+  unlink (objfile_name_s);
 
   delete data;
 }
@@ -125,23 +118,12 @@ compile_object_run (compile_module_up &&module)
 {
   struct value *func_val;
   struct do_module_cleanup *data;
-  const char *objfile_name_s = objfile_name (module->objfile);
   int dtor_found, executed = 0;
   struct symbol *func_sym = module->func_sym;
   CORE_ADDR regs_addr = module->regs_addr;
   struct objfile *objfile = module->objfile;
 
-  data = new struct do_module_cleanup;
-  data->executedp = &executed;
-  data->source_file = xstrdup (module->source_file);
-  data->objfile_name_string = xstrdup (objfile_name_s);
-  data->scope = module->scope;
-  data->scope_data = module->scope_data;
-  data->out_value_type = module->out_value_type;
-  data->out_value_addr = module->out_value_addr;
-  data->munmap_list_head = module->munmap_list_head;
-
-  xfree (module->source_file);
+  data = new struct do_module_cleanup (&executed, std::move (module));
 
   try
     {
@@ -169,9 +151,10 @@ compile_object_run (compile_module_up &&module)
 	}
       if (func_type->num_fields () >= 2)
 	{
-	  gdb_assert (data->out_value_addr != 0);
+	  gdb_assert (data->module->out_value_addr != 0);
 	  vargs[current_arg] = value_from_pointer
-	       (func_type->field (current_arg).type (), data->out_value_addr);
+	       (func_type->field (current_arg).type (),
+		data->module->out_value_addr);
 	  ++current_arg;
 	}
       gdb_assert (current_arg == func_type->num_fields ());
-- 
2.17.2


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 5/6] Simplify compile_module cleanup
  2020-08-09 13:52 [PATCH 0/6] Avoid manual memory management in gdb/compile/ Tom Tromey
                   ` (3 preceding siblings ...)
  2020-08-09 13:52 ` [PATCH 4/6] Transfer module ownership to do_module_cleanup Tom Tromey
@ 2020-08-09 13:52 ` Tom Tromey
  2020-08-09 13:52 ` [PATCH 6/6] Avoid manual memory management of argv arrays in gdb/compile Tom Tromey
  5 siblings, 0 replies; 15+ messages in thread
From: Tom Tromey @ 2020-08-09 13:52 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This simplifies compile_module cleanup by removing the need to
explicitly free anything.  struct setup_sections_data is also cleaned
up a bit.

gdb/ChangeLog
2020-08-08  Tom Tromey  <tom@tromey.com>

	* compile/compile-object-run.c (do_module_cleanup)
	<~do_module_cleanup> :Remove.
	(do_module_cleanup): Update.
	* compile/compile-object-load.h (struct munmap_list): Add move
	assignment operator.
	<source_file>: Now a std::string.
	<munmap_list>: Rename.  No longer a pointer.
	* compile/compile-object-load.c (struct setup_sections_data): Add
	constructor.
	<setup_one_section>: Declare.
	<munmap_list>: Move earlier.
	<m_bfd>: New member.
	<m_last_size, m_last_section_first, m_last_prot,
	m_last_max_alignment>: Rename, add initializers where needed.
	(setup_sections_data::setup_one_section): Rename from
	setup_sections.  Update.
	(compile_object_load): Update.  Don't use bfd_map_over_sections.
---
 gdb/ChangeLog                     |  20 ++++++
 gdb/compile/compile-object-load.c | 103 +++++++++++++++++-------------
 gdb/compile/compile-object-load.h |   8 ++-
 gdb/compile/compile-object-run.c  |   8 +--
 4 files changed, 83 insertions(+), 56 deletions(-)

diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c
index dff10fe94f4..bde3b742db4 100644
--- a/gdb/compile/compile-object-load.c
+++ b/gdb/compile/compile-object-load.c
@@ -62,34 +62,50 @@ munmap_list::~munmap_list ()
     }
 }
 
-/* Helper data for setup_sections.  */
+/* A data structure that is used to lay out sections of our objfile in
+   inferior memory.  */
 
 struct setup_sections_data
 {
+  explicit setup_sections_data (bfd *abfd)
+    : m_bfd (abfd),
+      m_last_section_first (abfd->sections)
+  {
+  }
+
+  /* Place all ABFD sections next to each other obeying all
+     constraints.  */
+  void setup_one_section (asection *sect);
+
+  /* List of inferior mmap ranges where setup_sections should add its
+     next range.  */
+  struct munmap_list munmap_list;
+
+private:
+
+  /* The BFD.  */
+  bfd *m_bfd;
+
   /* Size of all recent sections with matching LAST_PROT.  */
-  CORE_ADDR last_size;
+  CORE_ADDR m_last_size = 0;
 
   /* First section matching LAST_PROT.  */
-  asection *last_section_first;
+  asection *m_last_section_first;
 
   /* Memory protection like the prot parameter of gdbarch_infcall_mmap. */
-  unsigned last_prot;
+  unsigned m_last_prot = -1;
 
   /* Maximum of alignments of all sections matching LAST_PROT.
      This value is always at least 1.  This value is always a power of 2.  */
-  CORE_ADDR last_max_alignment;
+  CORE_ADDR m_last_max_alignment = -1;
 
-  /* List of inferior mmap ranges where setup_sections should add its
-     next range.  */
-  std::unique_ptr<struct munmap_list> munmap_list;
 };
 
-/* Place all ABFD sections next to each other obeying all constraints.  */
+/* See setup_sections_data.  */
 
-static void
-setup_sections (bfd *abfd, asection *sect, void *data_voidp)
+void
+setup_sections_data::setup_one_section (asection *sect)
 {
-  struct setup_sections_data *data = (struct setup_sections_data *) data_voidp;
   CORE_ADDR alignment;
   unsigned prot;
 
@@ -112,7 +128,7 @@ setup_sections (bfd *abfd, asection *sect, void *data_voidp)
       if (compile_debug)
 	fprintf_unfiltered (gdb_stdlog,
 			    "module \"%s\" section \"%s\" size %s prot %u\n",
-			    bfd_get_filename (abfd),
+			    bfd_get_filename (m_bfd),
 			    bfd_section_name (sect),
 			    paddress (target_gdbarch (),
 				      bfd_section_size (sect)),
@@ -122,55 +138,55 @@ setup_sections (bfd *abfd, asection *sect, void *data_voidp)
     prot = -1;
 
   if (sect == NULL
-      || (data->last_prot != prot && bfd_section_size (sect) != 0))
+      || (m_last_prot != prot && bfd_section_size (sect) != 0))
     {
       CORE_ADDR addr;
       asection *sect_iter;
 
-      if (data->last_size != 0)
+      if (m_last_size != 0)
 	{
-	  addr = gdbarch_infcall_mmap (target_gdbarch (), data->last_size,
-				       data->last_prot);
-	  data->munmap_list->add (addr, data->last_size);
+	  addr = gdbarch_infcall_mmap (target_gdbarch (), m_last_size,
+				       m_last_prot);
+	  munmap_list.add (addr, m_last_size);
 	  if (compile_debug)
 	    fprintf_unfiltered (gdb_stdlog,
 				"allocated %s bytes at %s prot %u\n",
-				paddress (target_gdbarch (), data->last_size),
+				paddress (target_gdbarch (), m_last_size),
 				paddress (target_gdbarch (), addr),
-				data->last_prot);
+				m_last_prot);
 	}
       else
 	addr = 0;
 
-      if ((addr & (data->last_max_alignment - 1)) != 0)
+      if ((addr & (m_last_max_alignment - 1)) != 0)
 	error (_("Inferior compiled module address %s "
 		 "is not aligned to BFD required %s."),
 	       paddress (target_gdbarch (), addr),
-	       paddress (target_gdbarch (), data->last_max_alignment));
+	       paddress (target_gdbarch (), m_last_max_alignment));
 
-      for (sect_iter = data->last_section_first; sect_iter != sect;
+      for (sect_iter = m_last_section_first; sect_iter != sect;
 	   sect_iter = sect_iter->next)
 	if ((bfd_section_flags (sect_iter) & SEC_ALLOC) != 0)
 	  bfd_set_section_vma (sect_iter, addr + bfd_section_vma (sect_iter));
 
-      data->last_size = 0;
-      data->last_section_first = sect;
-      data->last_prot = prot;
-      data->last_max_alignment = 1;
+      m_last_size = 0;
+      m_last_section_first = sect;
+      m_last_prot = prot;
+      m_last_max_alignment = 1;
     }
 
   if (sect == NULL)
     return;
 
   alignment = ((CORE_ADDR) 1) << bfd_section_alignment (sect);
-  data->last_max_alignment = std::max (data->last_max_alignment, alignment);
+  m_last_max_alignment = std::max (m_last_max_alignment, alignment);
 
-  data->last_size = (data->last_size + alignment - 1) & -alignment;
+  m_last_size = (m_last_size + alignment - 1) & -alignment;
 
-  bfd_set_section_vma (sect, data->last_size);
+  bfd_set_section_vma (sect, m_last_size);
 
-  data->last_size += bfd_section_size (sect);
-  data->last_size = (data->last_size + alignment - 1) & -alignment;
+  m_last_size += bfd_section_size (sect);
+  m_last_size = (m_last_size + alignment - 1) & -alignment;
 }
 
 /* Helper for link_callbacks callbacks vector.  */
@@ -586,7 +602,6 @@ compile_module_up
 compile_object_load (const compile_file_names &file_names,
 		     enum compile_i_scope_types scope, void *scope_data)
 {
-  struct setup_sections_data setup_sections_data;
   CORE_ADDR regs_addr, out_value_addr = 0;
   struct symbol *func_sym;
   struct type *func_type;
@@ -616,14 +631,10 @@ compile_object_load (const compile_file_names &file_names,
   if ((bfd_get_file_flags (abfd.get ()) & (EXEC_P | DYNAMIC)) != 0)
     error (_("\"%s\": not in object format."), filename.get ());
 
-  setup_sections_data.last_size = 0;
-  setup_sections_data.last_section_first = abfd->sections;
-  setup_sections_data.last_prot = -1;
-  setup_sections_data.last_max_alignment = 1;
-  setup_sections_data.munmap_list.reset (new struct munmap_list);
-
-  bfd_map_over_sections (abfd.get (), setup_sections, &setup_sections_data);
-  setup_sections (abfd.get (), NULL, &setup_sections_data);
+  struct setup_sections_data setup_sections_data (abfd.get ());
+  for (asection *sect = abfd->sections; sect != nullptr; sect = sect->next)
+    setup_sections_data.setup_one_section (sect);
+  setup_sections_data.setup_one_section (nullptr);
 
   storage_needed = bfd_get_symtab_upper_bound (abfd.get ());
   if (storage_needed < 0)
@@ -757,7 +768,7 @@ compile_object_load (const compile_file_names &file_names,
 					TYPE_LENGTH (regs_type),
 					GDB_MMAP_PROT_READ);
       gdb_assert (regs_addr != 0);
-      setup_sections_data.munmap_list->add (regs_addr, TYPE_LENGTH (regs_type));
+      setup_sections_data.munmap_list.add (regs_addr, TYPE_LENGTH (regs_type));
       if (compile_debug)
 	fprintf_unfiltered (gdb_stdlog,
 			    "allocated %s bytes at %s for registers\n",
@@ -779,8 +790,8 @@ compile_object_load (const compile_file_names &file_names,
 					     (GDB_MMAP_PROT_READ
 					      | GDB_MMAP_PROT_WRITE));
       gdb_assert (out_value_addr != 0);
-      setup_sections_data.munmap_list->add (out_value_addr,
-					    TYPE_LENGTH (out_value_type));
+      setup_sections_data.munmap_list.add (out_value_addr,
+					   TYPE_LENGTH (out_value_type));
       if (compile_debug)
 	fprintf_unfiltered (gdb_stdlog,
 			    "allocated %s bytes at %s for printed value\n",
@@ -791,14 +802,14 @@ compile_object_load (const compile_file_names &file_names,
 
   compile_module_up retval (new struct compile_module);
   retval->objfile = objfile_holder.release ();
-  retval->source_file = xstrdup (file_names.source_file ());
+  retval->source_file = file_names.source_file ();
   retval->func_sym = func_sym;
   retval->regs_addr = regs_addr;
   retval->scope = scope;
   retval->scope_data = scope_data;
   retval->out_value_type = out_value_type;
   retval->out_value_addr = out_value_addr;
-  retval->munmap_list_head = setup_sections_data.munmap_list.release ();
+  retval->munmap_list = std::move (setup_sections_data.munmap_list);
 
   return retval;
 }
diff --git a/gdb/compile/compile-object-load.h b/gdb/compile/compile-object-load.h
index 9def29ebc9b..0254390109e 100644
--- a/gdb/compile/compile-object-load.h
+++ b/gdb/compile/compile-object-load.h
@@ -29,6 +29,8 @@ struct munmap_list
 
   DISABLE_COPY_AND_ASSIGN (munmap_list);
 
+  munmap_list &operator= (munmap_list &&) = default;
+
   /* Add a region to the list.  */
   void add (CORE_ADDR addr, CORE_ADDR size);
 
@@ -56,8 +58,8 @@ struct compile_module
   /* objfile for the compiled module.  */
   struct objfile *objfile;
 
-  /* .c file OBJFILE was built from.  It needs to be xfree-d.  */
-  char *source_file;
+  /* .c file OBJFILE was built from.  */
+  std::string source_file;
 
   /* Inferior function GCC_FE_WRAPPER_FUNCTION.  */
   struct symbol *func_sym;
@@ -81,7 +83,7 @@ struct compile_module
   CORE_ADDR out_value_addr;
 
   /* Track inferior memory reserved by inferior mmap.  */
-  struct munmap_list *munmap_list_head;
+  struct munmap_list munmap_list;
 };
 
 /* A unique pointer for a compile_module.  */
diff --git a/gdb/compile/compile-object-run.c b/gdb/compile/compile-object-run.c
index ac0a995fee9..10867eee30c 100644
--- a/gdb/compile/compile-object-run.c
+++ b/gdb/compile/compile-object-run.c
@@ -38,12 +38,6 @@ struct do_module_cleanup
   {
   }
 
-  ~do_module_cleanup ()
-  {
-    delete module->munmap_list_head;
-    xfree (module->source_file);
-  }
-
   DISABLE_COPY_AND_ASSIGN (do_module_cleanup);
 
   /* Boolean to set true upon a call of do_module_cleanup.
@@ -99,7 +93,7 @@ do_module_cleanup (void *arg, int registers_valid)
       }
 
   /* Delete the .c file.  */
-  unlink (data->module->source_file);
+  unlink (data->module->source_file.c_str ());
 
   /* Delete the .o file.  */
   unlink (objfile_name_s);
-- 
2.17.2


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 6/6] Avoid manual memory management of argv arrays in gdb/compile
  2020-08-09 13:52 [PATCH 0/6] Avoid manual memory management in gdb/compile/ Tom Tromey
                   ` (4 preceding siblings ...)
  2020-08-09 13:52 ` [PATCH 5/6] Simplify compile_module cleanup Tom Tromey
@ 2020-08-09 13:52 ` Tom Tromey
  5 siblings, 0 replies; 15+ messages in thread
From: Tom Tromey @ 2020-08-09 13:52 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes gdb/compile to use gdb_argv directly, rather than
manually managing the arrays itself.  A few new helpers are added to
gdb_argv.

gdb/ChangeLog
2020-08-08  Tom Tromey  <tom@tromey.com>

	* utils.h (class gdb_argv): Add move operators.
	<append>: New methods.
	* compile/compile.c (build_argc_argv): Remove.
	(compile_args_argc): Remove.
	(compile_args_argv): Change type.
	(set_compile_args): Simplify.
	(append_args): Remove.
	(filter_args): Remove argcp parameter.
	(get_args): Return gdb_argv.  Simplify.
	(compile_to_object): Update.
---
 gdb/ChangeLog         | 13 ++++++++
 gdb/compile/compile.c | 75 ++++++++++---------------------------------
 gdb/utils.h           | 43 +++++++++++++++++++++++++
 3 files changed, 73 insertions(+), 58 deletions(-)

diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c
index 0f830f6db71..cc91d24fe1a 100644
--- a/gdb/compile/compile.c
+++ b/gdb/compile/compile.c
@@ -493,33 +493,18 @@ get_expr_block_and_pc (CORE_ADDR *pc)
   return block;
 }
 
-/* Call buildargv (via gdb_argv), set its result for S into *ARGVP but
-   calculate also the number of parsed arguments into *ARGCP.  If
-   buildargv has returned NULL then *ARGCP is set to zero.  */
-
-static void
-build_argc_argv (const char *s, int *argcp, char ***argvp)
-{
-  gdb_argv args (s);
-
-  *argcp = args.count ();
-  *argvp = args.release ();
-}
-
 /* String for 'set compile-args' and 'show compile-args'.  */
 static char *compile_args;
 
-/* Parsed form of COMPILE_ARGS.  COMPILE_ARGS_ARGV is NULL terminated.  */
-static int compile_args_argc;
-static char **compile_args_argv;
+/* Parsed form of COMPILE_ARGS.  */
+static gdb_argv compile_args_argv;
 
 /* Implement 'set compile-args'.  */
 
 static void
 set_compile_args (const char *args, int from_tty, struct cmd_list_element *c)
 {
-  freeargv (compile_args_argv);
-  build_argc_argv (compile_args, &compile_args_argc, &compile_args_argv);
+  compile_args_argv = gdb_argv (compile_args);
 }
 
 /* Implement 'show compile-args'.  */
@@ -533,21 +518,6 @@ show_compile_args (struct ui_file *file, int from_tty,
 		    value);
 }
 
-/* Append ARGC and ARGV (as parsed by build_argc_argv) to *ARGCP and *ARGVP.
-   ARGCP+ARGVP can be zero+NULL and also ARGC+ARGV can be zero+NULL.  */
-
-static void
-append_args (int *argcp, char ***argvp, int argc, char **argv)
-{
-  int argi;
-
-  *argvp = XRESIZEVEC (char *, *argvp, (*argcp + argc + 1));
-
-  for (argi = 0; argi < argc; argi++)
-    (*argvp)[(*argcp)++] = xstrdup (argv[argi]);
-  (*argvp)[(*argcp)] = NULL;
-}
-
 /* String for 'set compile-gcc' and 'show compile-gcc'.  */
 static char *compile_gcc;
 
@@ -586,10 +556,10 @@ get_selected_pc_producer_options (void)
   return cs;
 }
 
-/* Filter out unwanted options from *ARGCP and ARGV.  */
+/* Filter out unwanted options from ARGV.  */
 
 static void
-filter_args (int *argcp, char **argv)
+filter_args (char **argv)
 {
   char **destv;
 
@@ -599,7 +569,6 @@ filter_args (int *argcp, char **argv)
       if (strcmp (*argv, "-fpreprocessed") == 0)
 	{
 	  xfree (*argv);
-	  (*argcp)--;
 	  continue;
 	}
       *destv++ = *argv;
@@ -627,35 +596,26 @@ filter_args (int *argcp, char **argv)
    appended last so as to override any of the arguments automatically
    generated above.  */
 
-static void
-get_args (const compile_instance *compiler, struct gdbarch *gdbarch,
-	  int *argcp, char ***argvp)
+static gdb_argv
+get_args (const compile_instance *compiler, struct gdbarch *gdbarch)
 {
   const char *cs_producer_options;
-  int argc_compiler;
-  char **argv_compiler;
 
-  build_argc_argv (gdbarch_gcc_target_options (gdbarch).c_str (),
-		   argcp, argvp);
+  gdb_argv result (gdbarch_gcc_target_options (gdbarch).c_str ());
 
   cs_producer_options = get_selected_pc_producer_options ();
   if (cs_producer_options != NULL)
     {
-      int argc_producer;
-      char **argv_producer;
+      gdb_argv argv_producer (cs_producer_options);
+      filter_args (argv_producer.get ());
 
-      build_argc_argv (cs_producer_options, &argc_producer, &argv_producer);
-      filter_args (&argc_producer, argv_producer);
-      append_args (argcp, argvp, argc_producer, argv_producer);
-      freeargv (argv_producer);
+      result.append (std::move (argv_producer));
     }
 
-  build_argc_argv (compiler->gcc_target_options ().c_str (),
-		   &argc_compiler, &argv_compiler);
-  append_args (argcp, argvp, argc_compiler, argv_compiler);
-  freeargv (argv_compiler);
+  result.append (gdb_argv (compiler->gcc_target_options ().c_str ()));
+  result.append (compile_args_argv);
 
-  append_args (argcp, argvp, compile_args_argc, compile_args_argv);
+  return result;
 }
 
 /* A helper function suitable for use as the "print_callback" in the
@@ -677,8 +637,6 @@ compile_to_object (struct command_line *cmd, const char *cmd_string,
 {
   const struct block *expr_block;
   CORE_ADDR trash_pc, expr_pc;
-  int argc;
-  char **argv;
   int ok;
   struct gdbarch *gdbarch = get_current_arch ();
   std::string triplet_rx;
@@ -750,8 +708,9 @@ compile_to_object (struct command_line *cmd, const char *cmd_string,
     }
 
   /* Set compiler command-line arguments.  */
-  get_args (compiler.get (), gdbarch, &argc, &argv);
-  gdb_argv argv_holder (argv);
+  gdb_argv argv_holder = get_args (compiler.get (), gdbarch);
+  int argc = argv_holder.count ();
+  char **argv = argv_holder.get ();
 
   gdb::unique_xmalloc_ptr<char> error_message;
   error_message.reset (compiler->set_arguments (argc, argv,
diff --git a/gdb/utils.h b/gdb/utils.h
index 3434ff1caa2..29ce0125035 100644
--- a/gdb/utils.h
+++ b/gdb/utils.h
@@ -164,6 +164,20 @@ class gdb_argv
   gdb_argv (const gdb_argv &) = delete;
   gdb_argv &operator= (const gdb_argv &) = delete;
 
+  gdb_argv &operator= (gdb_argv &&other)
+  {
+    freeargv (m_argv);
+    m_argv = other.m_argv;
+    other.m_argv = nullptr;
+    return *this;
+  }
+
+  gdb_argv (gdb_argv &&other)
+  {
+    m_argv = other.m_argv;
+    other.m_argv = nullptr;
+  }
+
   ~gdb_argv ()
   {
     freeargv (m_argv);
@@ -210,6 +224,35 @@ class gdb_argv
     return m_argv[arg];
   }
 
+  /* Append arguments to this array.  */
+  void append (gdb_argv &&other)
+  {
+    int size = count ();
+    int argc = other.count ();
+    m_argv = XRESIZEVEC (char *, m_argv, (size + argc + 1));
+
+    for (int argi = 0; argi < argc; argi++)
+      {
+	/* Transfer ownership of the string.  */
+	m_argv[size++] = other.m_argv[argi];
+	/* Ensure that destruction of OTHER works correctly.  */
+	other.m_argv[argi] = nullptr;
+      }
+    m_argv[size] = nullptr;
+  }
+
+  /* Append arguments to this array.  */
+  void append (const gdb_argv &other)
+  {
+    int size = count ();
+    int argc = other.count ();
+    m_argv = XRESIZEVEC (char *, m_argv, (size + argc + 1));
+
+    for (int argi = 0; argi < argc; argi++)
+      m_argv[size++] = xstrdup (other.m_argv[argi]);
+    m_argv[size] = nullptr;
+  }
+
   /* The iterator type.  */
 
   typedef char **iterator;
-- 
2.17.2


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 1/6] Remove some manual memory management from compile interface
  2020-08-09 13:52 ` [PATCH 1/6] Remove some manual memory management from compile interface Tom Tromey
@ 2020-08-09 22:34   ` Simon Marchi
  2020-09-19 23:45     ` Tom Tromey
  0 siblings, 1 reply; 15+ messages in thread
From: Simon Marchi @ 2020-08-09 22:34 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches

> diff --git a/gdb/compile/compile-cplus-types.c b/gdb/compile/compile-cplus-types.c
> index 02df7ab90e6..00eaaf3fa68 100644
> --- a/gdb/compile/compile-cplus-types.c
> +++ b/gdb/compile/compile-cplus-types.c
> @@ -848,33 +848,33 @@ compile_cplus_convert_struct_or_union (compile_cplus_instance *instance,
>    gcc_type result;
>    if (type->code () == TYPE_CODE_STRUCT)
>      {
> -      struct gcc_vbase_array bases;
>        int num_baseclasses = TYPE_N_BASECLASSES (type);
> +      std::vector<gcc_type> elements (num_baseclasses);
> +      std::vector<enum gcc_cp_symbol_kind> flags (num_baseclasses);
>  
> -      memset (&bases, 0, sizeof (bases));
> +      struct gcc_vbase_array bases {};
> +      bases.elements = elements.data ();
>  
>        if (num_baseclasses > 0)

You could now remove this `if (num_baseclasses > 0)`, there's no reason for it anymore I think.

Otherwise, LGTM.

Simon

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PP?] [PATCH 2/6] Use new/delete for do_module_cleanup
  2020-08-09 13:52 ` [PATCH 2/6] Use new/delete for do_module_cleanup Tom Tromey
@ 2020-08-09 22:45   ` Simon Marchi
  2020-09-23 13:36     ` Tom Tromey
  0 siblings, 1 reply; 15+ messages in thread
From: Simon Marchi @ 2020-08-09 22:45 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches

On 2020-08-09 9:52 a.m., Tom Tromey wrote:
> This changes do_module_cleanup to use new and delete.  It also removes
> the use of the struct hack from this object -- this requires more
> allocations for now, but this will be removed in a subsequent patch.
> 
> gdb/ChangeLog
> 2020-08-08  Tom Tromey  <tom@tromey.com>
> 
> 	* compile/compile-object-run.c (struct do_module_cleanup): Add
> 	constructor, destructor.
> 	<objfile_name_string>: Don't use struct hack.
> 	(do_module_cleanup): Use delete.
> 	(compile_object_run): Use new.
> ---
>  gdb/ChangeLog                    |  8 ++++++++
>  gdb/compile/compile-object-run.c | 24 ++++++++++++++++--------
>  2 files changed, 24 insertions(+), 8 deletions(-)
> 
> diff --git a/gdb/compile/compile-object-run.c b/gdb/compile/compile-object-run.c
> index a2f39900053..4a18655d488 100644
> --- a/gdb/compile/compile-object-run.c
> +++ b/gdb/compile/compile-object-run.c
> @@ -32,6 +32,17 @@
>  
>  struct do_module_cleanup
>  {
> +  do_module_cleanup () = default;
> +
> +  ~do_module_cleanup ()
> +  {
> +    delete munmap_list_head;
> +    xfree (source_file);
> +    xfree (objfile_name_string);
> +  }
> +
> +  DISABLE_COPY_AND_ASSIGN (do_module_cleanup);
> +

Seeing this makes me a bit nervous, as it easily allows the destructor run on an object
whose fields have not been initialized.  So it will call delete/xfree on uninitialized
pointers.  So I'd rather introduce a constructor before introducing a destructor, or
simultaneously.

The next patches touch that code, so I presume that will change.  But I read patches in
a very linear way, so that is my comment at this intermediary point :).

Simon

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PP?] [PATCH 4/6] Transfer module ownership to do_module_cleanup
  2020-08-09 13:52 ` [PATCH 4/6] Transfer module ownership to do_module_cleanup Tom Tromey
@ 2020-08-10  0:48   ` Simon Marchi
  2020-09-23 14:55     ` Tom Tromey
  0 siblings, 1 reply; 15+ messages in thread
From: Simon Marchi @ 2020-08-10  0:48 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches

On 2020-08-09 9:52 a.m., Tom Tromey wrote:
> This changes the do_module_cleanup structure to simply hold on to the
> module itself.  This lets us remove most members from
> do_module_cleanup.
> 
> gdb/ChangeLog
> 2020-08-08  Tom Tromey  <tom@tromey.com>
> 
> 	* compile/compile-object-run.c (struct do_module_cleanup): Add
> 	parameters to constructor.  Update destructor.
> 	<source_file, scope, scope_data, out_value_type, out_value_addr,
> 	munmap_list_head, objfile_name_string>: Remove.
> 	<module>: New member.
> 	(do_module_cleanup): Update.
> 	(compile_object_run): Update.
> ---
>  gdb/ChangeLog                    | 10 +++++
>  gdb/compile/compile-object-run.c | 67 ++++++++++++--------------------
>  2 files changed, 35 insertions(+), 42 deletions(-)
> 
> diff --git a/gdb/compile/compile-object-run.c b/gdb/compile/compile-object-run.c
> index 5a680a6723f..ac0a995fee9 100644
> --- a/gdb/compile/compile-object-run.c
> +++ b/gdb/compile/compile-object-run.c
> @@ -32,13 +32,16 @@
>  
>  struct do_module_cleanup
>  {
> -  do_module_cleanup () = default;
> +  do_module_cleanup (int *ptr, compile_module_up &&mod)
> +    : executedp (ptr),
> +      module (std::move (mod))
> +  {
> +  }
>  
>    ~do_module_cleanup ()
>    {
> -    delete munmap_list_head;
> -    xfree (source_file);
> -    xfree (objfile_name_string);
> +    delete module->munmap_list_head;
> +    xfree (module->source_file);
>    }
>  
>    DISABLE_COPY_AND_ASSIGN (do_module_cleanup);
> @@ -47,22 +50,8 @@ struct do_module_cleanup
>       The pointer may be NULL.  */
>    int *executedp;
>  
> -  /* .c file OBJFILE was built from.  It needs to be xfree-d.  */
> -  char *source_file;
> -
> -  /* Copy from struct compile_module.  */
> -  enum compile_i_scope_types scope;
> -  void *scope_data;
> -
> -  /* Copy from struct compile_module.  */
> -  struct type *out_value_type;
> -  CORE_ADDR out_value_addr;
> -
> -  /* Copy from struct compile_module.  */
> -  struct munmap_list *munmap_list_head;
> -
> -  /* objfile_name of our objfile.  */
> -  char *objfile_name_string;
> +  /* The compile module.  */
> +  compile_module_up module;
>  };
>  
>  /* Cleanup everything after the inferior function dummy frame gets
> @@ -80,22 +69,26 @@ do_module_cleanup (void *arg, int registers_valid)
>  
>        /* This code cannot be in compile_object_run as OUT_VALUE_TYPE
>  	 no longer exists there.  */
> -      if (data->scope == COMPILE_I_PRINT_ADDRESS_SCOPE
> -	  || data->scope == COMPILE_I_PRINT_VALUE_SCOPE)
> +      if (data->module->scope == COMPILE_I_PRINT_ADDRESS_SCOPE
> +	  || data->module->scope == COMPILE_I_PRINT_VALUE_SCOPE)
>  	{
>  	  struct value *addr_value;
> -	  struct type *ptr_type = lookup_pointer_type (data->out_value_type);
> +	  struct type *ptr_type
> +	    = lookup_pointer_type (data->module->out_value_type);
>  
> -	  addr_value = value_from_pointer (ptr_type, data->out_value_addr);
> +	  addr_value = value_from_pointer (ptr_type,
> +					   data->module->out_value_addr);
>  
>  	  /* SCOPE_DATA would be stale unless EXECUTEDP != NULL.  */
> -	  compile_print_value (value_ind (addr_value), data->scope_data);
> +	  compile_print_value (value_ind (addr_value),
> +			       data->module->scope_data);
>  	}
>      }
>  
> +  const char *objfile_name_s = objfile_name (data->module->objfile);
>    for (objfile *objfile : current_program_space->objfiles ())
>      if ((objfile->flags & OBJF_USERLOADED) == 0
> -        && (strcmp (objfile_name (objfile), data->objfile_name_string) == 0))
> +        && (strcmp (objfile_name (objfile), objfile_name_s) == 0))
>        {
>  	objfile->unlink ();
>  
> @@ -106,10 +99,10 @@ do_module_cleanup (void *arg, int registers_valid)
>        }
>  
>    /* Delete the .c file.  */
> -  unlink (data->source_file);
> +  unlink (data->module->source_file);
>  
>    /* Delete the .o file.  */
> -  unlink (data->objfile_name_string);
> +  unlink (objfile_name_s);

The objfile gets destroyed when unlinked.  Is it guaranteed that objfile_name_s is still alive at that point?

Simon

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 1/6] Remove some manual memory management from compile interface
  2020-08-09 22:34   ` Simon Marchi
@ 2020-09-19 23:45     ` Tom Tromey
  2020-09-19 23:52       ` Simon Marchi
  0 siblings, 1 reply; 15+ messages in thread
From: Tom Tromey @ 2020-09-19 23:45 UTC (permalink / raw)
  To: Simon Marchi; +Cc: Tom Tromey, gdb-patches

Simon> You could now remove this `if (num_baseclasses > 0)`, there's no
Simon> reason for it anymore I think.

I looked at this more deeply, and based on the compiler library, I think
the rule is that a 0-length array should be passed as nullptr here:

  status
  marshall (connection *conn, const gcc_vbase_array *a)
  {
    size_t len;

    if (a)
      len = a->n_elements;
    else
      len = (size_t)-1;

    if (!marshall_array_start (conn, 'v', len))
      return FAIL;

    if (!a)
      return OK;
   [...]


So, I changed this code to use your suggestion and then also modified
the final call:

      result = instance->plugin ().start_class_type
	(name.get (), resuld, num_baseclasses > 0 ? &bases : nullptr,
	 filename, line);

This didn't result in any test result changes, but I didn't look to see
if this case is not tested or something like that.

Tom

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 1/6] Remove some manual memory management from compile interface
  2020-09-19 23:45     ` Tom Tromey
@ 2020-09-19 23:52       ` Simon Marchi
  2020-09-23 12:56         ` Tom Tromey
  0 siblings, 1 reply; 15+ messages in thread
From: Simon Marchi @ 2020-09-19 23:52 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches


On 2020-09-19 7:45 p.m., Tom Tromey wrote:
> Simon> You could now remove this `if (num_baseclasses > 0)`, there's no
> Simon> reason for it anymore I think.
>
> I looked at this more deeply, and based on the compiler library, I think
> the rule is that a 0-length array should be passed as nullptr here:
>
>   status
>   marshall (connection *conn, const gcc_vbase_array *a)
>   {
>     size_t len;
>
>     if (a)
>       len = a->n_elements;
>     else
>       len = (size_t)-1;
>
>     if (!marshall_array_start (conn, 'v', len))
>       return FAIL;
>
>     if (!a)
>       return OK;
>    [...]
>
>
> So, I changed this code to use your suggestion and then also modified
> the final call:
>
>       result = instance->plugin ().start_class_type
> 	(name.get (), resuld, num_baseclasses > 0 ? &bases : nullptr,
> 	 filename, line);
>
> This didn't result in any test result changes, but I didn't look to see
> if this case is not tested or something like that.

Oh, I didn't realize that the change I proposed would change how we call
the function.  What you ended up doing makes sense, if that's what's the
compiler library expects.

Simon

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 1/6] Remove some manual memory management from compile interface
  2020-09-19 23:52       ` Simon Marchi
@ 2020-09-23 12:56         ` Tom Tromey
  0 siblings, 0 replies; 15+ messages in thread
From: Tom Tromey @ 2020-09-23 12:56 UTC (permalink / raw)
  To: Simon Marchi; +Cc: Tom Tromey, gdb-patches

>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:

>> This didn't result in any test result changes, but I didn't look to see
>> if this case is not tested or something like that.

Simon> Oh, I didn't realize that the change I proposed would change how we call
Simon> the function.  What you ended up doing makes sense, if that's what's the
Simon> compiler library expects.

I dug even further and found out that the distinction doesn't matter on
the remote end:

    static tree
    start_class_def (tree type,
                     const gcc_vbase_array *base_classes)
    {
      tree bases = NULL;
      if (base_classes)
        {
          for (int i = 0; i < base_classes->n_elements; i++)
            {

So, I am going to change it back to your suggested approach and check it
in.

Tom

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PP?] [PATCH 2/6] Use new/delete for do_module_cleanup
  2020-08-09 22:45   ` [PP?] " Simon Marchi
@ 2020-09-23 13:36     ` Tom Tromey
  0 siblings, 0 replies; 15+ messages in thread
From: Tom Tromey @ 2020-09-23 13:36 UTC (permalink / raw)
  To: Simon Marchi; +Cc: Tom Tromey, gdb-patches

>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:

>> struct do_module_cleanup
>> {
>> +  do_module_cleanup () = default;
>> +
>> +  ~do_module_cleanup ()
>> +  {
>> +    delete munmap_list_head;
>> +    xfree (source_file);
>> +    xfree (objfile_name_string);
>> +  }
>> +
>> +  DISABLE_COPY_AND_ASSIGN (do_module_cleanup);
>> +

Simon> Seeing this makes me a bit nervous, as it easily allows the destructor run on an object
Simon> whose fields have not been initialized.  So it will call delete/xfree on uninitialized
Simon> pointers.  So I'd rather introduce a constructor before introducing a destructor, or
Simon> simultaneously.

Makes sense.  Because this gets reworked in later patches, I've added
initializers to these fields in this patch.  That will avoid the
possibly-uninitialized problem here.

Tom

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PP?] [PATCH 4/6] Transfer module ownership to do_module_cleanup
  2020-08-10  0:48   ` [PP?] " Simon Marchi
@ 2020-09-23 14:55     ` Tom Tromey
  0 siblings, 0 replies; 15+ messages in thread
From: Tom Tromey @ 2020-09-23 14:55 UTC (permalink / raw)
  To: Simon Marchi; +Cc: Tom Tromey, gdb-patches

>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:

>> /* Delete the .o file.  */
>> -  unlink (data->objfile_name_string);
>> +  unlink (objfile_name_s);

Simon> The objfile gets destroyed when unlinked.  Is it guaranteed that
Simon> objfile_name_s is still alive at that point?

Thanks for noticing this.  I've changed it to copy the name locally, and
added a comment explaining why.

Tom

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2020-09-23 14:59 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-09 13:52 [PATCH 0/6] Avoid manual memory management in gdb/compile/ Tom Tromey
2020-08-09 13:52 ` [PATCH 1/6] Remove some manual memory management from compile interface Tom Tromey
2020-08-09 22:34   ` Simon Marchi
2020-09-19 23:45     ` Tom Tromey
2020-09-19 23:52       ` Simon Marchi
2020-09-23 12:56         ` Tom Tromey
2020-08-09 13:52 ` [PATCH 2/6] Use new/delete for do_module_cleanup Tom Tromey
2020-08-09 22:45   ` [PP?] " Simon Marchi
2020-09-23 13:36     ` Tom Tromey
2020-08-09 13:52 ` [PATCH 3/6] Introduce and use compile_module_up Tom Tromey
2020-08-09 13:52 ` [PATCH 4/6] Transfer module ownership to do_module_cleanup Tom Tromey
2020-08-10  0:48   ` [PP?] " Simon Marchi
2020-09-23 14:55     ` Tom Tromey
2020-08-09 13:52 ` [PATCH 5/6] Simplify compile_module cleanup Tom Tromey
2020-08-09 13:52 ` [PATCH 6/6] Avoid manual memory management of argv arrays in gdb/compile Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).