This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

FYI: fix Python API usage buglets


I am checking this in on the trunk.

Today I tried out David Malcolm's GCC plugin:

    https://fedorahosted.org/gcc-python-plugin/

It has a checker for PyArg_ParseTuple usage; this detected a number of
buglets in GDB.

Most of the fixes are in the Python code, but in one case I chose to
constify some APIs in the core.

Also, in some places we now copy strings where we previously did not.  I
think cleaning this up would be a nice future cleanup, perhaps for an
intern or new developer.  Right now there is no guarantee that an
expression parser or command implementation will not write to a string;
but enforcing this as a rule seems like a better programming practice.

Built and regtested by the buildbot.

Tom

2011-06-24  Tom Tromey  <tromey@redhat.com>

	* varobj.c (update_dynamic_varobj_children): Make 'name' const.
	* symtab.h (lookup_struct, lookup_union, lookup_enum): Update.
	* python/python.c (gdbpy_parameter): Make 'arg' const.
	(execute_gdb_command): Likewise.
	(gdbpy_decode_line): Likewise.  Copy it.
	(gdbpy_parse_and_eval): Make 'expr_string' const.  Copy it.
	(gdbpy_write): Make 'arg' const.
	* python/py-type.c (typy_lookup_typename): Make 'type_name'
	const.
	(gdbpy_lookup_type): Likewise.
	* python/py-prettyprint.c (print_children): Make 'name' const.
	* python/py-param.c (parmpy_init): Make 'name' const.  Copy it.
	* python/py-inferior.c (infpy_write_memory): Make 'buf_len' a
	Py_ssize_t.
	* python/py-function.c (fnpy_init): Make 'name' const.
	* python/py-cmd.c (cmdpy_init): Make 'name' const.  Copy it.
	(gdbpy_string_to_argv): Make 'input' const.
	* python/py-breakpoint.c (bppy_init): Make 'spec' const.  Copy
	it.
	* gdbtypes.h (lookup_typename): Update.
	* gdbtypes.c (lookup_typename): Make 'name' const.
	(lookup_struct): Likewise.
	(lookup_union): Likewise.
	(lookup_enum): Likewise.

diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 2572046..da9bade 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1137,7 +1137,7 @@ type_name_no_tag_or_error (struct type *type)
 
 struct type *
 lookup_typename (const struct language_defn *language,
-		 struct gdbarch *gdbarch, char *name,
+		 struct gdbarch *gdbarch, const char *name,
 		 const struct block *block, int noerr)
 {
   struct symbol *sym;
@@ -1194,7 +1194,7 @@ lookup_signed_typename (const struct language_defn *language,
    visible in lexical block BLOCK.  */
 
 struct type *
-lookup_struct (char *name, struct block *block)
+lookup_struct (const char *name, struct block *block)
 {
   struct symbol *sym;
 
@@ -1216,7 +1216,7 @@ lookup_struct (char *name, struct block *block)
    visible in lexical block BLOCK.  */
 
 struct type *
-lookup_union (char *name, struct block *block)
+lookup_union (const char *name, struct block *block)
 {
   struct symbol *sym;
   struct type *t;
@@ -1241,7 +1241,7 @@ lookup_union (char *name, struct block *block)
    visible in lexical block BLOCK.  */
 
 struct type *
-lookup_enum (char *name, struct block *block)
+lookup_enum (const char *name, struct block *block)
 {
   struct symbol *sym;
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 60da35b..3b62453 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1405,7 +1405,7 @@ extern void check_stub_method_group (struct type *, int);
 extern char *gdb_mangle_name (struct type *, int, int);
 
 extern struct type *lookup_typename (const struct language_defn *,
-				     struct gdbarch *, char *,
+				     struct gdbarch *, const char *,
 				     const struct block *, int);
 
 extern struct type *lookup_template_type (char *, struct type *,
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index 9c33848..e73dc24 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -599,7 +599,7 @@ static int
 bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
 {
   static char *keywords[] = { "spec", "type", "wp_class", "internal", NULL };
-  char *spec;
+  const char *spec;
   int type = bp_breakpoint;
   int access_type = hw_write;
   PyObject *internal = NULL;
@@ -623,12 +623,15 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
   
   TRY_CATCH (except, RETURN_MASK_ALL)
     {
+      char *copy = xstrdup (spec);
+      struct cleanup *cleanup = make_cleanup (xfree, copy);
+
       switch (type)
 	{
 	case bp_breakpoint:
 	  {
 	    create_breakpoint (python_gdbarch,
-			       spec, NULL, -1,
+			       copy, NULL, -1,
 			       0,
 			       0, bp_breakpoint,
 			       0,
@@ -639,11 +642,11 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
         case bp_watchpoint:
 	  {
 	    if (access_type == hw_write)
-	      watch_command_wrapper (spec, 0, internal_bp);
+	      watch_command_wrapper (copy, 0, internal_bp);
 	    else if (access_type == hw_access)
-	      awatch_command_wrapper (spec, 0, internal_bp);
+	      awatch_command_wrapper (copy, 0, internal_bp);
 	    else if (access_type == hw_read)
-	      rwatch_command_wrapper (spec, 0, internal_bp);
+	      rwatch_command_wrapper (copy, 0, internal_bp);
 	    else
 	      error(_("Cannot understand watchpoint access type."));
 	    break;
@@ -651,6 +654,8 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
 	default:
 	  error(_("Do not understand breakpoint type to set."));
 	}
+
+      do_cleanups (cleanup);
     }
   if (except.reason < 0)
     {
diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index c0e3291..20933fd 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -405,7 +405,8 @@ static int
 cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
 {
   cmdpy_object *obj = (cmdpy_object *) self;
-  char *name;
+  const char *name;
+  char *copy;
   int cmdtype;
   int completetype = -1;
   char *docstring = NULL;
@@ -449,7 +450,9 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
       return -1;
     }
 
-  cmd_name = gdbpy_parse_command_name (name, &cmd_list, &cmdlist);
+  copy = xstrdup (name);
+  cmd_name = gdbpy_parse_command_name (copy, &cmd_list, &cmdlist);
+  xfree (copy);
   if (! cmd_name)
     return -1;
 
@@ -659,7 +662,7 @@ PyObject *
 gdbpy_string_to_argv (PyObject *self, PyObject *args)
 {
   PyObject *py_argv;
-  char *input;
+  const char *input;
 
   if (!PyArg_ParseTuple (args, "s", &input))
     return NULL;
diff --git a/gdb/python/py-function.c b/gdb/python/py-function.c
index 0c3e6f2..5cdf190 100644
--- a/gdb/python/py-function.c
+++ b/gdb/python/py-function.c
@@ -150,7 +150,8 @@ fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language,
 static int
 fnpy_init (PyObject *self, PyObject *args, PyObject *kwds)
 {
-  char *name, *docstring = NULL;
+  const char *name;
+  char *docstring = NULL;
 
   if (! PyArg_ParseTuple (args, "s", &name))
     return -1;
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index da0a4b6..f226501 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -428,7 +428,8 @@ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
 static PyObject *
 infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
 {
-  int buf_len, error = 0;
+  Py_ssize_t buf_len;
+  int error = 0;
   const char *buffer;
   CORE_ADDR addr, length;
   PyObject *addr_obj, *length_obj = NULL;
diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c
index 4d873d8..5c726d6 100644
--- a/gdb/python/py-param.c
+++ b/gdb/python/py-param.c
@@ -645,7 +645,8 @@ static int
 parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
 {
   parmpy_object *obj = (parmpy_object *) self;
-  char *name;
+  const char *name;
+  char *copy;
   char *set_doc, *show_doc, *doc;
   char *cmd_name;
   int parmclass, cmdtype;
@@ -696,16 +697,21 @@ parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
   obj->type = (enum var_types) parmclass;
   memset (&obj->value, 0, sizeof (obj->value));
 
-  cmd_name = gdbpy_parse_command_name (name, &set_list,
+  copy = xstrdup (name);
+  cmd_name = gdbpy_parse_command_name (copy, &set_list,
 				       &setlist);
 
   if (! cmd_name)
-    return -1;
+    {
+      xfree (copy);
+      return -1;
+    }
   xfree (cmd_name);
-  cmd_name = gdbpy_parse_command_name (name, &show_list,
+  cmd_name = gdbpy_parse_command_name (copy, &show_list,
 				       &showlist);
   if (! cmd_name)
     return -1;
+  xfree (copy);
 
   set_doc = get_doc_string (self, set_doc_cst);
   show_doc = get_doc_string (self, show_doc_cst);
diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c
index a657432..b3660de 100644
--- a/gdb/python/py-prettyprint.c
+++ b/gdb/python/py-prettyprint.c
@@ -526,7 +526,7 @@ print_children (PyObject *printer, const char *hint,
   for (i = 0; i < options->print_max; ++i)
     {
       PyObject *py_v, *item = PyIter_Next (iter);
-      char *name;
+      const char *name;
       struct cleanup *inner_cleanup;
 
       if (! item)
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index c010420..8ab18cf 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -497,7 +497,7 @@ typy_get_sizeof (PyObject *self, void *closure)
 }
 
 static struct type *
-typy_lookup_typename (char *type_name, struct block *block)
+typy_lookup_typename (const char *type_name, struct block *block)
 {
   struct type *type = NULL;
   volatile struct gdb_exception except;
@@ -1020,7 +1020,7 @@ PyObject *
 gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw)
 {
   static char *keywords[] = { "name", "block", NULL };
-  char *type_name = NULL;
+  const char *type_name = NULL;
   struct type *type = NULL;
   PyObject *block_obj = NULL;
   struct block *block = NULL;
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 8a7bc66..ddfe9ba 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -290,7 +290,8 @@ PyObject *
 gdbpy_parameter (PyObject *self, PyObject *args)
 {
   struct cmd_list_element *alias, *prefix, *cmd;
-  char *arg, *newarg;
+  const char *arg;
+  char *newarg;
   int found = -1;
   volatile struct gdb_exception except;
 
@@ -340,7 +341,7 @@ gdbpy_target_wide_charset (PyObject *self, PyObject *args)
 static PyObject *
 execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
 {
-  char *arg;
+  const char *arg;
   PyObject *from_tty_obj = NULL, *to_string_obj = NULL;
   int from_tty, to_string;
   volatile struct gdb_exception except;
@@ -434,7 +435,7 @@ gdbpy_decode_line (PyObject *self, PyObject *args)
   struct symtabs_and_lines sals = { NULL, 0 }; /* Initialize to
 						  appease gcc.  */
   struct symtab_and_line sal;
-  char *arg = NULL;
+  const char *arg = NULL;
   char *copy = NULL;
   struct cleanup *cleanups;
   PyObject *result = NULL;
@@ -451,9 +452,8 @@ gdbpy_decode_line (PyObject *self, PyObject *args)
     {
       if (arg)
 	{
-	  arg = xstrdup (arg);
-	  make_cleanup (xfree, arg);
-	  copy = arg;
+	  copy = xstrdup (arg);
+	  make_cleanup (xfree, copy);
 	  sals = decode_line_1 (&copy, 0, 0, 0, 0);
 	  make_cleanup (xfree, sals.sals);
 	}
@@ -531,7 +531,7 @@ gdbpy_decode_line (PyObject *self, PyObject *args)
 static PyObject *
 gdbpy_parse_and_eval (PyObject *self, PyObject *args)
 {
-  char *expr_str;
+  const char *expr_str;
   struct value *result = NULL;
   volatile struct gdb_exception except;
 
@@ -540,7 +540,11 @@ gdbpy_parse_and_eval (PyObject *self, PyObject *args)
 
   TRY_CATCH (except, RETURN_MASK_ALL)
     {
-      result = parse_and_eval (expr_str);
+      char *copy = xstrdup (expr_str);
+      struct cleanup *cleanup = make_cleanup (xfree, copy);
+
+      result = parse_and_eval (copy);
+      do_cleanups (cleanup);
     }
   GDB_PY_HANDLE_EXCEPTION (except);
 
@@ -687,7 +691,7 @@ gdbpy_initialize_events (void)
 static PyObject *
 gdbpy_write (PyObject *self, PyObject *args, PyObject *kw)
 {
-  char *arg;
+  const char *arg;
   static char *keywords[] = {"text", "stream", NULL };
   int stream_type = 0;
   
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 2716f34..4f96398 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -934,11 +934,11 @@ extern struct symbol *lookup_block_symbol (const struct block *, const char *,
 
 /* lookup a [struct, union, enum] by name, within a specified block.  */
 
-extern struct type *lookup_struct (char *, struct block *);
+extern struct type *lookup_struct (const char *, struct block *);
 
-extern struct type *lookup_union (char *, struct block *);
+extern struct type *lookup_union (const char *, struct block *);
 
-extern struct type *lookup_enum (char *, struct block *);
+extern struct type *lookup_enum (const char *, struct block *);
 
 /* from blockframe.c: */
 
diff --git a/gdb/varobj.c b/gdb/varobj.c
index e068823..07dbc27 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -1085,7 +1085,7 @@ update_dynamic_varobj_children (struct varobj *var,
       if (to < 0 || i < to)
 	{
 	  PyObject *py_v;
-	  char *name;
+	  const char *name;
 	  struct value *v;
 	  struct cleanup *inner;
 	  int can_mention = from < 0 || i >= from;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]