From: Tom Tromey Date: Sat, 15 Oct 2016 15:20:02 +0000 (-0600) Subject: Use unique_xmalloc_ptr in Python code X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9b9720149dfee4a9a961c29d0382fc5bdf9c975b;p=binutils-gdb.git Use unique_xmalloc_ptr in Python code This changes some utility functions in the Python code to return unique_xmalloc_ptr, and then fixes up the callers. I chose unique_xmalloc_ptr rather than std::string because at a few call points the xmalloc'd string is released and ownership transferred elsewhere. This patch found a few existing memory leaks. For example, py-unwind.c called gdbpy_obj_to_string but never freed the result. Built and regression tested on the buildbot. 2016-11-09 Tom Tromey * varobj.h (varobj_get_display_hint): Change return type. * varobj.c (varobj_get_display_hint): Return unique_xmalloc_ptr. (varobj_value_get_print_value): Update. * python/python.c (gdbpy_before_prompt_hook, gdbpy_print_stack) (gdbpy_apply_type_printers): Update. * python/python-internal.h (unicode_to_target_string) (python_string_to_target_string, python_string_to_host_string) (gdbpy_obj_to_string, gdbpy_exception_to_string) (gdbpy_get_display_hint): Change return types. * python/py-varobj.c (py_varobj_iter_next): Update. * python/py-value.c (valpy_getitem, convert_value_from_python): Update. * python/py-utils.c (unicode_to_encoded_string) (unicode_to_target_string, python_string_to_target_string) (python_string_to_host_string, gdbpy_obj_to_string) (gdbpy_exception_to_string): Return unique_xmalloc_ptr. * python/py-unwind.c (pyuw_parse_register_id): Update. * python/py-type.c (typy_getitem): Update. * python/py-prettyprint.c (gdbpy_get_display_hint) (print_stack_unless_memory_error, print_children) (gdbpy_apply_val_pretty_printer): Update. * python/py-param.c (set_parameter_value): Update. (get_doc_string, call_doc_function): Return unique_xmalloc_ptr. (get_set_value, get_show_value, compute_enum_values, parmpy_init): Update. * python/py-infthread.c (thpy_set_name): Update. * python/py-function.c (fnpy_call, fnpy_init): Update. * python/py-framefilter.c (extract_sym): Change "name" to unique_xmalloc_ptr. (enumerate_args, enumerate_locals): Update. (py_print_frame): Use unique_xmalloc_ptr. * python/py-frame.c (frapy_read_var): Update. Remove cleanup. * python/py-cmd.c (cmdpy_function, cmdpy_completer, cmdpy_init): Update. * python/py-breakpoint.c (bppy_set_condition): Use unique_xmalloc_ptr. (bppy_init): Likewise. Remove cleanup. (local_setattro): Update. * mi/mi-cmd-var.c (print_varobj, mi_cmd_var_list_children) (varobj_update_one): Update. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9123596873d..8982d99f7be 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,46 @@ +2016-11-09 Tom Tromey + + * varobj.h (varobj_get_display_hint): Change return type. + * varobj.c (varobj_get_display_hint): Return unique_xmalloc_ptr. + (varobj_value_get_print_value): Update. + * python/python.c (gdbpy_before_prompt_hook, gdbpy_print_stack) + (gdbpy_apply_type_printers): Update. + * python/python-internal.h (unicode_to_target_string) + (python_string_to_target_string, python_string_to_host_string) + (gdbpy_obj_to_string, gdbpy_exception_to_string) + (gdbpy_get_display_hint): Change return types. + * python/py-varobj.c (py_varobj_iter_next): Update. + * python/py-value.c (valpy_getitem, convert_value_from_python): + Update. + * python/py-utils.c (unicode_to_encoded_string) + (unicode_to_target_string, python_string_to_target_string) + (python_string_to_host_string, gdbpy_obj_to_string) + (gdbpy_exception_to_string): Return unique_xmalloc_ptr. + * python/py-unwind.c (pyuw_parse_register_id): Update. + * python/py-type.c (typy_getitem): Update. + * python/py-prettyprint.c (gdbpy_get_display_hint) + (print_stack_unless_memory_error, print_children) + (gdbpy_apply_val_pretty_printer): Update. + * python/py-param.c (set_parameter_value): Update. + (get_doc_string, call_doc_function): Return unique_xmalloc_ptr. + (get_set_value, get_show_value, compute_enum_values, parmpy_init): + Update. + * python/py-infthread.c (thpy_set_name): Update. + * python/py-function.c (fnpy_call, fnpy_init): Update. + * python/py-framefilter.c (extract_sym): Change "name" to + unique_xmalloc_ptr. + (enumerate_args, enumerate_locals): Update. + (py_print_frame): Use unique_xmalloc_ptr. + * python/py-frame.c (frapy_read_var): Update. Remove cleanup. + * python/py-cmd.c (cmdpy_function, cmdpy_completer, cmdpy_init): + Update. + * python/py-breakpoint.c (bppy_set_condition): Use + unique_xmalloc_ptr. + (bppy_init): Likewise. Remove cleanup. + (local_setattro): Update. + * mi/mi-cmd-var.c (print_varobj, mi_cmd_var_list_children) + (varobj_update_one): Update. + 2016-11-09 Pedro Alves * ax-gdb.c (agent_eval_command_one): Use std::move instead of diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c index 147e0265b08..4131f99b2a8 100644 --- a/gdb/mi/mi-cmd-var.c +++ b/gdb/mi/mi-cmd-var.c @@ -50,7 +50,6 @@ print_varobj (struct varobj *var, enum print_values print_values, { struct ui_out *uiout = current_uiout; int thread_id; - char *display_hint; ui_out_field_string (uiout, "name", varobj_get_objname (var)); if (print_expression) @@ -79,12 +78,9 @@ print_varobj (struct varobj *var, enum print_values print_values, if (varobj_get_frozen (var)) ui_out_field_int (uiout, "frozen", 1); - display_hint = varobj_get_display_hint (var); + gdb::unique_xmalloc_ptr display_hint = varobj_get_display_hint (var); if (display_hint) - { - ui_out_field_string (uiout, "displayhint", display_hint); - xfree (display_hint); - } + ui_out_field_string (uiout, "displayhint", display_hint.get ()); if (varobj_is_dynamic_p (var)) ui_out_field_int (uiout, "dynamic", 1); @@ -378,7 +374,6 @@ mi_cmd_var_list_children (char *command, char **argv, int argc) enum print_values print_values; int ix; int from, to; - char *display_hint; if (argc < 1 || argc > 4) error (_("-var-list-children: Usage: " @@ -408,12 +403,9 @@ mi_cmd_var_list_children (char *command, char **argv, int argc) else print_values = PRINT_NO_VALUES; - display_hint = varobj_get_display_hint (var); + gdb::unique_xmalloc_ptr display_hint = varobj_get_display_hint (var); if (display_hint) - { - ui_out_field_string (uiout, "displayhint", display_hint); - xfree (display_hint); - } + ui_out_field_string (uiout, "displayhint", display_hint.get ()); if (from < to) { @@ -721,7 +713,6 @@ varobj_update_one (struct varobj *var, enum print_values print_values, for (i = 0; VEC_iterate (varobj_update_result, changes, i, r); ++i) { - char *display_hint; int from, to; struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); @@ -767,12 +758,10 @@ varobj_update_one (struct varobj *var, enum print_values print_values, ui_out_field_int (uiout, "new_num_children", varobj_get_num_children (r->varobj)); - display_hint = varobj_get_display_hint (r->varobj); + gdb::unique_xmalloc_ptr display_hint + = varobj_get_display_hint (r->varobj); if (display_hint) - { - ui_out_field_string (uiout, "displayhint", display_hint); - xfree (display_hint); - } + ui_out_field_string (uiout, "displayhint", display_hint.get ()); if (varobj_is_dynamic_p (r->varobj)) ui_out_field_int (uiout, "dynamic", 1); diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index e61cbcddaf9..0897acf7389 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -440,7 +440,8 @@ bppy_get_condition (PyObject *self, void *closure) static int bppy_set_condition (PyObject *self, PyObject *newvalue, void *closure) { - char *exp; + gdb::unique_xmalloc_ptr exp_holder; + const char *exp = NULL; gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self; struct gdb_exception except = exception_none; @@ -456,9 +457,10 @@ bppy_set_condition (PyObject *self, PyObject *newvalue, void *closure) exp = ""; else { - exp = python_string_to_host_string (newvalue); - if (exp == NULL) + exp_holder = python_string_to_host_string (newvalue); + if (exp_holder == NULL) return -1; + exp = exp_holder.get (); } TRY @@ -471,9 +473,6 @@ bppy_set_condition (PyObject *self, PyObject *newvalue, void *closure) } END_CATCH - if (newvalue != Py_None) - xfree (exp); - GDB_PY_SET_HANDLE_EXCEPTION (except); return 0; @@ -680,18 +679,20 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) TRY { - char *copy = xstrdup (skip_spaces_const (spec)); - struct cleanup *cleanup = make_cleanup (xfree, copy); + gdb::unique_xmalloc_ptr + copy_holder (xstrdup (skip_spaces_const (spec))); + char *copy = copy_holder.get (); switch (type) { case bp_breakpoint: { struct event_location *location; + struct cleanup *cleanup; location = string_to_event_location_basic (©, current_language); - make_cleanup_delete_event_location (location); + cleanup = make_cleanup_delete_event_location (location); create_breakpoint (python_gdbarch, location, NULL, -1, NULL, 0, @@ -700,6 +701,8 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) AUTO_BOOLEAN_TRUE, &bkpt_breakpoint_ops, 0, 1, internal_bp, 0); + + do_cleanups (cleanup); break; } case bp_watchpoint: @@ -717,8 +720,6 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) default: error(_("Do not understand breakpoint type to set.")); } - - do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) { @@ -1043,7 +1044,7 @@ static int local_setattro (PyObject *self, PyObject *name, PyObject *v) { gdbpy_breakpoint_object *obj = (gdbpy_breakpoint_object *) self; - char *attr = python_string_to_host_string (name); + gdb::unique_xmalloc_ptr attr (python_string_to_host_string (name)); if (attr == NULL) return -1; @@ -1051,7 +1052,7 @@ local_setattro (PyObject *self, PyObject *name, PyObject *v) /* If the attribute trying to be set is the "stop" method, but we already have a condition set in the CLI or other extension language, disallow this operation. */ - if (strcmp (attr, stop_func) == 0) + if (strcmp (attr.get (), stop_func) == 0) { const struct extension_language_defn *extlang = NULL; @@ -1063,7 +1064,6 @@ local_setattro (PyObject *self, PyObject *name, PyObject *v) { char *error_text; - xfree (attr); error_text = xstrprintf (_("Only one stop condition allowed. There is" " currently a %s stop condition defined for" @@ -1075,8 +1075,6 @@ local_setattro (PyObject *self, PyObject *name, PyObject *v) } } - xfree (attr); - return PyObject_GenericSetAttr ((PyObject *)self, name, v); } diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c index af6c5cfa7e0..83337899c28 100644 --- a/gdb/python/py-cmd.c +++ b/gdb/python/py-cmd.c @@ -156,7 +156,6 @@ cmdpy_function (struct cmd_list_element *command, char *args, int from_tty) if (! result) { PyObject *ptype, *pvalue, *ptraceback; - char *msg; PyErr_Fetch (&ptype, &pvalue, &ptraceback); @@ -164,8 +163,8 @@ cmdpy_function (struct cmd_list_element *command, char *args, int from_tty) When fetching the error message we need to make our own copy, we no longer own ptype, pvalue after the call to PyErr_Restore. */ - msg = gdbpy_exception_to_string (ptype, pvalue); - make_cleanup (xfree, msg); + gdb::unique_xmalloc_ptr + msg (gdbpy_exception_to_string (ptype, pvalue)); if (msg == NULL) { @@ -190,7 +189,7 @@ cmdpy_function (struct cmd_list_element *command, char *args, int from_tty) PyErr_Restore (ptype, pvalue, ptraceback); gdbpy_print_stack (); if (msg != NULL && *msg != '\0') - error (_("Error occurred in Python command: %s"), msg); + error (_("Error occurred in Python command: %s"), msg.get ()); else error (_("Error occurred in Python command.")); } @@ -199,7 +198,7 @@ cmdpy_function (struct cmd_list_element *command, char *args, int from_tty) Py_XDECREF (ptype); Py_XDECREF (pvalue); Py_XDECREF (ptraceback); - error ("%s", msg); + error ("%s", msg.get ()); } } @@ -374,7 +373,6 @@ cmdpy_completer (struct cmd_list_element *command, while ((elt = PyIter_Next (iter)) != NULL) { - char *item; if (! gdbpy_is_string (elt)) { @@ -382,7 +380,8 @@ cmdpy_completer (struct cmd_list_element *command, Py_DECREF (elt); continue; } - item = python_string_to_host_string (elt); + gdb::unique_xmalloc_ptr + item (python_string_to_host_string (elt)); Py_DECREF (elt); if (item == NULL) { @@ -390,7 +389,7 @@ cmdpy_completer (struct cmd_list_element *command, PyErr_Clear (); continue; } - VEC_safe_push (char_ptr, result, item); + VEC_safe_push (char_ptr, result, item.release ()); } Py_DECREF (iter); @@ -604,7 +603,7 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw) if (ds_obj && gdbpy_is_string (ds_obj)) { - docstring = python_string_to_host_string (ds_obj); + docstring = python_string_to_host_string (ds_obj).release (); if (docstring == NULL) { xfree (cmd_name); diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c index a66f88555ff..7c958036f83 100644 --- a/gdb/python/py-frame.c +++ b/gdb/python/py-frame.c @@ -514,13 +514,11 @@ frapy_read_var (PyObject *self, PyObject *args) var = symbol_object_to_symbol (sym_obj); else if (gdbpy_is_string (sym_obj)) { - char *var_name; - struct cleanup *cleanup; + gdb::unique_xmalloc_ptr + var_name (python_string_to_target_string (sym_obj)); - var_name = python_string_to_target_string (sym_obj); if (!var_name) return NULL; - cleanup = make_cleanup (xfree, var_name); if (block_obj) { @@ -529,7 +527,6 @@ frapy_read_var (PyObject *self, PyObject *args) { PyErr_SetString (PyExc_RuntimeError, _("Second argument must be block.")); - do_cleanups (cleanup); return NULL; } } @@ -541,13 +538,12 @@ frapy_read_var (PyObject *self, PyObject *args) if (!block) block = get_frame_block (frame, NULL); - lookup_sym = lookup_symbol (var_name, block, VAR_DOMAIN, NULL); + lookup_sym = lookup_symbol (var_name.get (), block, VAR_DOMAIN, NULL); var = lookup_sym.symbol; block = lookup_sym.block; } CATCH (except, RETURN_MASK_ALL) { - do_cleanups (cleanup); gdbpy_convert_exception (except); return NULL; } @@ -556,13 +552,10 @@ frapy_read_var (PyObject *self, PyObject *args) if (!var) { PyErr_Format (PyExc_ValueError, - _("Variable '%s' not found."), var_name); - do_cleanups (cleanup); + _("Variable '%s' not found."), var_name.get ()); return NULL; } - - do_cleanups (cleanup); } else { diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c index 4c7757cbb93..3beea129f21 100644 --- a/gdb/python/py-framefilter.c +++ b/gdb/python/py-framefilter.c @@ -52,8 +52,9 @@ enum mi_print_types appropriate Python exception set, and EXT_LANG_BT_OK on success. */ static enum ext_lang_bt_status -extract_sym (PyObject *obj, char **name, struct symbol **sym, - struct block **sym_block, const struct language_defn **language) +extract_sym (PyObject *obj, gdb::unique_xmalloc_ptr *name, + struct symbol **sym, struct block **sym_block, + const struct language_defn **language) { PyObject *result = PyObject_CallMethod (obj, "symbol", NULL); @@ -101,7 +102,7 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym, /* Duplicate the symbol name, so the caller has consistency in garbage collection. */ - *name = xstrdup (SYMBOL_PRINT_NAME (*sym)); + name->reset (xstrdup (SYMBOL_PRINT_NAME (*sym))); /* If a symbol is specified attempt to determine the language from the symbol. If mode is not "auto", then the language @@ -538,7 +539,7 @@ enumerate_args (PyObject *iter, while (item) { const struct language_defn *language; - char *sym_name; + gdb::unique_xmalloc_ptr sym_name; struct symbol *sym; struct block *sym_block; struct value *val; @@ -554,7 +555,6 @@ enumerate_args (PyObject *iter, success = extract_value (item, &val); if (success == EXT_LANG_BT_ERROR) { - xfree (sym_name); Py_DECREF (item); goto error; } @@ -564,10 +564,7 @@ enumerate_args (PyObject *iter, if (sym && ui_out_is_mi_like_p (out) && ! mi_should_print (sym, MI_PRINT_ARGS)) - { - xfree (sym_name); - continue; - } + continue; /* If the object did not provide a value, read it using read_frame_args and account for entry values, if any. */ @@ -581,7 +578,6 @@ enumerate_args (PyObject *iter, { PyErr_SetString (PyExc_RuntimeError, _("No symbol or value provided.")); - xfree (sym_name); goto error; } @@ -591,7 +587,6 @@ enumerate_args (PyObject *iter, } CATCH (except, RETURN_MASK_ALL) { - xfree (sym_name); gdbpy_convert_exception (except); goto error; } @@ -611,7 +606,6 @@ enumerate_args (PyObject *iter, { xfree (arg.error); xfree (entryarg.error); - xfree (sym_name); goto error; } } @@ -629,7 +623,6 @@ enumerate_args (PyObject *iter, { xfree (arg.error); xfree (entryarg.error); - xfree (sym_name); gdbpy_convert_exception (except); goto error; } @@ -642,7 +635,6 @@ enumerate_args (PyObject *iter, { xfree (arg.error); xfree (entryarg.error); - xfree (sym_name); goto error; } } @@ -655,18 +647,13 @@ enumerate_args (PyObject *iter, /* If the object has provided a value, we just print that. */ if (val != NULL) { - if (py_print_single_arg (out, sym_name, NULL, val, &opts, + if (py_print_single_arg (out, sym_name.get (), NULL, val, &opts, args_type, print_args_field, language) == EXT_LANG_BT_ERROR) - { - xfree (sym_name); - goto error; - } + goto error; } } - xfree (sym_name); - /* Collect the next item from the iterator. If this is the last item, do not print the comma. */ @@ -736,7 +723,7 @@ enumerate_locals (PyObject *iter, while ((item = PyIter_Next (iter))) { const struct language_defn *language; - char *sym_name; + gdb::unique_xmalloc_ptr sym_name; struct value *val; enum ext_lang_bt_status success = EXT_LANG_BT_ERROR; struct symbol *sym; @@ -753,8 +740,6 @@ enumerate_locals (PyObject *iter, goto error; } - make_cleanup (xfree, sym_name); - success = extract_value (item, &val); if (success == EXT_LANG_BT_ERROR) { @@ -801,7 +786,7 @@ enumerate_locals (PyObject *iter, ui_out_spaces (out, local_indent); } - ui_out_field_string (out, "name", sym_name); + ui_out_field_string (out, "name", sym_name.get ()); if (! ui_out_is_mi_like_p (out)) ui_out_text (out, " = "); @@ -1033,6 +1018,7 @@ py_print_frame (PyObject *filter, int flags, struct value_print_options opts; PyObject *py_inf_frame; int print_level, print_frame_info, print_args, print_locals; + gdb::unique_xmalloc_ptr function_to_free; /* Extract print settings from FLAGS. */ print_level = (flags & PRINT_LEVEL) ? 1 : 0; @@ -1205,17 +1191,15 @@ py_print_frame (PyObject *filter, int flags, if (gdbpy_is_string (py_func)) { - char *function_to_free; - - function = function_to_free = - python_string_to_host_string (py_func); + function_to_free = python_string_to_host_string (py_func); - if (function == NULL) + if (function_to_free == NULL) { do_cleanups (cleanup_stack); return EXT_LANG_BT_ERROR; } - make_cleanup (xfree, function_to_free); + + function = function_to_free.get (); } else if (PyLong_Check (py_func)) { @@ -1302,7 +1286,8 @@ py_print_frame (PyObject *filter, int flags, if (py_fn != Py_None) { - char *filename = python_string_to_host_string (py_fn); + gdb::unique_xmalloc_ptr + filename (python_string_to_host_string (py_fn)); if (filename == NULL) { @@ -1310,13 +1295,12 @@ py_print_frame (PyObject *filter, int flags, return EXT_LANG_BT_ERROR; } - make_cleanup (xfree, filename); TRY { ui_out_wrap_hint (out, " "); ui_out_text (out, " at "); annotate_frame_source_file (); - ui_out_field_string (out, "file", filename); + ui_out_field_string (out, "file", filename.get ()); annotate_frame_source_file_end (); } CATCH (except, RETURN_MASK_ERROR) diff --git a/gdb/python/py-function.c b/gdb/python/py-function.c index d42dbdeb758..800605ab50f 100644 --- a/gdb/python/py-function.c +++ b/gdb/python/py-function.c @@ -94,7 +94,6 @@ fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language, if (!result) { PyObject *ptype, *pvalue, *ptraceback; - char *msg; PyErr_Fetch (&ptype, &pvalue, &ptraceback); @@ -102,8 +101,8 @@ fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language, When fetching the error message we need to make our own copy, we no longer own ptype, pvalue after the call to PyErr_Restore. */ - msg = gdbpy_exception_to_string (ptype, pvalue); - make_cleanup (xfree, msg); + gdb::unique_xmalloc_ptr + msg (gdbpy_exception_to_string (ptype, pvalue)); if (msg == NULL) { @@ -131,7 +130,7 @@ fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language, gdbpy_print_stack (); if (msg != NULL && *msg != '\0') error (_("Error occurred in Python convenience function: %s"), - msg); + msg.get ()); else error (_("Error occurred in Python convenience function.")); } @@ -140,7 +139,7 @@ fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language, Py_XDECREF (ptype); Py_XDECREF (pvalue); Py_XDECREF (ptraceback); - error ("%s", msg); + error ("%s", msg.get ()); } } @@ -165,7 +164,7 @@ static int fnpy_init (PyObject *self, PyObject *args, PyObject *kwds) { const char *name; - char *docstring = NULL; + gdb::unique_xmalloc_ptr docstring; if (! PyArg_ParseTuple (args, "s", &name)) return -1; @@ -191,9 +190,9 @@ fnpy_init (PyObject *self, PyObject *args, PyObject *kwds) } } if (! docstring) - docstring = xstrdup (_("This function is not documented.")); + docstring.reset (xstrdup (_("This function is not documented."))); - add_internal_function (name, docstring, fnpy_call, self); + add_internal_function (name, docstring.release (), fnpy_call, self); return 0; } diff --git a/gdb/python/py-infthread.c b/gdb/python/py-infthread.c index 697298d19dd..3cc359c4a79 100644 --- a/gdb/python/py-infthread.c +++ b/gdb/python/py-infthread.c @@ -80,7 +80,7 @@ static int thpy_set_name (PyObject *self, PyObject *newvalue, void *ignore) { thread_object *thread_obj = (thread_object *) self; - char *name; + gdb::unique_xmalloc_ptr name; if (! thread_obj->thread) { @@ -95,7 +95,9 @@ thpy_set_name (PyObject *self, PyObject *newvalue, void *ignore) return -1; } else if (newvalue == Py_None) - name = NULL; + { + /* Nothing. */ + } else if (! gdbpy_is_string (newvalue)) { PyErr_SetString (PyExc_TypeError, @@ -110,7 +112,7 @@ thpy_set_name (PyObject *self, PyObject *newvalue, void *ignore) } xfree (thread_obj->thread->name); - thread_obj->thread->name = name; + thread_obj->thread->name = name.release (); return 0; } diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c index 3604f9f52aa..0d19c97efb8 100644 --- a/gdb/python/py-param.c +++ b/gdb/python/py-param.c @@ -148,21 +148,19 @@ set_parameter_value (parmpy_object *self, PyObject *value) } else { - char *string; - - string = python_string_to_host_string (value); + gdb::unique_xmalloc_ptr + string (python_string_to_host_string (value)); if (string == NULL) return -1; xfree (self->value.stringval); - self->value.stringval = string; + self->value.stringval = string.release (); } break; case var_enum: { int i; - char *str; if (! gdbpy_is_string (value)) { @@ -171,13 +169,13 @@ set_parameter_value (parmpy_object *self, PyObject *value) return -1; } - str = python_string_to_host_string (value); + gdb::unique_xmalloc_ptr + str (python_string_to_host_string (value)); if (str == NULL) return -1; for (i = 0; self->enumeration[i]; ++i) - if (! strcmp (self->enumeration[i], str)) + if (! strcmp (self->enumeration[i], str.get ())) break; - xfree (str); if (! self->enumeration[i]) { PyErr_SetString (PyExc_RuntimeError, @@ -301,10 +299,10 @@ set_attr (PyObject *obj, PyObject *attr_name, PyObject *val) /* A helper function which returns a documentation string for an object. */ -static char * +static gdb::unique_xmalloc_ptr get_doc_string (PyObject *object, PyObject *attr) { - char *result = NULL; + gdb::unique_xmalloc_ptr result; if (PyObject_HasAttr (object, attr)) { @@ -319,7 +317,7 @@ get_doc_string (PyObject *object, PyObject *attr) Py_XDECREF (ds_obj); } if (! result) - result = xstrdup (_("This command is not documented.")); + result.reset (xstrdup (_("This command is not documented."))); return result; } @@ -327,10 +325,10 @@ get_doc_string (PyObject *object, PyObject *attr) argument ARG. ARG can be NULL. METHOD should return a Python string. If this function returns NULL, there has been an error and the appropriate exception set. */ -static char * +static gdb::unique_xmalloc_ptr call_doc_function (PyObject *obj, PyObject *method, PyObject *arg) { - char *data = NULL; + gdb::unique_xmalloc_ptr data; PyObject *result = PyObject_CallMethodObjArgs (obj, method, arg, NULL); if (! result) @@ -365,7 +363,7 @@ get_set_value (char *args, int from_tty, struct cmd_list_element *c) { PyObject *obj = (PyObject *) get_cmd_context (c); - char *set_doc_string; + gdb::unique_xmalloc_ptr set_doc_string; struct cleanup *cleanup = ensure_python_env (get_current_arch (), current_language); PyObject *set_doc_func = PyString_FromString ("get_set_string"); @@ -387,8 +385,7 @@ get_set_value (char *args, int from_tty, set_doc_string = get_doc_string (obj, set_doc_cst); } - make_cleanup (xfree, set_doc_string); - fprintf_filtered (gdb_stdout, "%s\n", set_doc_string); + fprintf_filtered (gdb_stdout, "%s\n", set_doc_string.get ()); Py_XDECREF (set_doc_func); do_cleanups (cleanup); @@ -413,7 +410,7 @@ get_show_value (struct ui_file *file, int from_tty, const char *value) { PyObject *obj = (PyObject *) get_cmd_context (c); - char *show_doc_string = NULL; + gdb::unique_xmalloc_ptr show_doc_string; struct cleanup *cleanup = ensure_python_env (get_current_arch (), current_language); PyObject *show_doc_func = PyString_FromString ("get_show_string"); @@ -433,9 +430,7 @@ get_show_value (struct ui_file *file, int from_tty, if (! show_doc_string) goto error; - make_cleanup (xfree, show_doc_string); - - fprintf_filtered (file, "%s\n", show_doc_string); + fprintf_filtered (file, "%s\n", show_doc_string.get ()); } else { @@ -443,8 +438,7 @@ get_show_value (struct ui_file *file, int from_tty, callback function does not exist, then attempt to read the show_doc attribute. */ show_doc_string = get_doc_string (obj, show_doc_cst); - make_cleanup (xfree, show_doc_string); - fprintf_filtered (file, "%s %s\n", show_doc_string, value); + fprintf_filtered (file, "%s %s\n", show_doc_string.get (), value); } Py_XDECREF (show_doc_func); @@ -614,7 +608,7 @@ compute_enum_values (parmpy_object *self, PyObject *enum_values) _("The enumeration item not a string.")); return 0; } - self->enumeration[i] = python_string_to_host_string (item); + self->enumeration[i] = python_string_to_host_string (item).release (); Py_DECREF (item); if (self->enumeration[i] == NULL) { @@ -716,9 +710,9 @@ parmpy_init (PyObject *self, PyObject *args, PyObject *kwds) if (! cmd_name) return -1; - set_doc = get_doc_string (self, set_doc_cst); - show_doc = get_doc_string (self, show_doc_cst); - doc = get_doc_string (self, gdbpy_doc_cst); + set_doc = get_doc_string (self, set_doc_cst).release (); + show_doc = get_doc_string (self, show_doc_cst).release (); + doc = get_doc_string (self, gdbpy_doc_cst).release (); Py_INCREF (self); diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c index 88343443583..3c6a5afe402 100644 --- a/gdb/python/py-prettyprint.c +++ b/gdb/python/py-prettyprint.c @@ -244,11 +244,11 @@ pretty_print_one_value (PyObject *printer, struct value **out_value) NULL if there is no display_hint method, or if the method did not return a string. On error, print stack trace and return NULL. On success, return an xmalloc()d string. */ -char * +gdb::unique_xmalloc_ptr gdbpy_get_display_hint (PyObject *printer) { PyObject *hint; - char *result = NULL; + gdb::unique_xmalloc_ptr result; if (! PyObject_HasAttr (printer, gdbpy_display_hint_cst)) return NULL; @@ -279,20 +279,20 @@ print_stack_unless_memory_error (struct ui_file *stream) { struct cleanup *cleanup; PyObject *type, *value, *trace; - char *msg; PyErr_Fetch (&type, &value, &trace); cleanup = make_cleanup_py_decref (type); make_cleanup_py_decref (value); make_cleanup_py_decref (trace); - msg = gdbpy_exception_to_string (type, value); - make_cleanup (xfree, msg); + gdb::unique_xmalloc_ptr + msg (gdbpy_exception_to_string (type, value)); if (msg == NULL || *msg == '\0') fprintf_filtered (stream, _("")); else - fprintf_filtered (stream, _(""), msg); + fprintf_filtered (stream, _(""), + msg.get ()); do_cleanups (cleanup); } @@ -647,16 +647,13 @@ print_children (PyObject *printer, const char *hint, } else if (gdbpy_is_string (py_v)) { - char *output; + gdb::unique_xmalloc_ptr output; output = python_string_to_host_string (py_v); if (!output) gdbpy_print_stack (); else - { - fputs_filtered (output, stream); - xfree (output); - } + fputs_filtered (output.get (), stream); } else { @@ -713,7 +710,7 @@ gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang, PyObject *printer = NULL; PyObject *val_obj = NULL; struct value *value; - char *hint = NULL; + gdb::unique_xmalloc_ptr hint; struct cleanup *cleanups; enum ext_lang_rc result = EXT_LANG_RC_NOP; enum string_repr_result print_result; @@ -767,13 +764,12 @@ gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang, /* If we are printing a map, we want some special formatting. */ hint = gdbpy_get_display_hint (printer); - make_cleanup (free_current_contents, &hint); /* Print the section */ - print_result = print_string_repr (printer, hint, stream, recurse, + print_result = print_string_repr (printer, hint.get (), stream, recurse, options, language, gdbarch); if (print_result != string_repr_error) - print_children (printer, hint, stream, recurse, options, language, + print_children (printer, hint.get (), stream, recurse, options, language, print_result == string_repr_none); result = EXT_LANG_RC_OK; diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c index da9dadd2fb0..17fa297960b 100644 --- a/gdb/python/py-type.c +++ b/gdb/python/py-type.c @@ -1197,10 +1197,9 @@ static PyObject * typy_getitem (PyObject *self, PyObject *key) { struct type *type = ((type_object *) self)->type; - char *field; int i; - field = python_string_to_host_string (key); + gdb::unique_xmalloc_ptr field = python_string_to_host_string (key); if (field == NULL) return NULL; @@ -1216,7 +1215,7 @@ typy_getitem (PyObject *self, PyObject *key) { const char *t_field_name = TYPE_FIELD_NAME (type, i); - if (t_field_name && (strcmp_iw (t_field_name, field) == 0)) + if (t_field_name && (strcmp_iw (t_field_name, field.get ()) == 0)) { return convert_field (type, i); } diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c index 64c3123c2fd..52184bd4e0d 100644 --- a/gdb/python/py-unwind.c +++ b/gdb/python/py-unwind.c @@ -116,12 +116,12 @@ pyuw_parse_register_id (struct gdbarch *gdbarch, PyObject *pyo_reg_id, return 0; if (gdbpy_is_string (pyo_reg_id)) { - const char *reg_name = gdbpy_obj_to_string (pyo_reg_id); + gdb::unique_xmalloc_ptr reg_name (gdbpy_obj_to_string (pyo_reg_id)); if (reg_name == NULL) return 0; - *reg_num = user_reg_map_name_to_regnum (gdbarch, reg_name, - strlen (reg_name)); + *reg_num = user_reg_map_name_to_regnum (gdbarch, reg_name.get (), + strlen (reg_name.get ())); return *reg_num >= 0; } else if (PyInt_Check (pyo_reg_id)) diff --git a/gdb/python/py-utils.c b/gdb/python/py-utils.c index 2e2121d6d68..9f99e2934d3 100644 --- a/gdb/python/py-utils.c +++ b/gdb/python/py-utils.c @@ -107,10 +107,10 @@ python_string_to_unicode (PyObject *obj) conversion, NULL will be returned and a python exception will be set. The caller is responsible for xfree'ing the string. */ -static char * +static gdb::unique_xmalloc_ptr unicode_to_encoded_string (PyObject *unicode_str, const char *charset) { - char *result; + gdb::unique_xmalloc_ptr result; PyObject *string; /* Translate string to named charset. */ @@ -119,9 +119,9 @@ unicode_to_encoded_string (PyObject *unicode_str, const char *charset) return NULL; #ifdef IS_PY3K - result = xstrdup (PyBytes_AsString (string)); + result.reset (xstrdup (PyBytes_AsString (string))); #else - result = xstrdup (PyString_AsString (string)); + result.reset (xstrdup (PyString_AsString (string))); #endif Py_DECREF (string); @@ -140,12 +140,11 @@ unicode_to_encoded_python_string (PyObject *unicode_str, const char *charset) return PyUnicode_AsEncodedString (unicode_str, charset, NULL); } -/* Returns a newly allocated string with the contents of the given unicode - string object converted to the target's charset. If an error occurs during - the conversion, NULL will be returned and a python exception will be set. - - The caller is responsible for xfree'ing the string. */ -char * +/* Returns a newly allocated string with the contents of the given + unicode string object converted to the target's charset. If an + error occurs during the conversion, NULL will be returned and a + python exception will be set. */ +gdb::unique_xmalloc_ptr unicode_to_target_string (PyObject *unicode_str) { return unicode_to_encoded_string (unicode_str, @@ -164,20 +163,18 @@ unicode_to_target_python_string (PyObject *unicode_str) } /* Converts a python string (8-bit or unicode) to a target string in - the target's charset. Returns NULL on error, with a python exception set. - - The caller is responsible for xfree'ing the string. */ -char * + the target's charset. Returns NULL on error, with a python + exception set. */ +gdb::unique_xmalloc_ptr python_string_to_target_string (PyObject *obj) { PyObject *str; - char *result; str = python_string_to_unicode (obj); if (str == NULL) return NULL; - result = unicode_to_target_string (str); + gdb::unique_xmalloc_ptr result (unicode_to_target_string (str)); Py_DECREF (str); return result; } @@ -203,20 +200,19 @@ python_string_to_target_python_string (PyObject *obj) } /* Converts a python string (8-bit or unicode) to a target string in - the host's charset. Returns NULL on error, with a python exception set. - - The caller is responsible for xfree'ing the string. */ -char * + the host's charset. Returns NULL on error, with a python exception + set. */ +gdb::unique_xmalloc_ptr python_string_to_host_string (PyObject *obj) { PyObject *str; - char *result; str = python_string_to_unicode (obj); if (str == NULL) return NULL; - result = unicode_to_encoded_string (str, host_charset ()); + gdb::unique_xmalloc_ptr + result (unicode_to_encoded_string (str, host_charset ())); Py_DECREF (str); return result; } @@ -243,20 +239,21 @@ gdbpy_is_string (PyObject *obj) } /* Return the string representation of OBJ, i.e., str (obj). - Space for the result is malloc'd, the caller must free. If the result is NULL a python error occurred, the caller must clear it. */ -char * +gdb::unique_xmalloc_ptr gdbpy_obj_to_string (PyObject *obj) { PyObject *str_obj = PyObject_Str (obj); if (str_obj != NULL) { + gdb::unique_xmalloc_ptr msg; + #ifdef IS_PY3K - char *msg = python_string_to_host_string (str_obj); + msg = python_string_to_host_string (str_obj); #else - char *msg = xstrdup (PyString_AsString (str_obj)); + msg.reset (xstrdup (PyString_AsString (str_obj))); #endif Py_DECREF (str_obj); @@ -269,14 +266,11 @@ gdbpy_obj_to_string (PyObject *obj) /* Return the string representation of the exception represented by TYPE, VALUE which is assumed to have been obtained with PyErr_Fetch, i.e., the error indicator is currently clear. - Space for the result is malloc'd, the caller must free. If the result is NULL a python error occurred, the caller must clear it. */ -char * +gdb::unique_xmalloc_ptr gdbpy_exception_to_string (PyObject *ptype, PyObject *pvalue) { - char *str; - /* There are a few cases to consider. For example: pvalue is a string when PyErr_SetString is used. @@ -288,11 +282,9 @@ gdbpy_exception_to_string (PyObject *ptype, PyObject *pvalue) gdb.GdbError ("message"). */ if (pvalue && pvalue != Py_None) - str = gdbpy_obj_to_string (pvalue); + return gdbpy_obj_to_string (pvalue); else - str = gdbpy_obj_to_string (ptype); - - return str; + return gdbpy_obj_to_string (ptype); } /* Convert a GDB exception to the appropriate Python exception. diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index 926a09c8512..b959f2e10dd 100644 --- a/gdb/python/py-value.c +++ b/gdb/python/py-value.c @@ -667,7 +667,7 @@ valpy_getitem (PyObject *self, PyObject *key) { struct gdb_exception except = exception_none; value_object *self_value = (value_object *) self; - char *field = NULL; + gdb::unique_xmalloc_ptr field; struct type *base_class_type = NULL, *field_type = NULL; long bitpos = -1; PyObject *result = NULL; @@ -754,7 +754,7 @@ valpy_getitem (PyObject *self, PyObject *key) struct value *res_val = NULL; if (field) - res_val = value_struct_elt (&tmp, NULL, field, NULL, + res_val = value_struct_elt (&tmp, NULL, field.get (), NULL, "struct/class/union"); else if (bitpos >= 0) res_val = value_struct_elt_bitpos (&tmp, bitpos, field_type, @@ -804,7 +804,6 @@ valpy_getitem (PyObject *self, PyObject *key) } END_CATCH - xfree (field); GDB_PY_HANDLE_EXCEPTION (except); return result; @@ -1663,17 +1662,11 @@ convert_value_from_python (PyObject *obj) } else if (gdbpy_is_string (obj)) { - char *s; - - s = python_string_to_target_string (obj); + gdb::unique_xmalloc_ptr s + = python_string_to_target_string (obj); if (s != NULL) - { - struct cleanup *old; - - old = make_cleanup (xfree, s); - value = value_cstring (s, strlen (s), builtin_type_pychar); - do_cleanups (old); - } + value = value_cstring (s.get (), strlen (s.get ()), + builtin_type_pychar); } else if (PyObject_TypeCheck (obj, &value_object_type)) value = value_copy (((value_object *) obj)->value); diff --git a/gdb/python/py-varobj.c b/gdb/python/py-varobj.c index a6b1968aefd..72c876ce82a 100644 --- a/gdb/python/py-varobj.c +++ b/gdb/python/py-varobj.c @@ -75,10 +75,11 @@ py_varobj_iter_next (struct varobj_iter *self) if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error)) { PyObject *type, *value, *trace; - char *name_str, *value_str; + char *name_str; PyErr_Fetch (&type, &value, &trace); - value_str = gdbpy_exception_to_string (type, value); + gdb::unique_xmalloc_ptr + value_str (gdbpy_exception_to_string (type, value)); Py_XDECREF (type); Py_XDECREF (value); Py_XDECREF (trace); @@ -90,9 +91,8 @@ py_varobj_iter_next (struct varobj_iter *self) name_str = xstrprintf ("", self->next_raw_index++); - item = Py_BuildValue ("(ss)", name_str, value_str); + item = Py_BuildValue ("(ss)", name_str, value_str.get ()); xfree (name_str); - xfree (value_str); if (item == NULL) { gdbpy_print_stack (); diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index 8545c7bae0c..f3213bb82eb 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -533,14 +533,15 @@ int gdbpy_print_python_errors_p (void); void gdbpy_print_stack (void); PyObject *python_string_to_unicode (PyObject *obj); -char *unicode_to_target_string (PyObject *unicode_str); -char *python_string_to_target_string (PyObject *obj); +gdb::unique_xmalloc_ptr unicode_to_target_string (PyObject *unicode_str); +gdb::unique_xmalloc_ptr python_string_to_target_string (PyObject *obj); PyObject *python_string_to_target_python_string (PyObject *obj); -char *python_string_to_host_string (PyObject *obj); +gdb::unique_xmalloc_ptr python_string_to_host_string (PyObject *obj); PyObject *host_string_to_python_string (const char *str); int gdbpy_is_string (PyObject *obj); -char *gdbpy_obj_to_string (PyObject *obj); -char *gdbpy_exception_to_string (PyObject *ptype, PyObject *pvalue); +gdb::unique_xmalloc_ptr gdbpy_obj_to_string (PyObject *obj); +gdb::unique_xmalloc_ptr gdbpy_exception_to_string (PyObject *ptype, + PyObject *pvalue); int gdbpy_is_lazy_string (PyObject *result); void gdbpy_extract_lazy_string (PyObject *string, CORE_ADDR *addr, @@ -555,7 +556,7 @@ PyObject *apply_varobj_pretty_printer (PyObject *print_obj, struct value **replacement, struct ui_file *stream); PyObject *gdbpy_get_varobj_pretty_printer (struct value *value); -char *gdbpy_get_display_hint (PyObject *printer); +gdb::unique_xmalloc_ptr gdbpy_get_display_hint (PyObject *printer); PyObject *gdbpy_default_visualizer (PyObject *self, PyObject *args); void bpfinishpy_pre_stop_hook (struct gdbpy_breakpoint_object *bp_obj); diff --git a/gdb/python/python.c b/gdb/python/python.c index d9940c2cdf9..321479bffdb 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -1020,7 +1020,7 @@ gdbpy_before_prompt_hook (const struct extension_language_defn *extlang, const char *current_gdb_prompt) { struct cleanup *cleanup; - char *prompt = NULL; + gdb::unique_xmalloc_ptr prompt; if (!gdb_python_initialized) return EXT_LANG_RC_NOP; @@ -1073,8 +1073,6 @@ gdbpy_before_prompt_hook (const struct extension_language_defn *extlang, if (prompt == NULL) goto fail; - else - make_cleanup (xfree, prompt); } } } @@ -1082,7 +1080,7 @@ gdbpy_before_prompt_hook (const struct extension_language_defn *extlang, /* If a prompt has been set, PROMPT will not be NULL. If it is NULL, do not set the prompt. */ if (prompt != NULL) - set_prompt (prompt); + set_prompt (prompt.get ()); do_cleanups (cleanup); return prompt != NULL ? EXT_LANG_RC_OK : EXT_LANG_RC_NOP; @@ -1213,13 +1211,13 @@ gdbpy_print_stack (void) else { PyObject *ptype, *pvalue, *ptraceback; - char *msg = NULL, *type = NULL; PyErr_Fetch (&ptype, &pvalue, &ptraceback); /* Fetch the error message contained within ptype, pvalue. */ - msg = gdbpy_exception_to_string (ptype, pvalue); - type = gdbpy_obj_to_string (ptype); + gdb::unique_xmalloc_ptr + msg (gdbpy_exception_to_string (ptype, pvalue)); + gdb::unique_xmalloc_ptr type (gdbpy_obj_to_string (ptype)); TRY { @@ -1233,7 +1231,7 @@ gdbpy_print_stack (void) } else fprintf_filtered (gdb_stderr, "Python Exception %s %s: \n", - type, msg); + type.get (), msg.get ()); } CATCH (except, RETURN_MASK_ALL) { @@ -1243,7 +1241,6 @@ gdbpy_print_stack (void) Py_XDECREF (ptype); Py_XDECREF (pvalue); Py_XDECREF (ptraceback); - xfree (msg); } } @@ -1448,7 +1445,7 @@ gdbpy_apply_type_printers (const struct extension_language_defn *extlang, PyObject *type_obj, *type_module = NULL, *func = NULL; PyObject *result_obj = NULL; PyObject *printers_obj = (PyObject *) ext_printers->py_type_printers; - char *result = NULL; + gdb::unique_xmalloc_ptr result; if (printers_obj == NULL) return EXT_LANG_RC_NOP; @@ -1501,8 +1498,11 @@ gdbpy_apply_type_printers (const struct extension_language_defn *extlang, Py_XDECREF (result_obj); do_cleanups (cleanups); if (result != NULL) - *prettied_type = result; - return result != NULL ? EXT_LANG_RC_OK : EXT_LANG_RC_ERROR; + { + *prettied_type = result.release (); + return EXT_LANG_RC_OK; + } + return EXT_LANG_RC_ERROR; } /* Free the result of start_type_printers. diff --git a/gdb/varobj.c b/gdb/varobj.c index afd82d25046..03edf0eb969 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -557,10 +557,10 @@ varobj_get_display_format (const struct varobj *var) return var->format; } -char * +gdb::unique_xmalloc_ptr varobj_get_display_hint (const struct varobj *var) { - char *result = NULL; + gdb::unique_xmalloc_ptr result; #if HAVE_PYTHON struct cleanup *back_to; @@ -2484,26 +2484,25 @@ varobj_value_get_print_value (struct value *value, string_print. Otherwise just return the extracted string as a value. */ - char *s = python_string_to_target_string (output); + gdb::unique_xmalloc_ptr s + = python_string_to_target_string (output); if (s) { struct gdbarch *gdbarch; - char *hint; - hint = gdbpy_get_display_hint (value_formatter); + gdb::unique_xmalloc_ptr hint + = gdbpy_get_display_hint (value_formatter); if (hint) { - if (!strcmp (hint, "string")) + if (!strcmp (hint.get (), "string")) string_print = 1; - xfree (hint); } - thevalue = std::string (s); + thevalue = std::string (s.get ()); len = thevalue.size (); gdbarch = get_type_arch (value_type (value)); type = builtin_type (gdbarch)->builtin_char; - xfree (s); if (!string_print) { diff --git a/gdb/varobj.h b/gdb/varobj.h index 7f4aad24209..df5c6cb3f08 100644 --- a/gdb/varobj.h +++ b/gdb/varobj.h @@ -264,7 +264,8 @@ extern void varobj_get_child_range (const struct varobj *var, int *from, extern void varobj_set_child_range (struct varobj *var, int from, int to); -extern char *varobj_get_display_hint (const struct varobj *var); +extern gdb::unique_xmalloc_ptr + varobj_get_display_hint (const struct varobj *var); extern int varobj_get_num_children (struct varobj *var);