Avoid some manual memory management in Python

This changes a few places in the Python code to avoid manual memory
management, in favor of letting std::string do the work.

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

	* python/python.c (compute_python_string): Return std::string.
	(gdbpy_eval_from_control_command): Update.
	(do_start_initialization): Use std::string.
	* python/py-varobj.c (py_varobj_iter_next): Use string_printf, not
	xstrprintf.
	* python/py-breakpoint.c (local_setattro): Use string_printf, not
	xstrprintf.
This commit is contained in:
Tom Tromey 2017-04-30 22:10:41 -06:00
parent 3c9ebddd93
commit 7f968c899f
4 changed files with 29 additions and 42 deletions

View file

@ -1,3 +1,13 @@
2017-08-03 Tom Tromey <tom@tromey.com>
* python/python.c (compute_python_string): Return std::string.
(gdbpy_eval_from_control_command): Update.
(do_start_initialization): Use std::string.
* python/py-varobj.c (py_varobj_iter_next): Use string_printf, not
xstrprintf.
* python/py-breakpoint.c (local_setattro): Use string_printf, not
xstrprintf.
2017-08-03 Tom Tromey <tom@tromey.com> 2017-08-03 Tom Tromey <tom@tromey.com>
* top.h (do_restore_instream_cleanup): Remove. * top.h (do_restore_instream_cleanup): Remove.

View file

@ -1026,15 +1026,12 @@ local_setattro (PyObject *self, PyObject *name, PyObject *v)
extlang = get_breakpoint_cond_ext_lang (obj->bp, EXT_LANG_PYTHON); extlang = get_breakpoint_cond_ext_lang (obj->bp, EXT_LANG_PYTHON);
if (extlang != NULL) if (extlang != NULL)
{ {
char *error_text; std::string error_text
= string_printf (_("Only one stop condition allowed. There is"
error_text " currently a %s stop condition defined for"
= xstrprintf (_("Only one stop condition allowed. There is" " this breakpoint."),
" currently a %s stop condition defined for" ext_lang_capitalized_name (extlang));
" this breakpoint."), PyErr_SetString (PyExc_RuntimeError, error_text.c_str ());
ext_lang_capitalized_name (extlang));
PyErr_SetString (PyExc_RuntimeError, error_text);
xfree (error_text);
return -1; return -1;
} }
} }

View file

@ -71,7 +71,6 @@ py_varobj_iter_next (struct varobj_iter *self)
if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error)) if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error))
{ {
PyObject *type, *value, *trace; PyObject *type, *value, *trace;
char *name_str;
PyErr_Fetch (&type, &value, &trace); PyErr_Fetch (&type, &value, &trace);
gdb::unique_xmalloc_ptr<char> gdb::unique_xmalloc_ptr<char>
@ -85,10 +84,10 @@ py_varobj_iter_next (struct varobj_iter *self)
return NULL; return NULL;
} }
name_str = xstrprintf ("<error at %d>", std::string name_str = string_printf ("<error at %d>",
self->next_raw_index++); self->next_raw_index++);
item.reset (Py_BuildValue ("(ss)", name_str, value_str.get ())); item.reset (Py_BuildValue ("(ss)", name_str.c_str (),
xfree (name_str); value_str.get ()));
if (item == NULL) if (item == NULL)
{ {
gdbpy_print_stack (); gdbpy_print_stack ();

View file

@ -365,32 +365,19 @@ python_run_simple_file (FILE *file, const char *filename)
} }
/* Given a command_line, return a command string suitable for passing /* Given a command_line, return a command string suitable for passing
to Python. Lines in the string are separated by newlines. The to Python. Lines in the string are separated by newlines. */
return value is allocated using xmalloc and the caller is
responsible for freeing it. */
static char * static std::string
compute_python_string (struct command_line *l) compute_python_string (struct command_line *l)
{ {
struct command_line *iter; struct command_line *iter;
char *script = NULL; std::string script;
int size = 0;
int here;
for (iter = l; iter; iter = iter->next)
size += strlen (iter->line) + 1;
script = (char *) xmalloc (size + 1);
here = 0;
for (iter = l; iter; iter = iter->next) for (iter = l; iter; iter = iter->next)
{ {
int len = strlen (iter->line); script += iter->line;
script += '\n';
strcpy (&script[here], iter->line);
here += len;
script[here++] = '\n';
} }
script[here] = '\0';
return script; return script;
} }
@ -402,16 +389,14 @@ gdbpy_eval_from_control_command (const struct extension_language_defn *extlang,
struct command_line *cmd) struct command_line *cmd)
{ {
int ret; int ret;
char *script;
if (cmd->body_count != 1) if (cmd->body_count != 1)
error (_("Invalid \"python\" block structure.")); error (_("Invalid \"python\" block structure."));
gdbpy_enter enter_py (get_current_arch (), current_language); gdbpy_enter enter_py (get_current_arch (), current_language);
script = compute_python_string (cmd->body_list[0]); std::string script = compute_python_string (cmd->body_list[0]);
ret = PyRun_SimpleString (script); ret = PyRun_SimpleString (script.c_str ());
xfree (script);
if (ret) if (ret)
error (_("Error while executing Python code.")); error (_("Error while executing Python code."));
} }
@ -1532,7 +1517,6 @@ do_start_initialization ()
#ifdef IS_PY3K #ifdef IS_PY3K
int i; int i;
size_t progsize, count; size_t progsize, count;
char *oldloc;
wchar_t *progname_copy; wchar_t *progname_copy;
#endif #endif
@ -1546,25 +1530,22 @@ do_start_initialization ()
progname = concat (ldirname (python_libdir).c_str (), SLASH_STRING, "bin", progname = concat (ldirname (python_libdir).c_str (), SLASH_STRING, "bin",
SLASH_STRING, "python", (char *) NULL); SLASH_STRING, "python", (char *) NULL);
#ifdef IS_PY3K #ifdef IS_PY3K
oldloc = xstrdup (setlocale (LC_ALL, NULL)); std::string oldloc = setlocale (LC_ALL, NULL);
setlocale (LC_ALL, ""); setlocale (LC_ALL, "");
progsize = strlen (progname); progsize = strlen (progname);
progname_copy = (wchar_t *) PyMem_Malloc ((progsize + 1) * sizeof (wchar_t)); progname_copy = (wchar_t *) PyMem_Malloc ((progsize + 1) * sizeof (wchar_t));
if (!progname_copy) if (!progname_copy)
{ {
xfree (oldloc);
fprintf (stderr, "out of memory\n"); fprintf (stderr, "out of memory\n");
return false; return false;
} }
count = mbstowcs (progname_copy, progname, progsize + 1); count = mbstowcs (progname_copy, progname, progsize + 1);
if (count == (size_t) -1) if (count == (size_t) -1)
{ {
xfree (oldloc);
fprintf (stderr, "Could not convert python path to string\n"); fprintf (stderr, "Could not convert python path to string\n");
return false; return false;
} }
setlocale (LC_ALL, oldloc); setlocale (LC_ALL, oldloc.c_str ());
xfree (oldloc);
/* Note that Py_SetProgramName expects the string it is passed to /* Note that Py_SetProgramName expects the string it is passed to
remain alive for the duration of the program's execution, so remain alive for the duration of the program's execution, so