From 8455d26243aef72f7b827ec0d8367b6b7816de07 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Thu, 6 Jul 2017 00:19:24 +0100 Subject: Fix Python unwinder frames regression The gdb.python/py-unwind.exp test is crashing GDB / leaving core dumps in the test dir, even though it all passes cleanly. The crash is not visible in gdb.sum/gdb.log because it happens as side effect of the "quit" command, while flushing the frame cache. The problem is simply a typo in a 'for' loop's condition, introduced by a recent change [4fa847d78edd ("Remove MAX_REGISTER_SIZE from py-unwind.c")], resulting in infinite loop / double-free. The new test exposes the crash, like: Running src/gdb/testsuite/gdb.python/py-unwind.exp ... ERROR: Process no longer exists gdb/ChangeLog: 2017-07-06 Pedro Alves * python/py-unwind.c (pyuw_dealloc_cache): Fix for loop condition. gdb/testsuite/ChangeLog: 2017-07-06 Pedro Alves * gdb.python/py-unwind.exp: Test flushregs. --- gdb/python/py-unwind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gdb/python') diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c index 1d800a7..acfce7d 100644 --- a/gdb/python/py-unwind.c +++ b/gdb/python/py-unwind.c @@ -595,7 +595,7 @@ pyuw_dealloc_cache (struct frame_info *this_frame, void *cache) TRACE_PY_UNWIND (3, "%s: enter", __FUNCTION__); cached_frame_info *cached_frame = (cached_frame_info *) cache; - for (int i = 0; cached_frame->reg_count; i++) + for (int i = 0; i < cached_frame->reg_count; i++) xfree (cached_frame->reg[i].data); xfree (cache); -- cgit v1.1 From 78b13106edcd14d87b4cc0b7f8dce8db8c2be489 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Mon, 17 Jul 2017 11:55:42 +0100 Subject: Rename make_symbol_completion_list_fn -> symbol_completer "make_symbol_completion_list_fn" is odly named when you look at a list of "standard" completers, like the Python/Guile completer lists adjusted by this patch. Rename / move it to completers.h/c, for consistency. gdb/ChangeLog: 2017-07-17 Pedro Alves * completer.c (symbol_completer): New function, based on make_symbol_completion_list_fn. * completer.h (symbol_completer): New declaration. * guile/scm-cmd.c (cmdscm_completers): Adjust. * python/py-cmd.c (completers): Adjust. * symtab.c (make_symbol_completion_list_fn): Delete. * symtab.h (make_symbol_completion_list_fn): Delete. * cli/cli-decode.c (add_cmd): Adjust. --- gdb/python/py-cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gdb/python') diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c index 6203211..72ea577 100644 --- a/gdb/python/py-cmd.c +++ b/gdb/python/py-cmd.c @@ -44,7 +44,7 @@ static const struct cmdpy_completer completers[] = { "COMPLETE_FILENAME", filename_completer }, { "COMPLETE_LOCATION", location_completer }, { "COMPLETE_COMMAND", command_completer }, - { "COMPLETE_SYMBOL", make_symbol_completion_list_fn }, + { "COMPLETE_SYMBOL", symbol_completer }, { "COMPLETE_EXPRESSION", expression_completer }, }; -- cgit v1.1 From 6e1dbf8cda1c66256179d0b15c96bc97ea5cf7b3 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Mon, 17 Jul 2017 12:05:03 +0100 Subject: Clean up "completer_handle_brkchars" callback handling This patch cleans up "completer_handle_brkchars" callback handling: - Renames the function typedef to better match its intent: completer_ftype_void -> completer_handle_brkchars_ftype - Factors out common code in complete_line_internal handling the "handle_brkchars" callback to a separate function. - Centralizes all the "completer method" to "handle_brkchars method" mapping in a single function. gdb/ChangeLog: 2017-07-17 Pedro Alves * cli/cli-decode.c (set_cmd_completer_handle_brkchars): Adjust to renames. * cli/cli-decode.h (struct cmd_list_element) : Move comments to completer_ftype's declaration. : Change type to completer_handle_brkchars_ftype. * command.h (completer_ftype): Add describing comment and give names to parameters. (completer_ftype_void): Rename to ... (completer_handle_brkchars_ftype) ... this. Add describing comment. (set_cmd_completer_handle_brkchars): Adjust. * completer.c (filename_completer_handle_brkchars): New function. (complete_line_internal_normal_command): New function, factored out from ... (complete_line_internal): ... here. (command_completer_handle_brkchars) (default_completer_handle_brkchars) (completer_handle_brkchars_func_for_completer): New functions. * completer.h (set_gdb_completion_word_break_characters): Delete declaration. (completer_handle_brkchars_func_for_completer): New declaration. * python/py-cmd.c (cmdpy_completer_handle_brkchars): Adjust to use completer_handle_brkchars_func_for_completer. --- gdb/python/py-cmd.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c index 72ea577..b9a866e 100644 --- a/gdb/python/py-cmd.c +++ b/gdb/python/py-cmd.c @@ -293,11 +293,14 @@ cmdpy_completer_handle_brkchars (struct cmd_list_element *command, } else if (value >= 0 && value < (long) N_COMPLETERS) { + completer_handle_brkchars_ftype *brkchars_fn; + /* This is the core of this function. Depending on which completer type the Python function returns, we have to adjust the break characters accordingly. */ - set_gdb_completion_word_break_characters - (completers[value].completer); + brkchars_fn = (completer_handle_brkchars_func_for_completer + (completers[value].completer)); + brkchars_fn (command, text, word); } } } -- cgit v1.1 From eb3ff9a55175dcdac8328b558d54951a14d719b1 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Mon, 17 Jul 2017 14:45:59 +0100 Subject: Introduce class completion_tracker & rewrite completion<->readline interaction This patch reworks the whole completion machinery, and prepares it for later enhancements. Adds a new "completion_tracker" class that is meant to hold everything about the state of the current completion operation. This class now has the responsibility of tracking the list of completion matches, and checking whether the max completions limit has been reached. You can look at this as this patch starting out by C++fying the existing "completion_tracker" in symtab.c (it's just an htab_t typedef currently), moving it to completer.h/c, and then making it a class/generalizing/enhancing it. Unlike with the current tracking, completion_tracker now checks whether the limit has been reached on each completion match list insertion. This both simplifies the max-completions handling code (maybe_add_completion_enum is gone, for example), and is a prerequisite for follow up patches. The current completion_tracker is only used for symbol completions, and the symbol code gets at the current instance via globals. This patch cleans that up by adding a completion_tracker reference to the signature of the completion functions, and passing the tracker around everywhere necessary. Then, the patch changes how the completion match list is handed over to readline. Currently, we're using the rl_completion_entry_function readline entry point, and the patch switches to rl_attempted_completion_function. A following patch will want to let GDB itself decide the common completion prefix between all matches (what readline calls the "lowest common denominator"), instead of having readline compute it, and that's not possible with the rl_completion_entry_function entry point. Also, rl_attempted_completion_function lets GDB hand over the match list to readline as an array in one go instead of passing down matches one by one, so from that angle it's a nicer entry point anyway. Lastly, the patch catches exceptions around the readline entry points, because we can't let C++ exceptions cross readline. We handle that in the readline input entry point, but the completion entry point isn't guarded, so GDB can abort if completion throws. E.g., in current master: (gdb) b -function "fun terminate called after throwing an instance of 'gdb_exception_RETURN_MASK_ERROR' Aborted (core dumped) This patch fixes that. This will be exercised in the new tests added later on in the series. gdb/ChangeLog: 2017-07-17 Pedro Alves * ada-lang.c (symbol_completion_match): Adjust comments. (symbol_completion_add): Replace vector parameter with completion_tracker parameter. Use it. (ada_make_symbol_completion_list): Rename to... (ada_collect_symbol_completion_matches): ... this. Add completion_tracker parameter and use it. (ada_language_defn): Adjust. * break-catch-syscall.c (catch_syscall_completer): Adjust prototype and work with completion_tracker instead of VEC. * breakpoint.c (condition_completer): Adjust prototype and work with completion_tracker instead of VEC. * c-lang.c (c_language_defn, cplus_language_defn) (asm_language_defn, minimal_language_defn): Adjust to renames. * cli/cli-cmds.c (complete_command): Rework using completion_tracker. Catch exceptions when completing. * cli/cli-decode.c (integer_unlimited_completer) (complete_on_cmdlist, complete_on_enum): Adjust prototype and work with completion_tracker instead of VEC. * command.h (struct completion_tracker): Forward declare. (completer_ftype, completer_handle_brkchars_ftype): Change types. (complete_on_cmdlist, complete_on_enum): Adjust. * completer.c: Include . (struct gdb_completer_state): New. (current_completion): New global. (readline_line_completion_function): Delete. (noop_completer, filename_completer) (filename_completer_handle_brkchars, complete_files_symbols) (linespec_location_completer): Adjust to work with a completion_tracker instead of a VEC. (string_or_empty): New. (collect_explicit_location_matches): Adjust to work with a completion_tracker instead of a VEC. (explicit_location_completer): Rename to ... (complete_explicit_location): ... this and adjust to work with a completion_tracker instead of a VEC. (location_completer): Adjust to work with a completion_tracker instead of a VEC. (add_struct_fields): Adjust to work with a completion_list instead of VEC. (expression_completer): Rename to ... (complete_expression): ... this and adjust to work with a completion_tracker instead of a VEC. Use complete_files_symbols. (expression_completer): Reimplement on top of complete_expression. (symbol_completer): Adjust to work with a completion_tracker instead of a VEC. (enum complete_line_internal_reason): Add describing comments. (complete_line_internal_normal_command): Adjust to work with a completion_tracker instead of a VEC. (complete_line_internal): Rename to ... (complete_line_internal_1): ... this and adjust to work with a completion_tracker instead of a VEC. Assert TEXT is NULL in the handle_brkchars phase. (new_completion_tracker): Delete. (complete_line_internal): Reimplement as TRY/CATCH wrapper around complete_line_internal_1. (free_completion_tracker): Delete. (INITIAL_COMPLETION_HTAB_SIZE): New. (completion_tracker::completion_tracker) (completion_tracker::~completion_tracker): New. (maybe_add_completion): Delete. (completion_tracker::maybe_add_completion) (completion_tracker::add_completion) (completion_tracker::add_completions): New. (throw_max_completions_reached_error): Delete. (complete_line): Adjust to work with a completion_tracker instead of a VEC. Don't create a completion_tracker_t or check for max completions here. (command_completer, command_completer_handle_brkchars) (signal_completer, reg_or_group_completer_1) (reg_or_group_completer, default_completer_handle_brkchars): Adjust to work with a completion_tracker. (gdb_completion_word_break_characters_throw): New. (gdb_completion_word_break_characters): Reimplement. (line_completion_function): Delete. (completion_tracker::recompute_lowest_common_denominator) (expand_preserving_ws) (completion_tracker::build_completion_result) (completion_result::completion_result) (completion_result::completion_result) (completion_result::~completion_result) (completion_result::completion_result) (completion_result::release_match_list, compare_cstrings) (completion_result::sort_match_list) (completion_result::reset_match_list) (gdb_rl_attempted_completion_function_throw) (gdb_rl_attempted_completion_function): New. * completer.h (completion_list, struct completion_result) (class completion_tracker): New. (complete_line): Add completion_tracker parameter. (readline_line_completion_function): Delete. (gdb_rl_attempted_completion_function): New. (noop_completer, filename_completer, expression_completer) (location_completer, symbol_completer, command_completer) (signal_completer, reg_or_group_completer): Update prototypes. (completion_tracker_t, new_completion_tracker) (make_cleanup_free_completion_tracker): Delete. (enum maybe_add_completion_enum): Delete. (maybe_add_completion): Delete. (throw_max_completions_reached_error): Delete. * corefile.c (complete_set_gnutarget): Adjust to work with a completion_tracker instead of a VEC. * cp-abi.c (cp_abi_completer): Adjust to work with a completion_tracker instead of a VEC. * d-lang.c (d_language_defn): Adjust. * disasm.c (disassembler_options_completer): Adjust to work with a completion_tracker instead of a VEC. * f-lang.c (f_make_symbol_completion_list): Rename to ... (f_collect_symbol_completion_matches): ... this. Adjust to work with a completion_tracker instead of a VEC. (f_language_defn): Adjust. * go-lang.c (go_language_defn): Adjust. * guile/scm-cmd.c (cmdscm_add_completion, cmdscm_completer): Adjust to work with a completion_tracker instead of a VEC. * infrun.c (handle_completer): Likewise. * interps.c (interpreter_completer): Likewise. * interps.h (interpreter_completer): Likewise. * language.c (unknown_language_defn, auto_language_defn) (local_language_defn): Adjust. * language.h (language_defn::la_make_symbol_completion_list): Rename to ... (language_defn::la_collect_symbol_completion_matches): ... this and adjust to work with a completion_tracker instead of a VEC. * m2-lang.c (m2_language_defn): Adjust. * objc-lang.c (objc_language_defn): Adjust. * opencl-lang.c (opencl_language_defn): Adjust. * p-lang.c (pascal_language_defn): Adjust. * python/py-cmd.c (cmdpy_completer_helper): Handle NULL word. (cmdpy_completer_handle_brkchars, cmdpy_completer): Adjust to work with a completion_tracker. * rust-lang.c (rust_language_defn): Adjust. * symtab.c (free_completion_list, do_free_completion_list) (return_val, completion_tracker): Delete. (completion_list_add_name, completion_list_add_symbol) (completion_list_add_msymbol, completion_list_objc_symbol) (completion_list_add_fields, add_symtab_completions): Add completion_tracker parameter and use it. (default_make_symbol_completion_list_break_on_1): Rename to... (default_collect_symbol_completion_matches_break_on): ... this. Add completion_tracker parameter and use it instead of allocating a completion tracker here. (default_make_symbol_completion_list_break_on): Delete old implementation. (default_make_symbol_completion_list): Delete. (default_collect_symbol_completion_matches): New. (make_symbol_completion_list): Delete. (collect_symbol_completion_matches): New. (make_symbol_completion_type): Rename to ... (collect_symbol_completion_matches_type): ... this. Add completion_tracker parameter and use it instead of VEC. (make_file_symbol_completion_list_1): Rename to... (collect_file_symbol_completion_matches): ... this. Add completion_tracker parameter and use it instead of VEC. (make_file_symbol_completion_list): Delete. (add_filename_to_list): Use completion_list instead of a VEC. (add_partial_filename_data::list): Now a completion_list. (make_source_files_completion_list): Work with a completion_list instead of a VEC. * symtab.h: Include "completer.h". (default_make_symbol_completion_list_break_on) (default_make_symbol_completion_list, make_symbol_completion_list) (make_symbol_completion_type, make_file_symbol_completion_list) (make_source_files_completion_list): Delete. (default_collect_symbol_completion_matches_break_on) (default_collect_symbol_completion_matches) (collect_symbol_completion_matches) (collect_symbol_completion_matches_type) (collect_file_symbol_completion_matches) (make_source_files_completion_list): New. * top.c (init_main): Don't install a rl_completion_entry_function hook. Install a rl_attempted_completion_function hook instead. * tui/tui-layout.c (layout_completer): Adjust to work with a completion_tracker. * tui/tui-regs.c (tui_reggroup_completer): * tui/tui-win.c (window_name_completer, focus_completer) (winheight_completer): Adjust to work with a completion_tracker. * value.c: Include "completer.h". (complete_internalvar): Adjust to work with a completion_tracker. * value.h (complete_internalvar): Likewise. --- gdb/python/py-cmd.c | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c index b9a866e..b9f6037 100644 --- a/gdb/python/py-cmd.c +++ b/gdb/python/py-cmd.c @@ -242,10 +242,21 @@ cmdpy_completer_helper (struct cmd_list_element *command, NULL)); if (textobj == NULL) error (_("Could not convert argument to Python string.")); - gdbpy_ref<> wordobj (PyUnicode_Decode (word, strlen (word), host_charset (), - NULL)); - if (wordobj == NULL) - error (_("Could not convert argument to Python string.")); + + gdbpy_ref<> wordobj; + if (word == NULL) + { + /* "brkchars" phase. */ + wordobj.reset (Py_None); + Py_INCREF (Py_None); + } + else + { + wordobj.reset (PyUnicode_Decode (word, strlen (word), host_charset (), + NULL)); + if (wordobj == NULL) + error (_("Could not convert argument to Python string.")); + } gdbpy_ref<> resultobj (PyObject_CallMethodObjArgs ((PyObject *) obj, complete_cst, @@ -267,6 +278,7 @@ cmdpy_completer_helper (struct cmd_list_element *command, static void cmdpy_completer_handle_brkchars (struct cmd_list_element *command, + completion_tracker &tracker, const char *text, const char *word) { gdbpy_enter enter_py (get_current_arch (), current_language); @@ -300,19 +312,18 @@ cmdpy_completer_handle_brkchars (struct cmd_list_element *command, adjust the break characters accordingly. */ brkchars_fn = (completer_handle_brkchars_func_for_completer (completers[value].completer)); - brkchars_fn (command, text, word); + brkchars_fn (command, tracker, text, word); } } } /* Called by gdb for command completion. */ -static VEC (char_ptr) * +static void cmdpy_completer (struct cmd_list_element *command, + completion_tracker &tracker, const char *text, const char *word) { - VEC (char_ptr) *result = NULL; - gdbpy_enter enter_py (get_current_arch (), current_language); /* Calling our helper to obtain the PyObject of the Python @@ -320,12 +331,10 @@ cmdpy_completer (struct cmd_list_element *command, gdbpy_ref<> resultobj (cmdpy_completer_helper (command, text, word)); /* If the result object of calling the Python function is NULL, it - means that there was an error. In this case, just give up and - return NULL. */ + means that there was an error. In this case, just give up. */ if (resultobj == NULL) - return NULL; + return; - result = NULL; if (PyInt_Check (resultobj.get ())) { /* User code may also return one of the completion constants, @@ -338,15 +347,16 @@ cmdpy_completer (struct cmd_list_element *command, PyErr_Clear (); } else if (value >= 0 && value < (long) N_COMPLETERS) - result = completers[value].completer (command, text, word); + completers[value].completer (command, tracker, text, word); } else { gdbpy_ref<> iter (PyObject_GetIter (resultobj.get ())); if (iter == NULL) - return NULL; + return; + bool got_matches = false; while (true) { gdbpy_ref<> elt (PyIter_Next (iter.get ())); @@ -366,16 +376,15 @@ cmdpy_completer (struct cmd_list_element *command, PyErr_Clear (); continue; } - VEC_safe_push (char_ptr, result, item.release ()); + tracker.add_completion (std::move (item)); + got_matches = true; } /* If we got some results, ignore problems. Otherwise, report the problem. */ - if (result != NULL && PyErr_Occurred ()) + if (got_matches && PyErr_Occurred ()) PyErr_Clear (); } - - return result; } /* Helper for cmdpy_init which locates the command list to use and -- cgit v1.1 From 7f968c899f21643322dcfaf807ec7d7bee7c9974 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sun, 30 Apr 2017 22:10:41 -0600 Subject: 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 * 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. --- gdb/python/py-breakpoint.c | 15 ++++++--------- gdb/python/py-varobj.c | 9 ++++----- gdb/python/python.c | 37 +++++++++---------------------------- 3 files changed, 19 insertions(+), 42 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index 64de803..6156eb6 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -1026,15 +1026,12 @@ local_setattro (PyObject *self, PyObject *name, PyObject *v) extlang = get_breakpoint_cond_ext_lang (obj->bp, EXT_LANG_PYTHON); if (extlang != NULL) { - char *error_text; - - error_text - = xstrprintf (_("Only one stop condition allowed. There is" - " currently a %s stop condition defined for" - " this breakpoint."), - ext_lang_capitalized_name (extlang)); - PyErr_SetString (PyExc_RuntimeError, error_text); - xfree (error_text); + std::string error_text + = string_printf (_("Only one stop condition allowed. There is" + " currently a %s stop condition defined for" + " this breakpoint."), + ext_lang_capitalized_name (extlang)); + PyErr_SetString (PyExc_RuntimeError, error_text.c_str ()); return -1; } } diff --git a/gdb/python/py-varobj.c b/gdb/python/py-varobj.c index e858556..5f6ab64 100644 --- a/gdb/python/py-varobj.c +++ b/gdb/python/py-varobj.c @@ -71,7 +71,6 @@ py_varobj_iter_next (struct varobj_iter *self) if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error)) { PyObject *type, *value, *trace; - char *name_str; PyErr_Fetch (&type, &value, &trace); gdb::unique_xmalloc_ptr @@ -85,10 +84,10 @@ py_varobj_iter_next (struct varobj_iter *self) return NULL; } - name_str = xstrprintf ("", - self->next_raw_index++); - item.reset (Py_BuildValue ("(ss)", name_str, value_str.get ())); - xfree (name_str); + std::string name_str = string_printf ("", + self->next_raw_index++); + item.reset (Py_BuildValue ("(ss)", name_str.c_str (), + value_str.get ())); if (item == NULL) { gdbpy_print_stack (); diff --git a/gdb/python/python.c b/gdb/python/python.c index be92f36..67f134d 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -365,32 +365,19 @@ python_run_simple_file (FILE *file, const char *filename) } /* Given a command_line, return a command string suitable for passing - to Python. Lines in the string are separated by newlines. The - return value is allocated using xmalloc and the caller is - responsible for freeing it. */ + to Python. Lines in the string are separated by newlines. */ -static char * +static std::string compute_python_string (struct command_line *l) { struct command_line *iter; - char *script = NULL; - int size = 0; - int here; + std::string script; 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) { - int len = strlen (iter->line); - - strcpy (&script[here], iter->line); - here += len; - script[here++] = '\n'; + script += iter->line; + script += '\n'; } - script[here] = '\0'; return script; } @@ -402,16 +389,14 @@ gdbpy_eval_from_control_command (const struct extension_language_defn *extlang, struct command_line *cmd) { int ret; - char *script; if (cmd->body_count != 1) error (_("Invalid \"python\" block structure.")); gdbpy_enter enter_py (get_current_arch (), current_language); - script = compute_python_string (cmd->body_list[0]); - ret = PyRun_SimpleString (script); - xfree (script); + std::string script = compute_python_string (cmd->body_list[0]); + ret = PyRun_SimpleString (script.c_str ()); if (ret) error (_("Error while executing Python code.")); } @@ -1532,7 +1517,6 @@ do_start_initialization () #ifdef IS_PY3K int i; size_t progsize, count; - char *oldloc; wchar_t *progname_copy; #endif @@ -1546,25 +1530,22 @@ do_start_initialization () progname = concat (ldirname (python_libdir).c_str (), SLASH_STRING, "bin", SLASH_STRING, "python", (char *) NULL); #ifdef IS_PY3K - oldloc = xstrdup (setlocale (LC_ALL, NULL)); + std::string oldloc = setlocale (LC_ALL, NULL); setlocale (LC_ALL, ""); progsize = strlen (progname); progname_copy = (wchar_t *) PyMem_Malloc ((progsize + 1) * sizeof (wchar_t)); if (!progname_copy) { - xfree (oldloc); fprintf (stderr, "out of memory\n"); return false; } count = mbstowcs (progname_copy, progname, progsize + 1); if (count == (size_t) -1) { - xfree (oldloc); fprintf (stderr, "Could not convert python path to string\n"); return false; } - setlocale (LC_ALL, oldloc); - xfree (oldloc); + setlocale (LC_ALL, oldloc.c_str ()); /* Note that Py_SetProgramName expects the string it is passed to remain alive for the duration of the program's execution, so -- cgit v1.1 From 0d50bde32b92821c9f1f660d273e6c996d26dc9f Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sun, 30 Apr 2017 22:12:13 -0600 Subject: Remove a cleanup in Python This removes cleanups from gdbpy_decode_line, in favor of a use of unique_xmalloc_ptr. ChangeLog 2017-08-03 Tom Tromey * python/python.c (gdbpy_decode_line): Use unique_xmalloc_ptr. --- gdb/python/python.c | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/python.c b/gdb/python/python.c index 67f134d..c53e10f 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -652,7 +652,6 @@ gdbpy_decode_line (PyObject *self, PyObject *args) appease gcc. */ struct symtab_and_line sal; char *arg = NULL; - struct cleanup *cleanups; gdbpy_ref<> result; gdbpy_ref<> unparsed; event_location_up location; @@ -660,8 +659,6 @@ gdbpy_decode_line (PyObject *self, PyObject *args) if (! PyArg_ParseTuple (args, "|s", &arg)) return NULL; - cleanups = make_cleanup (null_cleanup, NULL); - sals.sals = NULL; if (arg != NULL) @@ -685,12 +682,13 @@ gdbpy_decode_line (PyObject *self, PyObject *args) } END_CATCH + /* Ensure that the sals data is freed, when needed. */ + gdb::unique_xmalloc_ptr free_sals; if (sals.sals != NULL && sals.sals != &sal) - make_cleanup (xfree, sals.sals); + free_sals.reset (sals.sals); if (except.reason < 0) { - do_cleanups (cleanups); /* We know this will always throw. */ gdbpy_convert_exception (except); return NULL; @@ -702,20 +700,14 @@ gdbpy_decode_line (PyObject *self, PyObject *args) result.reset (PyTuple_New (sals.nelts)); if (result == NULL) - { - do_cleanups (cleanups); - return NULL; - } + return NULL; for (i = 0; i < sals.nelts; ++i) { PyObject *obj; obj = symtab_and_line_to_sal_object (sals.sals[i]); if (! obj) - { - do_cleanups (cleanups); - return NULL; - } + return NULL; PyTuple_SetItem (result.get (), i, obj); } @@ -728,19 +720,13 @@ gdbpy_decode_line (PyObject *self, PyObject *args) gdbpy_ref<> return_result (PyTuple_New (2)); if (return_result == NULL) - { - do_cleanups (cleanups); - return NULL; - } + return NULL; if (arg != NULL && strlen (arg) > 0) { unparsed.reset (PyString_FromString (arg)); if (unparsed == NULL) - { - do_cleanups (cleanups); - return NULL; - } + return NULL; } else { @@ -751,8 +737,6 @@ gdbpy_decode_line (PyObject *self, PyObject *args) PyTuple_SetItem (return_result.get (), 0, unparsed.release ()); PyTuple_SetItem (return_result.get (), 1, result.release ()); - do_cleanups (cleanups); - return return_result.release (); } -- cgit v1.1 From 773a1edcd1086fc76a91055bec67e2d14d76940d Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sun, 30 Apr 2017 23:02:30 -0600 Subject: Introduce gdb_argv, a class wrapper for buildargv This introduces gdb_argv, a class wrapping an "argv" pointer; that is, a pointer to a NULL-terminated array of char*, where both the array and each non-NULL element in the array are xmalloc'd. This patch then changes most users of gdb_buildargv to use gdb_argv instead. ChangeLog 2017-08-03 Tom Tromey * utils.h (struct gdb_argv_deleter): New. (gdb_argv): New class. * utils.c (gdb_argv::reset): New method. * tracepoint.c (delete_trace_variable_command): Use gdb_argv. * tracefile.c (tsave_command): Use gdb_argv. * top.c (new_ui_command): Use gdb_argv. * symmisc.c (maintenance_print_symbols) (maintenance_print_msymbols, maintenance_expand_symtabs): Use gdb_argv. * symfile.c (symbol_file_command, generic_load) (remove_symbol_file_command): Use gdb_argv. * stack.c (backtrace_command): Use gdb_argv. * source.c (add_path, show_substitute_path_command) (unset_substitute_path_command, set_substitute_path_command): Use gdb_argv. * skip.c (skip_command): Use gdb_argv. Use gdb_buildargv. * ser-mingw.c (pipe_windows_open): Use gdb_argv. * remote.c (extended_remote_run, remote_put_command) (remote_get_command, remote_delete_command): Use gdb_argv. * remote-sim.c (gdbsim_load, gdbsim_create_inferior) (gdbsim_open): Use gdb_argv. * python/py-cmd.c (gdbpy_string_to_argv): Use gdb_argv. * psymtab.c (maintenance_print_psymbols): Use gdb_argv. * procfs.c (procfs_info_proc): Use gdb_argv. * interps.c (interpreter_exec_cmd): Use gdb_argv. * infrun.c (handle_command): Use gdb_argv. * inferior.c (add_inferior_command, clone_inferior_command): Use gdb_argv. * guile/scm-string.c (gdbscm_string_to_argv): Use gdb_argv. * exec.c (exec_file_command): Use gdb_argv. * cli/cli-cmds.c (alias_command): Use gdb_argv. * compile/compile.c (build_argc_argv): Use gdb_argv. --- gdb/python/py-cmd.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c index b9f6037..2a7c613 100644 --- a/gdb/python/py-cmd.c +++ b/gdb/python/py-cmd.c @@ -775,22 +775,16 @@ gdbpy_string_to_argv (PyObject *self, PyObject *args) if (*input != '\0') { - char **c_argv = gdb_buildargv (input); - int i; + gdb_argv c_argv (input); - for (i = 0; c_argv[i] != NULL; ++i) + for (char *arg : c_argv) { - gdbpy_ref<> argp (PyString_FromString (c_argv[i])); + gdbpy_ref<> argp (PyString_FromString (arg)); if (argp == NULL || PyList_Append (py_argv.get (), argp.get ()) < 0) - { - freeargv (c_argv); - return NULL; - } + return NULL; } - - freeargv (c_argv); } return py_argv.release (); -- cgit v1.1 From 1c034b67a03ed928eb3916034eb1e782a8188520 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sun, 30 Apr 2017 23:03:58 -0600 Subject: Use gdb_argv in Python This changes one spot in the Python code to use gdb_argv. This removes the last cleanup from the Python layer. ChangeLog 2017-08-03 Tom Tromey * python/py-param.c (compute_enum_values): Use gdb_argv. --- gdb/python/py-param.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c index f0d3423..455c99e 100644 --- a/gdb/python/py-param.c +++ b/gdb/python/py-param.c @@ -555,7 +555,6 @@ static int compute_enum_values (parmpy_object *self, PyObject *enum_values) { Py_ssize_t size, i; - struct cleanup *back_to; if (! enum_values) { @@ -581,36 +580,27 @@ compute_enum_values (parmpy_object *self, PyObject *enum_values) return 0; } - self->enumeration = XCNEWVEC (const char *, size + 1); - back_to = make_cleanup (free_current_contents, &self->enumeration); + gdb_argv holder (XCNEWVEC (char *, size + 1)); + char **enumeration = holder.get (); for (i = 0; i < size; ++i) { gdbpy_ref<> item (PySequence_GetItem (enum_values, i)); if (item == NULL) - { - do_cleanups (back_to); - return 0; - } + return 0; if (! gdbpy_is_string (item.get ())) { - do_cleanups (back_to); PyErr_SetString (PyExc_RuntimeError, _("The enumeration item not a string.")); return 0; } - self->enumeration[i] - = python_string_to_host_string (item.get ()).release (); - if (self->enumeration[i] == NULL) - { - do_cleanups (back_to); - return 0; - } - make_cleanup (xfree, (char *) self->enumeration[i]); + enumeration[i] = python_string_to_host_string (item.get ()).release (); + if (enumeration[i] == NULL) + return 0; } - discard_cleanups (back_to); + self->enumeration = const_cast (holder.release ()); return 1; } -- cgit v1.1 From 29592bde87d250ea56e8431053918899d3d0c16b Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Wed, 9 Aug 2017 15:04:32 +0100 Subject: Make cp_comp_to_string return a gdb::unique_xmalloc_ptr To help avoid issues like the one fixed by e88e8651cf34 ("Fix memory leak in cp-support.c"). gdb/ChangeLog: 2017-08-09 Pedro Alves * cp-name-parser.y (cp_comp_to_string): Return a gdb::unique_xmalloc_ptr. * cp-support.c (replace_typedefs_qualified_name) (replace_typedefs): Adjust to use gdb::unique_xmalloc_ptr. (cp_canonicalize_string_full): Use op= instead of explicit convertion. (cp_class_name_from_physname, method_name_from_physname) (cp_func_name, cp_remove_params): Adjust to use gdb::unique_xmalloc_ptr. * cp-support.h (cp_comp_to_string): Return a gdb::unique_xmalloc_ptr. * python/py-type.c (typy_lookup_type): Adjust to use gdb::unique_xmalloc_ptr. --- gdb/python/py-type.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c index aa20d4c..51184ca 100644 --- a/gdb/python/py-type.c +++ b/gdb/python/py-type.c @@ -761,7 +761,6 @@ typy_lookup_type (struct demangle_component *demangled, const struct block *block) { struct type *type, *rtype = NULL; - char *type_name = NULL; enum demangle_component_type demangled_type; /* Save the type: typy_lookup_type() may (indirectly) overwrite @@ -816,11 +815,8 @@ typy_lookup_type (struct demangle_component *demangled, return rtype; /* We don't have a type, so lookup the type. */ - type_name = cp_comp_to_string (demangled, 10); - type = typy_lookup_typename (type_name, block); - xfree (type_name); - - return type; + gdb::unique_xmalloc_ptr type_name = cp_comp_to_string (demangled, 10); + return typy_lookup_typename (type_name.get (), block); } /* This is a helper function for typy_template_argument that is used -- cgit v1.1 From 0860c437cbe4efd8752531d0464007f448fc8274 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Mon, 4 Sep 2017 10:46:36 +0200 Subject: btrace: Store btrace_insn in an std::vector Because it contains a non-POD type field (flags), the type btrace_insn should be new'ed/delete'd. Replace the VEC (btrace_insn_s) in btrace_function with an std::vector. gdb/ChangeLog: * btrace.h (btrace_insn_s, DEF_VEC_O (btrace_insn_s)): Remove. (btrace_function) : Change type to use std::vector. * btrace.c (ftrace_debug, ftrace_call_num_insn, ftrace_find_call, ftrace_new_gap, ftrace_update_function, ftrace_update_insns, ftrace_compute_global_level_offset, btrace_stitch_bts, btrace_clear, btrace_insn_get, btrace_insn_end, btrace_insn_next, btrace_insn_prev): Adjust to change to std::vector. (ftrace_update_insns): Adjust to change to std::vector, change type of INSN parameter. (btrace_compute_ftrace_bts): Adjust call to ftrace_update_insns. * record-btrace.c (btrace_call_history_insn_range, btrace_compute_src_line_range, record_btrace_frame_prev_register): Adjust to change to std::vector. * python/py-record-btrace.c (recpy_bt_func_instructions): Adjust to change to std::vector. --- gdb/python/py-record-btrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gdb/python') diff --git a/gdb/python/py-record-btrace.c b/gdb/python/py-record-btrace.c index cd2be9f..220990b 100644 --- a/gdb/python/py-record-btrace.c +++ b/gdb/python/py-record-btrace.c @@ -376,7 +376,7 @@ recpy_bt_func_instructions (PyObject *self, void *closure) if (func == NULL) return NULL; - len = VEC_length (btrace_insn_s, func->insn); + len = func->insn.size (); /* Gaps count as one instruction. */ if (len == 0) -- cgit v1.1 From 6c5b2ebeacc2538cf342cfd13c4c98ff018e6c9a Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Mon, 4 Sep 2017 17:10:13 +0100 Subject: struct symtabs_and_lines -> std::vector This replaces "struct symtabs_and_lines" with std::vector in most cases. This removes a number of cleanups. In some cases, the sals objects do not own the sals they point at. Instead they point at some sal that lives on the stack. Typically something like this: struct symtab_and_line sal; struct symtabs_and_lines sals; // fill in sal sals.nelts = 1; sals.sals = &sal; // use sals Instead of switching those cases to std::vector too, such usages are replaced by gdb::array_view instead. This avoids introducing heap allocations. gdb/ChangeLog: 2017-09-04 Pedro Alves * ax-gdb.c (agent_command_1): Use range-for. * break-catch-throw.c (re_set_exception_catchpoint): Update. * breakpoint.c: Include "common/array-view.h". (init_breakpoint_sal, create_breakpoint_sal): Change sals parameter from struct symtabs_and_lines to array_view. Adjust. Use range-for. Update. (breakpoint_sals_to_pc): Change sals parameter from struct symtabs_and_lines to std::vector reference. (check_fast_tracepoint_sals): Change sals parameter from struct symtabs_and_lines to std::array_view. Use range-for. (decode_static_tracepoint_spec): Return a std::vector instead of symtabs_and_lines. Update. (create_breakpoint): Update. (break_range_command, until_break_command, clear_command): Update. (base_breakpoint_decode_location, bkpt_decode_location) (bkpt_probe_create_sals_from_location) (bkpt_probe_decode_location, tracepoint_decode_location) (tracepoint_probe_decode_location) (strace_marker_create_sals_from_location): Return a std::vector instead of symtabs_and_lines. (strace_marker_create_breakpoints_sal): Update. (strace_marker_decode_location): Return a std::vector instead of symtabs_and_lines. Update. (update_breakpoint_locations): Change struct symtabs_and_lines parameters to gdb::array_view. Adjust. (location_to_sals): Return a std::vector instead of symtabs_and_lines. Update. (breakpoint_re_set_default): Use std::vector instead of struct symtabs_and_lines. (decode_location_default): Return a std::vector instead of symtabs_and_lines. Update. * breakpoint.h: Include "common/array-view.h". (struct breakpoint_ops) : Now returns a std::vector instead of returning a symtabs_and_lines via output parameter. (update_breakpoint_locations): Change sals parameters to use gdb::array_view. * cli/cli-cmds.c (edit_command, list_command): Update to use std::vector and gdb::array_view. (ambiguous_line_spec): Adjust to use gdb::array_view and range-for. (compare_symtabs): Rename to ... (cmp_symtabs): ... this. Change parameters to symtab_and_line const reference and adjust. (filter_sals): Rewrite using std::vector and standard algorithms. * elfread.c (elf_gnu_ifunc_resolver_return_stop): Simplify. (jump_command): Update to use std::vector. * linespec.c (struct linespec_state) : Update comment. (add_sal_to_sals_basic): Delete. (add_sal_to_sals, filter_results, convert_results_to_lsals) (decode_line_2, create_sals_line_offset) (convert_address_location_to_sals, convert_linespec_to_sals) (convert_explicit_location_to_sals, parse_linespec) (event_location_to_sals, decode_line_full, decode_line_1) (decode_line_with_current_source) (decode_line_with_last_displayed, decode_objc) (decode_digits_list_mode, decode_digits_ordinary, minsym_found) (linespec_result::~linespec_result): Adjust to use std::vector instead of symtabs_and_lines. * linespec.h (linespec_sals::sals): Now a std::vector. (struct linespec_result): Use std::vector, bool, and in-class initialization. (decode_line_1, decode_line_with_current_source) (decode_line_with_last_displayed): Return std::vector. * macrocmd.c (info_macros_command): Use std::vector. * mi/mi-main.c (mi_cmd_trace_find): Use std::vector. * probe.c (parse_probes_in_pspace, parse_probes): Adjust to use std::vector. * probe.h (parse_probes): Return a std::vector. * python/python.c (gdbpy_decode_line): Use std::vector and gdb::array_view. * source.c (select_source_symtab, line_info): Use std::vector. * stack.c (func_command): Use std::vector. * symtab.h (struct symtabs_and_lines): Delete. * tracepoint.c (tfind_line_command, scope_info): Use std::vector. --- gdb/python/python.c | 47 ++++++++++++++++------------------------------- 1 file changed, 16 insertions(+), 31 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/python.c b/gdb/python/python.c index c53e10f..f40fe89 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -647,10 +647,6 @@ gdbpy_solib_name (PyObject *self, PyObject *args) static PyObject * gdbpy_decode_line (PyObject *self, PyObject *args) { - struct gdb_exception except = exception_none; - struct symtabs_and_lines sals = { NULL, 0 }; /* Initialize to - appease gcc. */ - struct symtab_and_line sal; char *arg = NULL; gdbpy_ref<> result; gdbpy_ref<> unparsed; @@ -659,54 +655,43 @@ gdbpy_decode_line (PyObject *self, PyObject *args) if (! PyArg_ParseTuple (args, "|s", &arg)) return NULL; - sals.sals = NULL; - if (arg != NULL) location = string_to_event_location_basic (&arg, python_language); + std::vector decoded_sals; + symtab_and_line def_sal; + gdb::array_view sals; TRY { if (location != NULL) - sals = decode_line_1 (location.get (), 0, NULL, NULL, 0); + { + decoded_sals = decode_line_1 (location.get (), 0, NULL, NULL, 0); + sals = decoded_sals; + } else { set_default_source_symtab_and_line (); - sal = get_current_source_symtab_and_line (); - sals.sals = &sal; - sals.nelts = 1; + def_sal = get_current_source_symtab_and_line (); + sals = def_sal; } } CATCH (ex, RETURN_MASK_ALL) { - except = ex; - } - END_CATCH - - /* Ensure that the sals data is freed, when needed. */ - gdb::unique_xmalloc_ptr free_sals; - if (sals.sals != NULL && sals.sals != &sal) - free_sals.reset (sals.sals); - - if (except.reason < 0) - { /* We know this will always throw. */ - gdbpy_convert_exception (except); + gdbpy_convert_exception (ex); return NULL; } + END_CATCH - if (sals.nelts) + if (!sals.empty ()) { - int i; - - result.reset (PyTuple_New (sals.nelts)); + result.reset (PyTuple_New (sals.size ())); if (result == NULL) return NULL; - for (i = 0; i < sals.nelts; ++i) + for (size_t i = 0; i < sals.size (); ++i) { - PyObject *obj; - - obj = symtab_and_line_to_sal_object (sals.sals[i]); - if (! obj) + PyObject *obj = symtab_and_line_to_sal_object (sals[i]); + if (obj == NULL) return NULL; PyTuple_SetItem (result.get (), i, obj); -- cgit v1.1 From 51abb421302bdd86946827727aebc878b5c756e3 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Mon, 4 Sep 2017 17:10:13 +0100 Subject: Kill init_sal Instead, make symtab_and_line initialize its members itself. Many symtab_and_line declarations are moved to where the object is initialized at the same time both for clarity and to avoid double initialization. A few functions, like e.g., find_frame_sal are adjusted to return the sal using normal function return instead of an output parameter likewise to avoid having to default-construct a sal and then immediately have the object overwritten. gdb/ChangeLog: 2017-09-04 Pedro Alves * ada-lang.c (is_known_support_routine): Move sal declaration to where it is initialized. * breakpoint.c (create_internal_breakpoint, init_catchpoint) (parse_breakpoint_sals, decode_static_tracepoint_spec) (clear_command, update_static_tracepoint): Remove init_sal references. Move declarations closer to initializations. * cli/cli-cmds.c (list_command): Move sal declarations closer to initializations. * elfread.c (elf_gnu_ifunc_resolver_stop): Remove init_sal references. Move sal declarations closer to initializations. * frame.c (find_frame_sal): Return a symtab_and_line via function return instead of output parameter. Remove init_sal references. * frame.h (find_frame_sal): Return a symtab_and_line via function return instead of output parameter. * guile/scm-frame.c (gdbscm_frame_sal): Adjust. * guile/scm-symtab.c (stscm_make_sal_smob): Use in-place new instead of memset. (gdbscm_find_pc_line): Remove init_sal reference. * infcall.c (call_function_by_hand_dummy): Remove init_sal references. Move declarations closer to initializations. * infcmd.c (set_step_frame): Update. Move declarations closer to initializations. (finish_backward): Remove init_sal references. Move declarations closer to initializations. * infrun.c (process_event_stop_test, handle_step_into_function) (insert_hp_step_resume_breakpoint_at_frame) (insert_step_resume_breakpoint_at_caller): Likewise. * linespec.c (create_sals_line_offset, decode_digits_ordinary) (symbol_to_sal): Likewise. * probe.c (parse_probes_in_pspace): Remove init_sal reference. * python/py-frame.c (frapy_find_sal): Move sal declaration closer to its initialization. * reverse.c (save_bookmark_command): Use new/delete. Remove init_sal references. Move declarations closer to initializations. * source.c (get_current_source_symtab_and_line): Remove brace initialization. (set_current_source_symtab_and_line): Now takes the sal by const reference. Remove brace initialization. (line_info): Remove init_sal reference. * source.h (set_current_source_symtab_and_line): Now takes a symtab_and_line via const reference. * stack.c (set_current_sal_from_frame): Adjust. (print_frame_info): Adjust. (get_last_displayed_sal): Return the sal via function return instead of via output parameter. Simplify. (frame_info): Adjust. * stack.h (get_last_displayed_sal): Return the sal via function return instead of via output parameter. * symtab.c (init_sal): Delete. (find_pc_sect_line): Remove init_sal references. Move declarations closer to initializations. (find_function_start_sal): Remove init_sal references. Move declarations closer to initializations. * symtab.h (struct symtab_and_line): In-class initialize all fields. * tracepoint.c (set_traceframe_context) (print_one_static_tracepoint_marker): Remove init_sal references. Move declarations closer to initializations. * tui/tui-disasm.c (tui_show_disassem_and_update_source): Adjust. * tui/tui-stack.c (tui_show_frame_info): Adjust. Move declarations closer to initializations. * tui/tui-winsource.c (tui_update_source_window_as_is): Remove init_sal references. Adjust. --- gdb/python/py-frame.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c index 891f44e..c5ae391 100644 --- a/gdb/python/py-frame.c +++ b/gdb/python/py-frame.c @@ -468,14 +468,13 @@ static PyObject * frapy_find_sal (PyObject *self, PyObject *args) { struct frame_info *frame; - struct symtab_and_line sal; PyObject *sal_obj = NULL; /* Initialize to appease gcc warning. */ TRY { FRAPY_REQUIRE_VALID (self, frame); - find_frame_sal (frame, &sal); + symtab_and_line sal = find_frame_sal (frame); sal_obj = symtab_and_line_to_sal_object (sal); } CATCH (except, RETURN_MASK_ALL) -- cgit v1.1 From 7022349d5c86bae74b49225515f42d2e221bd368 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Mon, 4 Sep 2017 20:21:13 +0100 Subject: Stop assuming no-debug-info functions return int The fact that GDB defaults to assuming that functions return int, when it has no debug info for the function has been a recurring source of user confusion. Recently this came up on the errno pretty printer discussions. Shortly after, it came up again on IRC, with someone wondering why does getenv() in GDB return a negative int: (gdb) p getenv("PATH") $1 = -6185 This question (with s/getenv/random-other-C-runtime-function) is a FAQ on IRC. The reason for the above is: (gdb) p getenv $2 = {} 0x7ffff7751d80 (gdb) ptype getenv type = int () ... which means that GDB truncated the 64-bit pointer that is actually returned from getent to 32-bit, and then sign-extended it: (gdb) p /x -6185 $6 = 0xffffe7d7 The workaround is to cast the function to the right type, like: (gdb) p ((char *(*) (const char *)) getenv) ("PATH") $3 = 0x7fffffffe7d7 "/usr/local/bin:/"... IMO, we should do better than this. I see the "assume-int" issue the same way I see printing bogus values for optimized-out variables instead of "" -- I'd much rather that the debugger tells me "I don't know" and tells me how to fix it than showing me bogus misleading results, making me go around tilting at windmills. If GDB prints a signed integer when you're expecting a pointer or aggregate, you at least have some sense that something is off, but consider the case of the function actually returning a 64-bit integer. For example, compile this without debug info: unsigned long long function () { return 0x7fffffffffffffff; } Currently, with pristine GDB, you get: (gdb) p function () $1 = -1 # incorrect (gdb) p /x function () $2 = 0xffffffff # incorrect maybe after spending a few hours debugging you suspect something is wrong with that -1, and do: (gdb) ptype function type = int () and maybe, just maybe, you realize that the function actually returns unsigned long long. And you try to fix it with: (gdb) p /x (unsigned long long) function () $3 = 0xffffffffffffffff # incorrect ... which still produces the wrong result, because GDB simply applied int to unsigned long long conversion. Meaning, it sign-extended the integer that it extracted from the return of the function, to 64-bits. and then maybe, after asking around on IRC, you realize you have to cast the function to a pointer of the right type, and call that. It won't be easy, but after a few missteps, you'll get to it: ..... (gdb) p /x ((unsigned long long(*) ()) function) () $666 = 0x7fffffffffffffff # finally! :-) So to improve on the user experience, this patch does the following (interrelated) things: - makes no-debug-info functions no longer default to "int" as return type. Instead, they're left with NULL/"" return type. (gdb) ptype getenv type = () - makes calling a function with unknown return type an error. (gdb) p getenv ("PATH") 'getenv' has unknown return type; cast the call to its declared return type - and then to make it easier to call the function, makes it possible to _only_ cast the return of the function to the right type, instead of having to cast the function to a function pointer: (gdb) p (char *) getenv ("PATH") # now Just Works $3 = 0x7fffffffe7d7 "/usr/local/bin:/"... (gdb) p ((char *(*) (const char *)) getenv) ("PATH") # continues working $4 = 0x7fffffffe7d7 "/usr/local/bin:/"... I.e., it makes GDB default the function's return type to the type of the cast, and the function's parameters to the type of the arguments passed down. After this patch, here's what you'll get for the "unsigned long long" example above: (gdb) p function () 'function' has unknown return type; cast the call to its declared return type (gdb) p /x (unsigned long long) function () $4 = 0x7fffffffffffffff # correct! Note that while with "print" GDB shows the name of the function that has the problem: (gdb) p getenv ("PATH") 'getenv' has unknown return type; cast the call to its declared return type which can by handy in more complicated expressions, "ptype" does not: (gdb) ptype getenv ("PATH") function has unknown return type; cast the call to its declared return type This will be fixed in the next patch. gdb/ChangeLog: 2017-09-04 Pedro Alves * ada-lang.c (ada_evaluate_subexp) : Don't handle TYPE_GNU_IFUNC specially here. Throw error if return type is unknown. * ada-typeprint.c (print_func_type): Handle functions with unknown return type. * c-typeprint.c (c_type_print_base): Handle functions and methods with unknown return type. * compile/compile-c-symbols.c (convert_symbol_bmsym) : Use nodebug_text_gnu_ifunc_symbol. * compile/compile-c-types.c: Include "objfiles.h". (convert_func): For functions with unknown return type, warn and default to int. * compile/compile-object-run.c (compile_object_run): Adjust call to call_function_by_hand_dummy. * elfread.c (elf_gnu_ifunc_resolve_addr): Adjust call to call_function_by_hand. * eval.c (evaluate_subexp_standard): Adjust calls to call_function_by_hand. Handle functions and methods with unknown return type. Pass expect_type to call_function_by_hand. * f-typeprint.c (f_type_print_base): Handle functions with unknown return type. * gcore.c (call_target_sbrk): Adjust call to call_function_by_hand. * gdbtypes.c (objfile_type): Leave nodebug text symbol with NULL return type instead of int. Make nodebug_text_gnu_ifunc_symbol be an integer address type instead of nodebug. * guile/scm-value.c (gdbscm_value_call): Adjust call to call_function_by_hand. * infcall.c (error_call_unknown_return_type): New function. (call_function_by_hand): New "default_return_type" parameter. Pass it down. (call_function_by_hand_dummy): New "default_return_type" parameter. Use it instead of defaulting to int. If there's no default and the return type is unknown, throw an error. If there's a default return type, and the called function has no debug info, then assume the function is prototyped. * infcall.h (call_function_by_hand, call_function_by_hand_dummy): New "default_return_type" parameter. (error_call_unknown_return_type): New declaration. * linux-fork.c (call_lseek): Cast return type of lseek. (inferior_call_waitpid, checkpoint_command): Adjust calls to call_function_by_hand. * linux-tdep.c (linux_infcall_mmap, linux_infcall_munmap): Adjust calls to call_function_by_hand. * m2-typeprint.c (m2_procedure): Handle functions with unknown return type. * objc-lang.c (lookup_objc_class, lookup_child_selector) (value_nsstring, print_object_command): Adjust calls to call_function_by_hand. * p-typeprint.c (pascal_type_print_varspec_prefix): Handle functions with unknown return type. (pascal_type_print_func_varspec_suffix): New function. (pascal_type_print_varspec_suffix) : Use it. * python/py-value.c (valpy_call): Adjust call to call_function_by_hand. * rust-lang.c (rust_evaluate_funcall): Adjust call to call_function_by_hand. * valarith.c (value_x_binop, value_x_unop): Adjust calls to call_function_by_hand. * valops.c (value_allocate_space_in_inferior): Adjust call to call_function_by_hand. * typeprint.c (type_print_unknown_return_type): New function. * typeprint.h (type_print_unknown_return_type): New declaration. gdb/testsuite/ChangeLog: 2017-09-04 Pedro Alves * gdb.base/break-main-file-remove-fail.exp (test_remove_bp): Cast return type of munmap in infcall. * gdb.base/break-probes.exp: Cast return type of foo in infcall. * gdb.base/checkpoint.exp: Simplify using for loop. Cast return type of ftell in infcall. * gdb.base/dprintf-detach.exp (dprintf_detach_test): Cast return type of getpid in infcall. * gdb.base/infcall-exec.exp: Cast return type of execlp in infcall. * gdb.base/info-os.exp: Cast return type of getpid in infcall. Bail on failure to extract the pid. * gdb.base/nodebug.c: #include . (multf, multf_noproto, mult, mult_noproto, add8, add8_noproto): New functions. * gdb.base/nodebug.exp (test_call_promotion): New procedure. Change expected output of print/whatis/ptype with functions with no debug info. Test all supported languages. Call test_call_promotion. * gdb.compile/compile.exp: Adjust expected output to expect warning. * gdb.threads/siginfo-threads.exp: Likewise. --- gdb/python/py-value.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gdb/python') diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index b5a0ef8..cbbb936 100644 --- a/gdb/python/py-value.c +++ b/gdb/python/py-value.c @@ -925,7 +925,8 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords) scoped_value_mark free_values; struct value *return_value; - return_value = call_function_by_hand (function, args_count, vargs); + return_value = call_function_by_hand (function, NULL, + args_count, vargs); result = value_to_value_object (return_value); } CATCH (except, RETURN_MASK_ALL) -- cgit v1.1 From 481695ed5f6e0a8a9c9c50bfac1cdd2b3151e6c9 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Sat, 9 Sep 2017 11:02:37 -0700 Subject: Remove unnecessary function prototypes. These prototypes were required when compiling GDB as C but are not required for C++. gdb/ChangeLog: * aarch64-linux-nat.c: Remove _initialize_aarch64_linux_nat prototype. * aarch64-linux-tdep.c: Remove _initialize_aarch64_linux_tdep prototype. * aarch64-newlib-tdep.c: Remove _initialize_aarch64_newlib_tdep prototype. * aarch64-tdep.c: Remove _initialize_aarch64_tdep prototype. * ada-exp.y: Remove _initialize_ada_exp prototype. * ada-lang.c: Remove _initialize_ada_language prototype. * ada-tasks.c: Remove _initialize_tasks prototype. * addrmap.c: Remove _initialize_addrmap prototype. * agent.c: Remove _initialize_agent prototype. * aix-thread.c: Remove _initialize_aix_thread prototype. * alpha-bsd-nat.c: Remove _initialize_alphabsd_nat prototype. * alpha-linux-nat.c: Remove _initialize_alpha_linux_nat prototype. * alpha-linux-tdep.c: Remove _initialize_alpha_linux_tdep prototype. * alpha-nbsd-tdep.c: Remove _initialize_alphanbsd_tdep prototype. * alpha-obsd-tdep.c: Remove _initialize_alphaobsd_tdep prototype. * alpha-tdep.c: Remove _initialize_alpha_tdep prototype. * amd64-darwin-tdep.c: Remove _initialize_amd64_darwin_tdep prototype. * amd64-dicos-tdep.c: Remove _initialize_amd64_dicos_tdep prototype. * amd64-fbsd-nat.c: Remove _initialize_amd64fbsd_nat prototype. * amd64-fbsd-tdep.c: Remove _initialize_amd64fbsd_tdep prototype. * amd64-linux-nat.c: Remove _initialize_amd64_linux_nat prototype. * amd64-linux-tdep.c: Remove _initialize_amd64_linux_tdep prototype. * amd64-nbsd-nat.c: Remove _initialize_amd64nbsd_nat prototype. * amd64-nbsd-tdep.c: Remove _initialize_amd64nbsd_tdep prototype. * amd64-obsd-nat.c: Remove _initialize_amd64obsd_nat prototype. * amd64-obsd-tdep.c: Remove _initialize_amd64obsd_tdep prototype. * amd64-sol2-tdep.c: Remove _initialize_amd64_sol2_tdep prototype. * amd64-tdep.c: Remove _initialize_amd64_tdep prototype. * amd64-windows-nat.c: Remove _initialize_amd64_windows_nat prototype. * amd64-windows-tdep.c: Remove _initialize_amd64_windows_tdep prototype. * annotate.c: Remove _initialize_annotate prototype. * arc-newlib-tdep.c: Remove _initialize_arc_newlib_tdep prototype. * arc-tdep.c: Remove _initialize_arc_tdep prototype. * arch-utils.c: Remove _initialize_gdbarch_utils prototype. * arm-linux-nat.c: Remove _initialize_arm_linux_nat prototype. * arm-linux-tdep.c: Remove _initialize_arm_linux_tdep prototype. * arm-nbsd-tdep.c: Remove _initialize_arm_netbsd_tdep prototype. * arm-obsd-tdep.c: Remove _initialize_armobsd_tdep prototype. * arm-symbian-tdep.c: Remove _initialize_arm_symbian_tdep prototype. * arm-tdep.c: Remove _initialize_arm_tdep prototype. * arm-wince-tdep.c: Remove _initialize_arm_wince_tdep prototype. * auto-load.c: Remove _initialize_auto_load prototype. * auxv.c: Remove _initialize_auxv prototype. * avr-tdep.c: Remove _initialize_avr_tdep prototype. * ax-gdb.c: Remove _initialize_ax_gdb prototype. * bfin-linux-tdep.c: Remove _initialize_bfin_linux_tdep prototype. * bfin-tdep.c: Remove _initialize_bfin_tdep prototype. * break-catch-sig.c: Remove _initialize_break_catch_sig prototype. * break-catch-syscall.c: Remove _initialize_break_catch_syscall prototype. * break-catch-throw.c: Remove _initialize_break_catch_throw prototype. * breakpoint.c: Remove _initialize_breakpoint prototype. * bsd-uthread.c: Remove _initialize_bsd_uthread prototype. * btrace.c: Remove _initialize_btrace prototype. * charset.c: Remove _initialize_charset prototype. * cli/cli-cmds.c: Remove _initialize_cli_cmds prototype. * cli/cli-dump.c: Remove _initialize_cli_dump prototype. * cli/cli-interp.c: Remove _initialize_cli_interp prototype. * cli/cli-logging.c: Remove _initialize_cli_logging prototype. * cli/cli-script.c: Remove _initialize_cli_script prototype. * coff-pe-read.c: Remove _initialize_coff_pe_read prototype. * coffread.c: Remove _initialize_coffread prototype. * compile/compile.c: Remove _initialize_compile prototype. * complaints.c: Remove _initialize_complaints prototype. * completer.c: Remove _initialize_completer prototype. * copying.awk: Remove _initialize_copying prototype. * copying.c: Regenerate. * core-regset.c: Remove _initialize_core_regset prototype. * corefile.c: Remove _initialize_core prototype. * corelow.c: Remove _initialize_corelow prototype. * cp-abi.c: Remove _initialize_cp_abi prototype. * cp-namespace.c: Remove _initialize_cp_namespace prototype. * cp-support.c: Remove _initialize_cp_support prototype. * cp-valprint.c: Remove _initialize_cp_valprint prototype. * cris-linux-tdep.c: Remove _initialize_cris_linux_tdep prototype. * cris-tdep.c: Remove _initialize_cris_tdep prototype. * ctf.c: Remove _initialize_ctf prototype. * d-lang.c: Remove _initialize_d_language prototype. * darwin-nat-info.c: Remove _initialize_darwin_info_commands prototype. * darwin-nat.c: Remove _initialize_darwin_inferior prototype. * dbxread.c: Remove _initialize_dbxread prototype. * dcache.c: Remove _initialize_dcache prototype. * demangle.c: Remove _initialize_demangler prototype. * disasm-selftests.c: Remove _initialize_disasm_selftests prototype. * disasm.c: Remove _initialize_disasm prototype. * dtrace-probe.c: Remove _initialize_dtrace_probe prototype. * dummy-frame.c: Remove _initialize_dummy_frame prototype. * dwarf2-frame-tailcall.c: Remove _initialize_tailcall_frame prototype. * dwarf2-frame.c: Remove _initialize_dwarf2_frame prototype. * dwarf2expr.c: Remove _initialize_dwarf2expr prototype. * dwarf2loc.c: Remove _initialize_dwarf2loc prototype. * dwarf2read.c: Remove _initialize_dwarf2_read prototype. * elfread.c: Remove _initialize_elfread prototype. * exec.c: Remove _initialize_exec prototype. * extension.c: Remove _initialize_extension prototype. * f-lang.c: Remove _initialize_f_language prototype. * f-valprint.c: Remove _initialize_f_valprint prototype. * fbsd-nat.c: Remove _initialize_fbsd_nat prototype. * fbsd-tdep.c: Remove _initialize_fbsd_tdep prototype. * filesystem.c: Remove _initialize_filesystem prototype. * findcmd.c: Remove _initialize_mem_search prototype. * fork-child.c: Remove _initialize_fork_child prototype. * frame-base.c: Remove _initialize_frame_base prototype. * frame-unwind.c: Remove _initialize_frame_unwind prototype. * frame.c: Remove _initialize_frame prototype. * frv-linux-tdep.c: Remove _initialize_frv_linux_tdep prototype. * frv-tdep.c: Remove _initialize_frv_tdep prototype. * ft32-tdep.c: Remove _initialize_ft32_tdep prototype. * gcore.c: Remove _initialize_gcore prototype. * gdb_bfd.c: Remove _initialize_gdb_bfd prototype. * gdbarch.c: Regenerate. * gdbarch.sh: Remove _initialize_gdbarch prototype. * gdbtypes.c: Remove _initialize_gdbtypes prototype. * gnu-nat.c: Remove _initialize_gnu_nat prototype. * gnu-v2-abi.c: Remove _initialize_gnu_v2_abi prototype. * gnu-v3-abi.c: Remove _initialize_gnu_v3_abi prototype. * go-lang.c: Remove _initialize_go_language prototype. * go32-nat.c: Remove _initialize_go32_nat prototype. * guile/guile.c: Remove _initialize_guile prototype. * h8300-tdep.c: Remove _initialize_h8300_tdep prototype. * hppa-linux-nat.c: Remove _initialize_hppa_linux_nat prototype. * hppa-linux-tdep.c: Remove _initialize_hppa_linux_tdep prototype. * hppa-nbsd-nat.c: Remove _initialize_hppanbsd_nat prototype. * hppa-nbsd-tdep.c: Remove _initialize_hppanbsd_tdep prototype. * hppa-obsd-nat.c: Remove _initialize_hppaobsd_nat prototype. * hppa-obsd-tdep.c: Remove _initialize_hppaobsd_tdep prototype. * hppa-tdep.c: Remove _initialize_hppa_tdep prototype. * i386-bsd-nat.c: Remove _initialize_i386bsd_nat prototype. * i386-cygwin-tdep.c: Remove _initialize_i386_cygwin_tdep prototype. * i386-darwin-tdep.c: Remove _initialize_i386_darwin_tdep prototype. * i386-dicos-tdep.c: Remove _initialize_i386_dicos_tdep prototype. * i386-fbsd-nat.c: Remove _initialize_i386fbsd_nat prototype. * i386-fbsd-tdep.c: Remove _initialize_i386fbsd_tdep prototype. * i386-gnu-nat.c: Remove _initialize_i386gnu_nat prototype. * i386-gnu-tdep.c: Remove _initialize_i386gnu_tdep prototype. * i386-linux-nat.c: Remove _initialize_i386_linux_nat prototype. * i386-linux-tdep.c: Remove _initialize_i386_linux_tdep prototype. * i386-nbsd-nat.c: Remove _initialize_i386nbsd_nat prototype. * i386-nbsd-tdep.c: Remove _initialize_i386nbsd_tdep prototype. * i386-nto-tdep.c: Remove _initialize_i386nto_tdep prototype. * i386-obsd-nat.c: Remove _initialize_i386obsd_nat prototype. * i386-obsd-tdep.c: Remove _initialize_i386obsd_tdep prototype. * i386-sol2-nat.c: Remove _initialize_amd64_sol2_nat prototype. * i386-sol2-tdep.c: Remove _initialize_amd64_sol2_tdep prototype. * i386-tdep.c: Remove _initialize_i386_tdep prototype. * i386-windows-nat.c: Remove _initialize_i386_windows_nat prototype. * ia64-libunwind-tdep.c: Remove _initialize_libunwind_frame prototype. * ia64-linux-nat.c: Remove _initialize_ia64_linux_nat prototype. * ia64-linux-tdep.c: Remove _initialize_ia64_linux_tdep prototype. * ia64-tdep.c: Remove _initialize_ia64_tdep prototype. * ia64-vms-tdep.c: Remove _initialize_ia64_vms_tdep prototype. * infcall.c: Remove _initialize_infcall prototype. * infcmd.c: Remove _initialize_infcmd prototype. * inferior.c: Remove _initialize_inferiors prototype. * inflow.c: Remove _initialize_inflow prototype. * infrun.c: Remove _initialize_infrun prototype. * interps.c: Remove _initialize_interpreter prototype. * iq2000-tdep.c: Remove _initialize_iq2000_tdep prototype. * jit.c: Remove _initialize_jit prototype. * language.c: Remove _initialize_language prototype. * linux-fork.c: Remove _initialize_linux_fork prototype. * linux-nat.c: Remove _initialize_linux_nat prototype. * linux-tdep.c: Remove _initialize_linux_tdep prototype. * linux-thread-db.c: Remove _initialize_thread_db prototype. * lm32-tdep.c: Remove _initialize_lm32_tdep prototype. * m2-lang.c: Remove _initialize_m2_language prototype. * m32c-tdep.c: Remove _initialize_m32c_tdep prototype. * m32r-linux-nat.c: Remove _initialize_m32r_linux_nat prototype. * m32r-linux-tdep.c: Remove _initialize_m32r_linux_tdep prototype. * m32r-tdep.c: Remove _initialize_m32r_tdep prototype. * m68hc11-tdep.c: Remove _initialize_m68hc11_tdep prototype. * m68k-bsd-nat.c: Remove _initialize_m68kbsd_nat prototype. * m68k-bsd-tdep.c: Remove _initialize_m68kbsd_tdep prototype. * m68k-linux-nat.c: Remove _initialize_m68k_linux_tdep prototype. * m68k-linux-tdep.c: Remove _initialize_m68k_linux_tdep prototype. * m68k-tdep.c: Remove _initialize_m68k_tdep prototype. * m88k-bsd-nat.c: Remove _initialize_m68kbsd_nat prototype. * m88k-tdep.c: Remove _initialize_m68kbsd_tdep prototype. * machoread.c: Remove _initialize_machoread prototype. * macrocmd.c: Remove _initialize_macrocmd prototype. * macroscope.c: Remove _initialize_macroscope prototype. * maint.c: Remove _initialize_maint_cmds prototype. * mdebugread.c: Remove _initialize_mdebugread prototype. * memattr.c: Remove _initialize_mem prototype. * mep-tdep.c: Remove _initialize_mep_tdep prototype. * mi/mi-cmd-env.c: Remove _initialize_mi_cmd_env prototype. * mi/mi-cmds.c: Remove _initialize_mi_cmds prototype. * mi/mi-interp.c: Remove _initialize_mi_interp prototype. * mi/mi-main.c: Remove _initialize_mi_main prototype. * microblaze-linux-tdep.c: Remove _initialize_microblaze_linux_tdep prototype. * microblaze-tdep.c: Remove _initialize_microblaze_tdep prototype. * mips-fbsd-nat.c: Remove _initialize_mips_fbsd_nat prototype. * mips-fbsd-tdep.c: Remove _initialize_mips_fbsd_tdep prototype. * mips-linux-nat.c: Remove _initialize_mips_linux_nat prototype. * mips-linux-tdep.c: Remove _initialize_mips_linux_tdep prototype. * mips-nbsd-nat.c: Remove _initialize_mipsnbsd_nat prototype. * mips-nbsd-tdep.c: Remove _initialize_mipsnbsd_tdep prototype. * mips-sde-tdep.c: Remove _initialize_mips_sde_tdep prototype. * mips-tdep.c: Remove _initialize_mips_tdep prototype. * mips64-obsd-nat.c: Remove _initialize_mips64obsd_nat prototype. * mips64-obsd-tdep.c: Remove _initialize_mips64obsd_tdep prototype. * mipsread.c: Remove _initialize_mipsread prototype. * mn10300-linux-tdep.c: Remove _initialize_mn10300_linux_tdep prototype. * mn10300-tdep.c: Remove _initialize_mn10300_tdep prototype. * moxie-tdep.c: Remove _initialize_moxie_tdep prototype. * msp430-tdep.c: Remove _initialize_msp430_tdep prototype. * mt-tdep.c: Remove _initialize_mt_tdep prototype. * nds32-tdep.c: Remove _initialize_nds32_tdep prototype. * nios2-linux-tdep.c: Remove _initialize_nios2_linux_tdep prototype. * nios2-tdep.c: Remove _initialize_nios2_tdep prototype. * nto-procfs.c: Remove _initialize_procfs prototype. * nto-tdep.c: Remove _initialize_nto_tdep prototype. * objc-lang.c: Remove _initialize_objc_language prototype. * objfiles.c: Remove _initialize_objfiles prototype. * observer.c: Remove observer_test_first_notification_function, observer_test_second_notification_function, observer_test_third_notification_function, and _initialize_observer prototypes. * opencl-lang.c: Remove _initialize_opencl_language prototypes. * osabi.c: Remove _initialize_gdb_osabi prototype. * osdata.c: Remove _initialize_osdata prototype. * p-valprint.c: Remove _initialize_pascal_valprint prototype. * parse.c: Remove _initialize_parse prototype. * ppc-fbsd-nat.c: Remove _initialize_ppcfbsd_nat prototype. * ppc-fbsd-tdep.c: Remove _initialize_ppcfbsd_tdep prototype. * ppc-linux-nat.c: Remove _initialize_ppc_linux_nat prototype. * ppc-linux-tdep.c: Remove _initialize_ppc_linux_tdep prototype. * ppc-nbsd-nat.c: Remove _initialize_ppcnbsd_nat prototype. * ppc-nbsd-tdep.c: Remove _initialize_ppcnbsd_tdep prototype. * ppc-obsd-nat.c: Remove _initialize_ppcobsd_nat prototype. * ppc-obsd-tdep.c: Remove _initialize_ppcobsd_tdep prototype. * printcmd.c: Remove _initialize_printcmd prototype. * probe.c: Remove _initialize_probe prototype. * proc-api.c: Remove _initialize_proc_api prototype. * proc-events.c: Remove _initialize_proc_events prototype. * proc-service.c: Remove _initialize_proc_service prototype. * procfs.c: Remove _initialize_procfs prototype. * psymtab.c: Remove _initialize_psymtab prototype. * python/python.c: Remove _initialize_python prototype. * ravenscar-thread.c: Remove _initialize_ravenscar prototype. * record-btrace.c: Remove _initialize_record_btrace prototype. * record-full.c: Remove _initialize_record_full prototype. * record.c: Remove _initialize_record prototype. * regcache.c: Remove _initialize_regcache prototype. * reggroups.c: Remove _initialize_reggroup prototype. * remote-notif.c: Remove _initialize_notif prototype. * remote-sim.c: Remove _initialize_remote_sim prototype. * remote.c: Remove _initialize_remote prototype. * reverse.c: Remove _initialize_reverse prototype. * rl78-tdep.c: Remove _initialize_rl78_tdep prototype. * rs6000-aix-tdep.c: Remove _initialize_rs6000_aix_tdep prototype. * rs6000-lynx178-tdep.c: Remove _initialize_rs6000_lynx178_tdep prototype. * rs6000-nat.c: Remove _initialize_rs6000_nat prototype. * rs6000-tdep.c: Remove _initialize_rs6000_tdep prototype. * rust-exp.y: Remove _initialize_rust_exp prototype. * rx-tdep.c: Remove _initialize_rx_tdep prototype. * s390-linux-nat.c: Remove _initialize_s390_nat prototype. * s390-linux-tdep.c: Remove _initialize_s390_tdep prototype. * score-tdep.c: Remove _initialize_score_tdep prototype. * selftest-arch.c: Remove _initialize_selftests_foreach_arch prototype. * ser-go32.c: Remove _initialize_ser_dos prototype. * ser-mingw.c: Remove _initialize_ser_windows prototype. * ser-pipe.c: Remove _initialize_ser_pipe prototype. * ser-tcp.c: Remove _initialize_ser_tcp prototype. * ser-unix.c: Remove _initialize_ser_hardwire prototype. * serial.c: Remove _initialize_serial prototype. * sh-linux-tdep.c: Remove _initialize_sh_linux_tdep prototype. * sh-nbsd-nat.c: Remove _initialize_shnbsd_nat prototype. * sh-nbsd-tdep.c: Remove _initialize_shnbsd_tdep prototype. * sh-tdep.c: Remove _initialize_sh_tdep prototype. * skip.c: Remove _initialize_step_skip prototype. * sol-thread.c: Remove _initialize_sol_thread prototype. * solib-aix.c: Remove _initialize_solib_aix prototype. * solib-darwin.c: Remove _initialize_darwin_solib prototype. * solib-dsbt.c: Remove _initialize_dsbt_solib prototype. * solib-frv.c: Remove _initialize_frv_solib prototype. * solib-spu.c: Remove _initialize_spu_solib prototype. * solib-svr4.c: Remove _initialize_svr4_solib prototype. * solib-target.c: Remove _initialize_solib_target prototype. * solib.c: Remove _initialize_solib prototype. * source.c: Remove _initialize_source prototype. * sparc-linux-nat.c: Remove _initialize_sparc_linux_nat prototype. * sparc-linux-tdep.c: Remove _initialize_sparc_linux_tdep prototype. * sparc-nat.c: Remove _initialize_sparc_nat prototype. * sparc-nbsd-nat.c: Remove _initialize_sparcnbsd_nat prototype. * sparc-nbsd-tdep.c: Remove _initialize_sparcnbsd_tdep prototype. * sparc-obsd-tdep.c: Remove _initialize_sparc32obsd_tdep prototype. * sparc-sol2-nat.c: Remove _initialize_sparc_sol2_nat prototype. * sparc-sol2-tdep.c: Remove _initialize_sparc_sol2_tdep prototype. * sparc-tdep.c: Remove _initialize_sparc_tdep prototype. * sparc64-fbsd-nat.c: Remove _initialize_sparc64fbsd_nat prototype. * sparc64-fbsd-tdep.c: Remove _initialize_sparc64fbsd_tdep prototype. * sparc64-linux-nat.c: Remove _initialize_sparc64_linux_nat prototype. * sparc64-linux-tdep.c: Remove _initialize_sparc64_linux_tdep prototype. * sparc64-nat.c: Remove _initialize_sparc64_nat prototype. * sparc64-nbsd-nat.c: Remove _initialize_sparc64nbsd_nat prototype. * sparc64-nbsd-tdep.c: Remove _initialize_sparc64nbsd_tdep prototype. * sparc64-obsd-nat.c: Remove _initialize_sparc64obsd_nat prototype. * sparc64-obsd-tdep.c: Remove _initialize_sparc64obsd_tdep prototype. * sparc64-sol2-tdep.c: Remove _initialize_sparc64_sol2_tdep prototype. * spu-linux-nat.c: Remove _initialize_spu_nat prototype. * spu-multiarch.c: Remove _initialize_spu_multiarch prototype. * spu-tdep.c: Remove _initialize_spu_tdep prototype. * stabsread.c: Remove _initialize_stabsread prototype. * stack.c: Remove _initialize_stack prototype. * stap-probe.c: Remove _initialize_stap_probe prototype. * std-regs.c: Remove _initialize_frame_reg prototype. * symfile-debug.c: Remove _initialize_symfile_debug prototype. * symfile-mem.c: Remove _initialize_symfile_mem prototype. * symfile.c: Remove _initialize_symfile prototype. * symmisc.c: Remove _initialize_symmisc prototype. * symtab.c: Remove _initialize_symtab prototype. * target-dcache.c: Remove _initialize_target_dcache prototype. * target-descriptions.c: Remove _initialize_target_descriptions prototype. * thread.c: Remove _initialize_thread prototype. * tic6x-linux-tdep.c: Remove _initialize_tic6x_linux_tdep prototype. * tic6x-tdep.c: Remove _initialize_tic6x_tdep prototype. * tilegx-linux-nat.c: Remove _initialize_tile_linux_nat prototype. * tilegx-linux-tdep.c: Remove _initialize_tilegx_linux_tdep prototype. * tilegx-tdep.c: Remove _initialize_tilegx_tdep prototype. * tracefile-tfile.c: Remove _initialize_tracefile_tfile prototype. * tracefile.c: Remove _initialize_tracefile prototype. * tracepoint.c: Remove _initialize_tracepoint prototype. * tui/tui-hooks.c: Remove _initialize_tui_hooks prototype. * tui/tui-interp.c: Remove _initialize_tui_interp prototype. * tui/tui-layout.c: Remove _initialize_tui_layout prototype. * tui/tui-regs.c: Remove _initialize_tui_regs prototype. * tui/tui-stack.c: Remove _initialize_tui_stack prototype. * tui/tui-win.c: Remove _initialize_tui_win prototype. * tui/tui.c: Remove _initialize_tui prototype. * typeprint.c: Remove _initialize_typeprint prototype. * user-regs.c: Remove _initialize_user_regs prototype. * utils.c: Remove _initialize_utils prototype. * v850-tdep.c: Remove _initialize_v850_tdep prototype. * valarith.c: Remove _initialize_valarith prototype. * valops.c: Remove _initialize_valops prototype. * valprint.c: Remove _initialize_valprint prototype. * value.c: Remove _initialize_values prototype. * varobj.c: Remove _initialize_varobj prototype. * vax-bsd-nat.c: Remove _initialize_vaxbsd_nat prototype. * vax-nbsd-tdep.c: Remove _initialize_vaxnbsd_tdep prototype. * vax-tdep.c: Remove _initialize_vax_tdep prototype. * windows-nat.c: Remove _initialize_windows_nat, _initialize_check_for_gdb_ini, and _initialize_loadable prototypes. * windows-tdep.c: Remove _initialize_windows_tdep prototype. * xcoffread.c: Remove _initialize_xcoffread prototype. * xml-support.c: Remove _initialize_xml_support prototype. * xstormy16-tdep.c: Remove _initialize_xstormy16_tdep prototype. * xtensa-linux-nat.c: Remove _initialize_xtensa_linux_nat prototype. * xtensa-linux-tdep.c: Remove _initialize_xtensa_linux_tdep prototype. * xtensa-tdep.c: Remove _initialize_xtensa_tdep prototype. --- gdb/python/python.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/python.c b/gdb/python/python.c index f40fe89..b086cef 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -1472,12 +1472,6 @@ finalize_python (void *ignore) restore_active_ext_lang (previous_active); } -#endif - -/* Provide a prototype to silence -Wmissing-prototypes. */ -extern initialize_file_ftype _initialize_python; - -#ifdef HAVE_PYTHON static bool do_start_initialization () -- cgit v1.1 From 7c96f8c1dae023c7d0b1cabc5e50c4d18fd06960 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Tue, 5 Sep 2017 12:07:00 -0600 Subject: Add new_inferior, inferior_deleted, and new_thread events This adds a few new events to gdb's Python layer: new_inferior, inferior_deleted, and new_thread. I wanted to be able to add a combined inferior/thread display window to my GUI, and I needed a few events to make this work. This is PR python/15622. ChangeLog 2017-09-11 Tom Tromey PR python/15622: * NEWS: Add entry. * python/python.c (do_start_initialization): Initialize new event types. * python/python-internal.h (gdbpy_initialize_new_inferior_event) (gdbpy_initialize_inferior_deleted_event) (gdbpy_initialize_new_thread_event): Declare. * python/py-threadevent.c (create_thread_event_object): Add option "thread" parameter. * python/py-inferior.c (new_thread_event_object_type) (new_inferior_event_object_type) (inferior_deleted_event_object_type): Declare. (python_new_inferior, python_inferior_deleted): New functions. (add_thread_object): Emit new_thread event. (gdbpy_initialize_inferior): Attach new functions to corresponding observers. (new_thread, new_inferior, inferior_deleted): Define new event types. * python/py-evts.c (gdbpy_initialize_py_events): Add new registries. * python/py-events.h (events_object) : New fields. * python/py-event.h (create_thread_event_breakpoint): Add optional "thread" parameter. doc/ChangeLog 2017-09-11 Tom Tromey * python.texi (Events In Python): Document new events. testsuite/ChangeLog 2017-09-11 Tom Tromey * gdb.python/py-infthread.exp: Add tests for new_thread event. * gdb.python/py-inferior.exp: Add tests for new inferior events. --- gdb/python/py-event.h | 3 +- gdb/python/py-events.h | 3 ++ gdb/python/py-evts.c | 9 +++++ gdb/python/py-inferior.c | 88 ++++++++++++++++++++++++++++++++++++++++++++ gdb/python/py-threadevent.c | 13 ++++--- gdb/python/python-internal.h | 6 +++ gdb/python/python.c | 3 ++ 7 files changed, 118 insertions(+), 7 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/py-event.h b/gdb/python/py-event.h index ccb8513..2f02c5f 100644 --- a/gdb/python/py-event.h +++ b/gdb/python/py-event.h @@ -125,7 +125,8 @@ extern int evpy_emit_event (PyObject *event, eventregistry_object *registry); extern PyObject *create_event_object (PyTypeObject *py_type); -extern PyObject *create_thread_event_object (PyTypeObject *py_type); +extern PyObject *create_thread_event_object (PyTypeObject *py_type, + PyObject *thread = nullptr); extern int emit_new_objfile_event (struct objfile *objfile); extern int emit_clear_objfiles_event (void); diff --git a/gdb/python/py-events.h b/gdb/python/py-events.h index 348dabc..2275d89 100644 --- a/gdb/python/py-events.h +++ b/gdb/python/py-events.h @@ -47,6 +47,9 @@ typedef struct eventregistry_object *exited; eventregistry_object *new_objfile; eventregistry_object *clear_objfiles; + eventregistry_object *new_inferior; + eventregistry_object *inferior_deleted; + eventregistry_object *new_thread; eventregistry_object *inferior_call; eventregistry_object *memory_changed; eventregistry_object *register_changed; diff --git a/gdb/python/py-evts.c b/gdb/python/py-evts.c index 126d18c..ad99241 100644 --- a/gdb/python/py-evts.c +++ b/gdb/python/py-evts.c @@ -89,6 +89,15 @@ gdbpy_initialize_py_events (void) if (add_new_registry (&gdb_py_events.clear_objfiles, "clear_objfiles") < 0) return -1; + if (add_new_registry (&gdb_py_events.new_inferior, "new_inferior") < 0) + return -1; + + if (add_new_registry (&gdb_py_events.inferior_deleted, "inferior_deleted") < 0) + return -1; + + if (add_new_registry (&gdb_py_events.new_thread, "new_thread") < 0) + return -1; + if (add_new_registry (&gdb_py_events.breakpoint_created, "breakpoint_created") < 0) return -1; diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c index f6a24a0..d7c6810 100644 --- a/gdb/python/py-inferior.c +++ b/gdb/python/py-inferior.c @@ -30,6 +30,13 @@ #include "py-event.h" #include "py-stopevent.h" +extern PyTypeObject new_thread_event_object_type + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); +extern PyTypeObject new_inferior_event_object_type + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); +extern PyTypeObject inferior_deleted_event_object_type + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); + struct threadlist_entry { thread_object *thread_obj; struct threadlist_entry *next; @@ -235,6 +242,60 @@ inferior_to_inferior_object (struct inferior *inferior) return (PyObject *) inf_obj; } +/* Called when a new inferior is created. Notifies any Python event + listeners. */ +static void +python_new_inferior (struct inferior *inf) +{ + if (!gdb_python_initialized) + return; + + gdbpy_enter enter_py (python_gdbarch, python_language); + + if (evregpy_no_listeners_p (gdb_py_events.new_inferior)) + return; + + gdbpy_ref<> inf_obj (inferior_to_inferior_object (inf)); + if (inf_obj == NULL) + { + gdbpy_print_stack (); + return; + } + + gdbpy_ref<> event (create_event_object (&new_inferior_event_object_type)); + if (event == NULL + || evpy_add_attribute (event.get (), "inferior", inf_obj.get ()) < 0 + || evpy_emit_event (event.get (), gdb_py_events.new_inferior) < 0) + gdbpy_print_stack (); +} + +/* Called when an inferior is removed. Notifies any Python event + listeners. */ +static void +python_inferior_deleted (struct inferior *inf) +{ + if (!gdb_python_initialized) + return; + + gdbpy_enter enter_py (python_gdbarch, python_language); + + if (evregpy_no_listeners_p (gdb_py_events.inferior_deleted)) + return; + + gdbpy_ref<> inf_obj (inferior_to_inferior_object (inf)); + if (inf_obj == NULL) + { + gdbpy_print_stack (); + return; + } + + gdbpy_ref<> event (create_event_object (&inferior_deleted_event_object_type)); + if (event == NULL + || evpy_add_attribute (event.get (), "inferior", inf_obj.get ()) < 0 + || evpy_emit_event (event.get (), gdb_py_events.inferior_deleted) < 0) + gdbpy_print_stack (); +} + /* Finds the Python Inferior object for the given PID. Returns a reference, or NULL if PID does not match any inferior object. */ @@ -298,6 +359,15 @@ add_thread_object (struct thread_info *tp) inf_obj->threads = entry; inf_obj->nthreads++; + + if (evregpy_no_listeners_p (gdb_py_events.new_thread)) + return; + + gdbpy_ref<> event (create_thread_event_object (&new_thread_event_object_type, + (PyObject *) thread_obj)); + if (event == NULL + || evpy_emit_event (event.get (), gdb_py_events.new_thread) < 0) + gdbpy_print_stack (); } static void @@ -823,6 +893,8 @@ gdbpy_initialize_inferior (void) observer_attach_register_changed (python_on_register_change); observer_attach_inferior_exit (python_inferior_exit); observer_attach_new_objfile (python_new_objfile); + observer_attach_inferior_added (python_new_inferior); + observer_attach_inferior_removed (python_inferior_deleted); membuf_object_type.tp_new = PyType_GenericNew; if (PyType_Ready (&membuf_object_type) < 0) @@ -970,3 +1042,19 @@ PyTypeObject membuf_object_type = { 0, /* tp_init */ 0, /* tp_alloc */ }; + +GDBPY_NEW_EVENT_TYPE (new_thread, + "gdb.NewThreadEvent", + "NewThreadEvent", + "GDB new thread event object", + thread_event_object_type); +GDBPY_NEW_EVENT_TYPE (new_inferior, + "gdb.NewInferiorEvent", + "NewInferiorEvent", + "GDB new inferior event object", + event_object_type); +GDBPY_NEW_EVENT_TYPE (inferior_deleted, + "gdb.InferiorDeletedEvent", + "InferiorDeletedEvent", + "GDB inferior deleted event object", + event_object_type); diff --git a/gdb/python/py-threadevent.c b/gdb/python/py-threadevent.c index 9217444..7211fa2 100644 --- a/gdb/python/py-threadevent.c +++ b/gdb/python/py-threadevent.c @@ -48,17 +48,18 @@ get_event_thread (void) } PyObject * -create_thread_event_object (PyTypeObject *py_type) +create_thread_event_object (PyTypeObject *py_type, PyObject *thread) { - PyObject *thread = NULL; - gdbpy_ref<> thread_event_obj (create_event_object (py_type)); if (thread_event_obj == NULL) return NULL; - thread = get_event_thread (); - if (!thread) - return NULL; + if (thread == NULL) + { + thread = get_event_thread (); + if (!thread) + return NULL; + } if (evpy_add_attribute (thread_event_obj.get (), "inferior_thread", diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index ebb83f0..0c3582f 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -630,6 +630,12 @@ int gdbpy_initialize_new_objfile_event (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; int gdbpy_initialize_clear_objfiles_event (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; +int gdbpy_initialize_new_inferior_event (void) + CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; +int gdbpy_initialize_inferior_deleted_event (void) + CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; +int gdbpy_initialize_new_thread_event (void) + CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; int gdbpy_initialize_arch (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; int gdbpy_initialize_xmethods (void) diff --git a/gdb/python/python.c b/gdb/python/python.c index b086cef..fbb4747 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -1603,6 +1603,9 @@ do_start_initialization () || gdbpy_initialize_thread_event () < 0 || gdbpy_initialize_new_objfile_event () < 0 || gdbpy_initialize_clear_objfiles_event () < 0 + || gdbpy_initialize_new_inferior_event () < 0 + || gdbpy_initialize_inferior_deleted_event () < 0 + || gdbpy_initialize_new_thread_event () < 0 || gdbpy_initialize_arch () < 0 || gdbpy_initialize_xmethods () < 0 || gdbpy_initialize_unwind () < 0) -- cgit v1.1 From 35c61a1dd5462ceab42618c48c9a60238245761b Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 8 Sep 2017 14:26:43 -0600 Subject: Small event ownership clean up in Python layer It seems cleaner to me for functions like create_thread_event_object, which pass object ownership to their callers, to directly return a gdb_ref<>. This way the ownership transfer is part of the API. This patch makes this change. ChangeLog 2017-09-11 Tom Tromey * python/py-threadevent.c (create_thread_event_object): Return gdbpy_ref. * python/py-stopevent.h (create_stop_event_object) (create_breakpoint_event_object, create_signal_event_object): Update. * python/py-stopevent.c (create_stop_event_object): Return gdbpy_ref. (emit_stop_event): Update. * python/py-signalevent.c (create_signal_event_object): Return gdbpy_ref. * python/py-infevents.c (create_inferior_call_event_object): Update. * python/py-event.h (create_event_object) (create_thread_event_object): Update. * python/py-event.c (create_event_object): Return gdbpy_ref. * python/py-continueevent.c: Return gdbpy_ref. * python/py-bpevent.c (create_breakpoint_event_object): Return gdbpy_ref. --- gdb/python/py-bpevent.c | 4 ++-- gdb/python/py-continueevent.c | 2 +- gdb/python/py-event.c | 4 ++-- gdb/python/py-event.h | 6 +++--- gdb/python/py-infevents.c | 4 ++-- gdb/python/py-signalevent.c | 4 ++-- gdb/python/py-stopevent.c | 10 +++++----- gdb/python/py-stopevent.h | 8 ++++---- gdb/python/py-threadevent.c | 4 ++-- 9 files changed, 23 insertions(+), 23 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/py-bpevent.c b/gdb/python/py-bpevent.c index c5a85b6..021c83a 100644 --- a/gdb/python/py-bpevent.c +++ b/gdb/python/py-bpevent.c @@ -27,7 +27,7 @@ extern PyTypeObject breakpoint_event_object_type /* Create and initialize a BreakpointEvent object. This acquires new references to BREAKPOINT_LIST and FIRST_BP. */ -PyObject * +gdbpy_ref<> create_breakpoint_event_object (PyObject *breakpoint_list, PyObject *first_bp) { gdbpy_ref<> breakpoint_event_obj @@ -45,7 +45,7 @@ create_breakpoint_event_object (PyObject *breakpoint_list, PyObject *first_bp) breakpoint_list) < 0) return NULL; - return breakpoint_event_obj.release (); + return breakpoint_event_obj; } GDBPY_NEW_EVENT_TYPE (breakpoint, diff --git a/gdb/python/py-continueevent.c b/gdb/python/py-continueevent.c index 8be28c2..ca2927f 100644 --- a/gdb/python/py-continueevent.c +++ b/gdb/python/py-continueevent.c @@ -24,7 +24,7 @@ extern PyTypeObject continue_event_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); -static PyObject * +static gdbpy_ref<> create_continue_event_object (void) { return create_thread_event_object (&continue_event_object_type); diff --git a/gdb/python/py-event.c b/gdb/python/py-event.c index b349891..9d84e33 100644 --- a/gdb/python/py-event.c +++ b/gdb/python/py-event.c @@ -27,7 +27,7 @@ evpy_dealloc (PyObject *self) Py_TYPE (self)->tp_free (self); } -PyObject * +gdbpy_ref<> create_event_object (PyTypeObject *py_type) { gdbpy_ref event_obj (PyObject_New (event_object, py_type)); @@ -38,7 +38,7 @@ create_event_object (PyTypeObject *py_type) if (!event_obj->dict) return NULL; - return (PyObject*) event_obj.release (); + return gdbpy_ref<> ((PyObject *) event_obj.release ()); } /* Add the attribute ATTR to the event object EVENT. In diff --git a/gdb/python/py-event.h b/gdb/python/py-event.h index 2f02c5f..27db828 100644 --- a/gdb/python/py-event.h +++ b/gdb/python/py-event.h @@ -124,9 +124,9 @@ extern int emit_memory_changed_event (CORE_ADDR addr, ssize_t len); extern int evpy_emit_event (PyObject *event, eventregistry_object *registry); -extern PyObject *create_event_object (PyTypeObject *py_type); -extern PyObject *create_thread_event_object (PyTypeObject *py_type, - PyObject *thread = nullptr); +extern gdbpy_ref<> create_event_object (PyTypeObject *py_type); +extern gdbpy_ref<> create_thread_event_object (PyTypeObject *py_type, + PyObject *thread = nullptr); extern int emit_new_objfile_event (struct objfile *objfile); extern int emit_clear_objfiles_event (void); diff --git a/gdb/python/py-infevents.c b/gdb/python/py-infevents.c index 6e3c8c8..8a63b79 100644 --- a/gdb/python/py-infevents.c +++ b/gdb/python/py-infevents.c @@ -43,10 +43,10 @@ create_inferior_call_event_object (inferior_call_kind flag, ptid_t ptid, switch (flag) { case INFERIOR_CALL_PRE: - event.reset (create_event_object (&inferior_call_pre_event_object_type)); + event = create_event_object (&inferior_call_pre_event_object_type); break; case INFERIOR_CALL_POST: - event.reset (create_event_object (&inferior_call_post_event_object_type)); + event = create_event_object (&inferior_call_post_event_object_type); break; default: gdb_assert_not_reached ("invalid inferior_call_kind"); diff --git a/gdb/python/py-signalevent.c b/gdb/python/py-signalevent.c index a8f41c2..c2391de 100644 --- a/gdb/python/py-signalevent.c +++ b/gdb/python/py-signalevent.c @@ -23,7 +23,7 @@ extern PyTypeObject signal_event_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); -PyObject * +gdbpy_ref<> create_signal_event_object (enum gdb_signal stop_signal) { const char *signal_name; @@ -43,7 +43,7 @@ create_signal_event_object (enum gdb_signal stop_signal) signal_name_obj.get ()) < 0) return NULL; - return signal_event_obj.release (); + return signal_event_obj; } GDBPY_NEW_EVENT_TYPE (signal, diff --git a/gdb/python/py-stopevent.c b/gdb/python/py-stopevent.c index cfa4591..a0be5f2 100644 --- a/gdb/python/py-stopevent.c +++ b/gdb/python/py-stopevent.c @@ -20,7 +20,7 @@ #include "defs.h" #include "py-stopevent.h" -PyObject * +gdbpy_ref<> create_stop_event_object (PyTypeObject *py_type) { return create_thread_event_object (py_type); @@ -70,8 +70,8 @@ emit_stop_event (struct bpstats *bs, enum gdb_signal stop_signal) if (list != NULL) { - stop_event_obj.reset (create_breakpoint_event_object (list.get (), - first_bp)); + stop_event_obj = create_breakpoint_event_object (list.get (), + first_bp); if (stop_event_obj == NULL) return -1; } @@ -80,7 +80,7 @@ emit_stop_event (struct bpstats *bs, enum gdb_signal stop_signal) if (stop_signal != GDB_SIGNAL_0 && stop_signal != GDB_SIGNAL_TRAP) { - stop_event_obj.reset (create_signal_event_object (stop_signal)); + stop_event_obj = create_signal_event_object (stop_signal); if (stop_event_obj == NULL) return -1; } @@ -89,7 +89,7 @@ emit_stop_event (struct bpstats *bs, enum gdb_signal stop_signal) be known and this should eventually be unused. */ if (stop_event_obj == NULL) { - stop_event_obj.reset (create_stop_event_object (&stop_event_object_type)); + stop_event_obj = create_stop_event_object (&stop_event_object_type); if (stop_event_obj == NULL) return -1; } diff --git a/gdb/python/py-stopevent.h b/gdb/python/py-stopevent.h index a56ca7e..62c52d7 100644 --- a/gdb/python/py-stopevent.h +++ b/gdb/python/py-stopevent.h @@ -22,15 +22,15 @@ #include "py-event.h" -extern PyObject *create_stop_event_object (PyTypeObject *py_type); +extern gdbpy_ref<> create_stop_event_object (PyTypeObject *py_type); extern void stop_evpy_dealloc (PyObject *self); extern int emit_stop_event (struct bpstats *bs, enum gdb_signal stop_signal); -extern PyObject *create_breakpoint_event_object (PyObject *breakpoint_list, - PyObject *first_bp); +extern gdbpy_ref<> create_breakpoint_event_object (PyObject *breakpoint_list, + PyObject *first_bp); -extern PyObject *create_signal_event_object (enum gdb_signal stop_signal); +extern gdbpy_ref<> create_signal_event_object (enum gdb_signal stop_signal); #endif /* GDB_PY_STOPEVENT_H */ diff --git a/gdb/python/py-threadevent.c b/gdb/python/py-threadevent.c index 7211fa2..8b742ca 100644 --- a/gdb/python/py-threadevent.c +++ b/gdb/python/py-threadevent.c @@ -47,7 +47,7 @@ get_event_thread (void) return thread; } -PyObject * +gdbpy_ref<> create_thread_event_object (PyTypeObject *py_type, PyObject *thread) { gdbpy_ref<> thread_event_obj (create_event_object (py_type)); @@ -66,7 +66,7 @@ create_thread_event_object (PyTypeObject *py_type, PyObject *thread) thread) < 0) return NULL; - return thread_event_obj.release (); + return thread_event_obj; } GDBPY_NEW_EVENT_TYPE (thread, -- cgit v1.1 From 7d221d749c0239f06ca571be6c9452cd22b5d582 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 8 Sep 2017 15:38:12 -0600 Subject: Make it simpler to add events to Python The first patch in this series went through several iterations as I'd forgotten how many places had to be touched to add a new event and a new event type. This patch simplifies the process using two new ".def" files. Now, a new event type can be added by adding a line to "py-event-types.def", and a new event registry can be added by adding a line to "py-all-events.def". ChangeLog 2017-09-11 Tom Tromey * python/python.c (do_start_initialization): Use py-event-types.def to initialize types. Define all object type structures. * python/python-internal.h: Don't declare event initialization functions. * python/py-threadevent.c (thread_event_object_type): Don't define. * python/py-stopevent.c (stop_event_object_type): Don't define. * python/py-signalevent.c (signal_event_object_type): Don't declare or define. * python/py-newobjfileevent.c (new_objfile_event_object_type) (clear_objfiles_event_object_type): Don't declare or define. * python/py-infevents.c (inferior_call_pre_event_object_type) (inferior_call_post_event_object_type) (register_changed_event_object_type) (memory_changed_event_object_type): Don't declare or define. * python/py-inferior.c (new_thread_event_object_type) (new_inferior_event_object_type) (inferior_deleted_event_object_type): Don't declare or define. * python/py-exitedevent.c (exited_event_object_type): Don't declare or define. * python/py-evts.c (gdbpy_initialize_py_events): Use py-all-events.def. * python/py-events.h (thread_event_object_type): Don't declare. (events_object): Use py-all-events.def. * python/py-event.h (GDBPY_NEW_EVENT_TYPE): Remove. Use py-event-types.def. * python/py-event-types.def: New file. * python/py-continueevent.c (create_continue_event_object): Don't declare or define. * python/py-bpevent.c (breakpoint_event_object_type): Don't declare or define. * python/py-all-events.def: New file. --- gdb/python/py-all-events.def | 40 +++++++++++++++ gdb/python/py-bpevent.c | 9 ---- gdb/python/py-continueevent.c | 9 ---- gdb/python/py-event-types.def | 107 ++++++++++++++++++++++++++++++++++++++++ gdb/python/py-event.h | 74 +++------------------------ gdb/python/py-events.h | 22 ++------- gdb/python/py-evts.c | 52 ++----------------- gdb/python/py-exitedevent.c | 10 ---- gdb/python/py-inferior.c | 23 --------- gdb/python/py-infevents.c | 34 ------------- gdb/python/py-newobjfileevent.c | 16 ------ gdb/python/py-signalevent.c | 9 ---- gdb/python/py-stopevent.c | 6 --- gdb/python/py-threadevent.c | 6 --- gdb/python/python-internal.h | 32 ------------ gdb/python/python.c | 68 +++++++++++++++++++------ 16 files changed, 214 insertions(+), 303 deletions(-) create mode 100644 gdb/python/py-all-events.def create mode 100644 gdb/python/py-event-types.def (limited to 'gdb/python') diff --git a/gdb/python/py-all-events.def b/gdb/python/py-all-events.def new file mode 100644 index 0000000..cdede6b --- /dev/null +++ b/gdb/python/py-all-events.def @@ -0,0 +1,40 @@ +/* Python event definitions -*- c++ -*- + + Copyright (C) 2017 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* To use this file, define GDB_PY_DEFINE_EVENT to expand how you + like, then include the file. + + GDB_PY_DEFINE_EVENT has one parameter, the name of the event. +*/ + +GDB_PY_DEFINE_EVENT(stop) +GDB_PY_DEFINE_EVENT(cont) +GDB_PY_DEFINE_EVENT(exited) +GDB_PY_DEFINE_EVENT(new_objfile) +GDB_PY_DEFINE_EVENT(clear_objfiles) +GDB_PY_DEFINE_EVENT(new_inferior) +GDB_PY_DEFINE_EVENT(inferior_deleted) +GDB_PY_DEFINE_EVENT(new_thread) +GDB_PY_DEFINE_EVENT(inferior_call) +GDB_PY_DEFINE_EVENT(memory_changed) +GDB_PY_DEFINE_EVENT(register_changed) +GDB_PY_DEFINE_EVENT(breakpoint_created) +GDB_PY_DEFINE_EVENT(breakpoint_deleted) +GDB_PY_DEFINE_EVENT(breakpoint_modified) +GDB_PY_DEFINE_EVENT(before_prompt) diff --git a/gdb/python/py-bpevent.c b/gdb/python/py-bpevent.c index 021c83a..1cb3f9a 100644 --- a/gdb/python/py-bpevent.c +++ b/gdb/python/py-bpevent.c @@ -21,9 +21,6 @@ #include "py-stopevent.h" #include "py-ref.h" -extern PyTypeObject breakpoint_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); - /* Create and initialize a BreakpointEvent object. This acquires new references to BREAKPOINT_LIST and FIRST_BP. */ @@ -47,9 +44,3 @@ create_breakpoint_event_object (PyObject *breakpoint_list, PyObject *first_bp) return breakpoint_event_obj; } - -GDBPY_NEW_EVENT_TYPE (breakpoint, - "gdb.BreakpointEvent", - "BreakpointEvent", - "GDB breakpoint stop event object", - stop_event_object_type); diff --git a/gdb/python/py-continueevent.c b/gdb/python/py-continueevent.c index ca2927f..8c704b9 100644 --- a/gdb/python/py-continueevent.c +++ b/gdb/python/py-continueevent.c @@ -21,9 +21,6 @@ #include "py-event.h" #include "py-ref.h" -extern PyTypeObject continue_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); - static gdbpy_ref<> create_continue_event_object (void) { @@ -45,9 +42,3 @@ emit_continue_event (ptid_t ptid) return evpy_emit_event (event.get (), gdb_py_events.cont); return -1; } - -GDBPY_NEW_EVENT_TYPE (continue, - "gdb.ContinueEvent", - "ContinueEvent", - "GDB continue event object", - thread_event_object_type); diff --git a/gdb/python/py-event-types.def b/gdb/python/py-event-types.def new file mode 100644 index 0000000..f571f66 --- /dev/null +++ b/gdb/python/py-event-types.def @@ -0,0 +1,107 @@ +/* Python event definitions -*- c++ -*- + + Copyright (C) 2017 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* To use this file, define GDB_PY_DEFINE_EVENT_TYPE to expand how you + like, then include the file. + + Each invocation is of the form: + + GDB_PY_DEFINE_EVENT_TYPE(name, py_name, doc, base) + + NAME is the name of the event. + PY_NAME a string representing what the event should be called in + python. + DOC Python documentation for the new event type + BASE the base event for this event usually just event_object_type. +*/ + +GDB_PY_DEFINE_EVENT_TYPE (breakpoint, + "BreakpointEvent", + "GDB breakpoint stop event object", + stop_event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (continue, + "ContinueEvent", + "GDB continue event object", + thread_event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (exited, + "ExitedEvent", + "GDB exited event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (new_thread, + "NewThreadEvent", + "GDB new thread event object", + thread_event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (new_inferior, + "NewInferiorEvent", + "GDB new inferior event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (inferior_deleted, + "InferiorDeletedEvent", + "GDB inferior deleted event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (inferior_call_pre, + "InferiorCallPreEvent", + "GDB inferior function pre-call event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (inferior_call_post, + "InferiorCallPostEvent", + "GDB inferior function post-call event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (register_changed, + "RegisterChangedEvent", + "GDB register change event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (memory_changed, + "MemoryChangedEvent", + "GDB memory change event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (new_objfile, + "NewObjFileEvent", + "GDB new object file event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (clear_objfiles, + "ClearObjFilesEvent", + "GDB clear object files event object", + event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (signal, + "SignalEvent", + "GDB signal event object", + stop_event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (stop, + "StopEvent", + "GDB stop event object", + thread_event_object_type); + +GDB_PY_DEFINE_EVENT_TYPE (thread, + "ThreadEvent", + "GDB thread event object", + event_object_type); diff --git a/gdb/python/py-event.h b/gdb/python/py-event.h index 27db828..2444260 100644 --- a/gdb/python/py-event.h +++ b/gdb/python/py-event.h @@ -26,74 +26,12 @@ #include "inferior.h" #include "py-ref.h" -/* This macro creates the following functions: - - gdbpy_initialize_{NAME}_event - Used to add the newly created event type to the gdb module. - - and the python type data structure for the event: - - struct PyTypeObject {NAME}_event_object_type - - NAME is the name of the event. - PY_PATH is a string representing the module and python name of - the event. - PY_NAME a string representing what the event should be called in - python. - DOC Python documentation for the new event type - BASE the base event for this event usually just event_object_type. -*/ - -#define GDBPY_NEW_EVENT_TYPE(name, py_path, py_name, doc, base) \ -\ - PyTypeObject name##_event_object_type \ - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object") \ - = { \ - PyVarObject_HEAD_INIT (NULL, 0) \ - py_path, /* tp_name */ \ - sizeof (event_object), /* tp_basicsize */ \ - 0, /* tp_itemsize */ \ - evpy_dealloc, /* tp_dealloc */ \ - 0, /* tp_print */ \ - 0, /* tp_getattr */ \ - 0, /* tp_setattr */ \ - 0, /* tp_compare */ \ - 0, /* tp_repr */ \ - 0, /* tp_as_number */ \ - 0, /* tp_as_sequence */ \ - 0, /* tp_as_mapping */ \ - 0, /* tp_hash */ \ - 0, /* tp_call */ \ - 0, /* tp_str */ \ - 0, /* tp_getattro */ \ - 0, /* tp_setattro */ \ - 0, /* tp_as_buffer */ \ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ \ - doc, /* tp_doc */ \ - 0, /* tp_traverse */ \ - 0, /* tp_clear */ \ - 0, /* tp_richcompare */ \ - 0, /* tp_weaklistoffset */ \ - 0, /* tp_iter */ \ - 0, /* tp_iternext */ \ - 0, /* tp_methods */ \ - 0, /* tp_members */ \ - 0, /* tp_getset */ \ - &base, /* tp_base */ \ - 0, /* tp_dict */ \ - 0, /* tp_descr_get */ \ - 0, /* tp_descr_set */ \ - 0, /* tp_dictoffset */ \ - 0, /* tp_init */ \ - 0 /* tp_alloc */ \ - }; \ -\ -int \ -gdbpy_initialize_##name##_event (void) \ -{ \ - return gdbpy_initialize_event_generic (&name##_event_object_type, \ - py_name); \ -} +/* Declare all event types. */ +#define GDB_PY_DEFINE_EVENT_TYPE(name, py_name, doc, base) \ + extern PyTypeObject name##_event_object_type \ + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); +#include "py-event-types.def" +#undef GDB_PY_DEFINE_EVENT_TYPE typedef struct { diff --git a/gdb/python/py-events.h b/gdb/python/py-events.h index 2275d89..876b564 100644 --- a/gdb/python/py-events.h +++ b/gdb/python/py-events.h @@ -24,9 +24,6 @@ #include "python-internal.h" #include "inferior.h" -extern PyTypeObject thread_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); - /* Stores a list of objects to be notified when the event for which this registry tracks occurs. */ @@ -42,21 +39,10 @@ typedef struct typedef struct { - eventregistry_object *stop; - eventregistry_object *cont; - eventregistry_object *exited; - eventregistry_object *new_objfile; - eventregistry_object *clear_objfiles; - eventregistry_object *new_inferior; - eventregistry_object *inferior_deleted; - eventregistry_object *new_thread; - eventregistry_object *inferior_call; - eventregistry_object *memory_changed; - eventregistry_object *register_changed; - eventregistry_object *breakpoint_created; - eventregistry_object *breakpoint_deleted; - eventregistry_object *breakpoint_modified; - eventregistry_object *before_prompt; +#define GDB_PY_DEFINE_EVENT(name) \ + eventregistry_object *name; +#include "py-all-events.def" +#undef GDB_PY_DEFINE_EVENT PyObject *module; diff --git a/gdb/python/py-evts.c b/gdb/python/py-evts.c index ad99241..0faf280 100644 --- a/gdb/python/py-evts.c +++ b/gdb/python/py-evts.c @@ -62,55 +62,11 @@ gdbpy_initialize_py_events (void) if (!gdb_py_events.module) return -1; - if (add_new_registry (&gdb_py_events.stop, "stop") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.cont, "cont") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.exited, "exited") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.inferior_call, - "inferior_call") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.memory_changed, - "memory_changed") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.register_changed, - "register_changed") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.new_objfile, "new_objfile") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.clear_objfiles, "clear_objfiles") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.new_inferior, "new_inferior") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.inferior_deleted, "inferior_deleted") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.new_thread, "new_thread") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.breakpoint_created, - "breakpoint_created") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.breakpoint_deleted, - "breakpoint_deleted") < 0) - return -1; - if (add_new_registry (&gdb_py_events.breakpoint_modified, - "breakpoint_modified") < 0) - return -1; - - if (add_new_registry (&gdb_py_events.before_prompt, "before_prompt") < 0) +#define GDB_PY_DEFINE_EVENT(name) \ + if (add_new_registry (&gdb_py_events.name, #name) < 0) \ return -1; +#include "py-all-events.def" +#undef GDB_PY_DEFINE_EVENT if (gdb_pymodule_addobject (gdb_module, "events", diff --git a/gdb/python/py-exitedevent.c b/gdb/python/py-exitedevent.c index 967fb1b..aa4aefb 100644 --- a/gdb/python/py-exitedevent.c +++ b/gdb/python/py-exitedevent.c @@ -20,9 +20,6 @@ #include "defs.h" #include "py-event.h" -extern PyTypeObject exited_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); - static PyObject * create_exited_event_object (const LONGEST *exit_code, struct inferior *inf) { @@ -67,10 +64,3 @@ emit_exited_event (const LONGEST *exit_code, struct inferior *inf) return -1; } - - -GDBPY_NEW_EVENT_TYPE (exited, - "gdb.ExitedEvent", - "ExitedEvent", - "GDB exited event object", - event_object_type); diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c index d7c6810..5cad042 100644 --- a/gdb/python/py-inferior.c +++ b/gdb/python/py-inferior.c @@ -30,13 +30,6 @@ #include "py-event.h" #include "py-stopevent.h" -extern PyTypeObject new_thread_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); -extern PyTypeObject new_inferior_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); -extern PyTypeObject inferior_deleted_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); - struct threadlist_entry { thread_object *thread_obj; struct threadlist_entry *next; @@ -1042,19 +1035,3 @@ PyTypeObject membuf_object_type = { 0, /* tp_init */ 0, /* tp_alloc */ }; - -GDBPY_NEW_EVENT_TYPE (new_thread, - "gdb.NewThreadEvent", - "NewThreadEvent", - "GDB new thread event object", - thread_event_object_type); -GDBPY_NEW_EVENT_TYPE (new_inferior, - "gdb.NewInferiorEvent", - "NewInferiorEvent", - "GDB new inferior event object", - event_object_type); -GDBPY_NEW_EVENT_TYPE (inferior_deleted, - "gdb.InferiorDeletedEvent", - "InferiorDeletedEvent", - "GDB inferior deleted event object", - event_object_type); diff --git a/gdb/python/py-infevents.c b/gdb/python/py-infevents.c index 8a63b79..825a892 100644 --- a/gdb/python/py-infevents.c +++ b/gdb/python/py-infevents.c @@ -21,15 +21,6 @@ #include "py-event.h" #include "py-ref.h" -extern PyTypeObject inferior_call_pre_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); -extern PyTypeObject inferior_call_post_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); -extern PyTypeObject register_changed_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); -extern PyTypeObject memory_changed_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); - /* Construct either a gdb.InferiorCallPreEvent or a gdb.InferiorCallPostEvent. */ @@ -172,28 +163,3 @@ emit_register_changed_event (struct frame_info* frame, int regnum) return evpy_emit_event (event.get (), gdb_py_events.register_changed); return -1; } - - -GDBPY_NEW_EVENT_TYPE (inferior_call_pre, - "gdb.InferiorCallPreEvent", - "InferiorCallPreEvent", - "GDB inferior function pre-call event object", - event_object_type); - -GDBPY_NEW_EVENT_TYPE (inferior_call_post, - "gdb.InferiorCallPostEvent", - "InferiorCallPostEvent", - "GDB inferior function post-call event object", - event_object_type); - -GDBPY_NEW_EVENT_TYPE (register_changed, - "gdb.RegisterChangedEvent", - "RegisterChangedEvent", - "GDB register change event object", - event_object_type); - -GDBPY_NEW_EVENT_TYPE (memory_changed, - "gdb.MemoryChangedEvent", - "MemoryChangedEvent", - "GDB memory change event object", - event_object_type); diff --git a/gdb/python/py-newobjfileevent.c b/gdb/python/py-newobjfileevent.c index dc09e0f..227f4a4 100644 --- a/gdb/python/py-newobjfileevent.c +++ b/gdb/python/py-newobjfileevent.c @@ -20,11 +20,6 @@ #include "defs.h" #include "py-event.h" -extern PyTypeObject new_objfile_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); -extern PyTypeObject clear_objfiles_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); - static PyObject * create_new_objfile_event_object (struct objfile *objfile) { @@ -62,11 +57,6 @@ emit_new_objfile_event (struct objfile *objfile) return -1; } -GDBPY_NEW_EVENT_TYPE (new_objfile, - "gdb.NewObjFileEvent", - "NewObjFileEvent", - "GDB new object file event object", - event_object_type); /* Subroutine of emit_clear_objfiles_event to simplify it. */ @@ -107,9 +97,3 @@ emit_clear_objfiles_event (void) return evpy_emit_event (event.get (), gdb_py_events.clear_objfiles); return -1; } - -GDBPY_NEW_EVENT_TYPE (clear_objfiles, - "gdb.ClearObjFilesEvent", - "ClearObjFilesEvent", - "GDB clear object files event object", - event_object_type); diff --git a/gdb/python/py-signalevent.c b/gdb/python/py-signalevent.c index c2391de..185e6f5 100644 --- a/gdb/python/py-signalevent.c +++ b/gdb/python/py-signalevent.c @@ -20,9 +20,6 @@ #include "defs.h" #include "py-stopevent.h" -extern PyTypeObject signal_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); - gdbpy_ref<> create_signal_event_object (enum gdb_signal stop_signal) { @@ -45,9 +42,3 @@ create_signal_event_object (enum gdb_signal stop_signal) return signal_event_obj; } - -GDBPY_NEW_EVENT_TYPE (signal, - "gdb.SignalEvent", - "SignalEvent", - "GDB signal event object", - stop_event_object_type); diff --git a/gdb/python/py-stopevent.c b/gdb/python/py-stopevent.c index a0be5f2..5717947 100644 --- a/gdb/python/py-stopevent.c +++ b/gdb/python/py-stopevent.c @@ -96,9 +96,3 @@ emit_stop_event (struct bpstats *bs, enum gdb_signal stop_signal) return evpy_emit_event (stop_event_obj.get (), gdb_py_events.stop); } - -GDBPY_NEW_EVENT_TYPE (stop, - "gdb.StopEvent", - "StopEvent", - "GDB stop event object", - thread_event_object_type); diff --git a/gdb/python/py-threadevent.c b/gdb/python/py-threadevent.c index 8b742ca..322fa26 100644 --- a/gdb/python/py-threadevent.c +++ b/gdb/python/py-threadevent.c @@ -68,9 +68,3 @@ create_thread_event_object (PyTypeObject *py_type, PyObject *thread) return thread_event_obj; } - -GDBPY_NEW_EVENT_TYPE (thread, - "gdb.ThreadEvent", - "ThreadEvent", - "GDB thread event object", - event_object_type); diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index 0c3582f..abfec91 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -373,8 +373,6 @@ extern PyTypeObject symbol_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("symbol_object"); extern PyTypeObject event_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); -extern PyTypeObject stop_event_object_type - CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); extern PyTypeObject breakpoint_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("breakpoint_object"); extern PyTypeObject frame_object_type @@ -606,36 +604,6 @@ int gdbpy_initialize_event (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; int gdbpy_initialize_py_events (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_stop_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_signal_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_breakpoint_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_continue_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_inferior_call_pre_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_inferior_call_post_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_register_changed_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_memory_changed_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_exited_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_thread_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_new_objfile_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_clear_objfiles_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_new_inferior_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_inferior_deleted_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_new_thread_event (void) - CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; int gdbpy_initialize_arch (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; int gdbpy_initialize_xmethods (void) diff --git a/gdb/python/python.c b/gdb/python/python.c index fbb4747..ff757fd 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -1591,26 +1591,17 @@ do_start_initialization () || gdbpy_initialize_eventregistry () < 0 || gdbpy_initialize_py_events () < 0 || gdbpy_initialize_event () < 0 - || gdbpy_initialize_stop_event () < 0 - || gdbpy_initialize_signal_event () < 0 - || gdbpy_initialize_breakpoint_event () < 0 - || gdbpy_initialize_continue_event () < 0 - || gdbpy_initialize_inferior_call_pre_event () < 0 - || gdbpy_initialize_inferior_call_post_event () < 0 - || gdbpy_initialize_register_changed_event () < 0 - || gdbpy_initialize_memory_changed_event () < 0 - || gdbpy_initialize_exited_event () < 0 - || gdbpy_initialize_thread_event () < 0 - || gdbpy_initialize_new_objfile_event () < 0 - || gdbpy_initialize_clear_objfiles_event () < 0 - || gdbpy_initialize_new_inferior_event () < 0 - || gdbpy_initialize_inferior_deleted_event () < 0 - || gdbpy_initialize_new_thread_event () < 0 || gdbpy_initialize_arch () < 0 || gdbpy_initialize_xmethods () < 0 || gdbpy_initialize_unwind () < 0) return false; +#define GDB_PY_DEFINE_EVENT_TYPE(name, py_name, doc, base) \ + if (gdbpy_initialize_event_generic (&name##_event_object_type, py_name) < 0) \ + return false; +#include "py-event-types.def" +#undef GDB_PY_DEFINE_EVENT_TYPE + gdbpy_to_string_cst = PyString_FromString ("to_string"); if (gdbpy_to_string_cst == NULL) return false; @@ -1963,4 +1954,51 @@ struct PyModuleDef python_GdbModuleDef = NULL }; #endif + +/* Define all the event objects. */ +#define GDB_PY_DEFINE_EVENT_TYPE(name, py_name, doc, base) \ + PyTypeObject name##_event_object_type \ + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object") \ + = { \ + PyVarObject_HEAD_INIT (NULL, 0) \ + "gdb." py_name, /* tp_name */ \ + sizeof (event_object), /* tp_basicsize */ \ + 0, /* tp_itemsize */ \ + evpy_dealloc, /* tp_dealloc */ \ + 0, /* tp_print */ \ + 0, /* tp_getattr */ \ + 0, /* tp_setattr */ \ + 0, /* tp_compare */ \ + 0, /* tp_repr */ \ + 0, /* tp_as_number */ \ + 0, /* tp_as_sequence */ \ + 0, /* tp_as_mapping */ \ + 0, /* tp_hash */ \ + 0, /* tp_call */ \ + 0, /* tp_str */ \ + 0, /* tp_getattro */ \ + 0, /* tp_setattro */ \ + 0, /* tp_as_buffer */ \ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ \ + doc, /* tp_doc */ \ + 0, /* tp_traverse */ \ + 0, /* tp_clear */ \ + 0, /* tp_richcompare */ \ + 0, /* tp_weaklistoffset */ \ + 0, /* tp_iter */ \ + 0, /* tp_iternext */ \ + 0, /* tp_methods */ \ + 0, /* tp_members */ \ + 0, /* tp_getset */ \ + &base, /* tp_base */ \ + 0, /* tp_dict */ \ + 0, /* tp_descr_get */ \ + 0, /* tp_descr_set */ \ + 0, /* tp_dictoffset */ \ + 0, /* tp_init */ \ + 0 /* tp_alloc */ \ + }; +#include "py-event-types.def" +#undef GDB_PY_DEFINE_EVENT_TYPE + #endif /* HAVE_PYTHON */ -- cgit v1.1 From f1735a53a63040cc4b4a735bf18a3f20d308e519 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sun, 10 Sep 2017 14:19:19 -0600 Subject: Rename _const functions to use overloading instead This renames a few functions -- skip_spaces_const, skip_to_space_const, get_number_const, extract_arg_const -- to drop the "_const" suffix and instead rely on overloading. This makes future const fixes simpler by reducing the number of lines that must be changed. I think it is also not any less clear, as all these functions have the same interface as their non-const versions by design. Furthermore there's an example of using an overload in-tree already, namely check_for_argument. This patch was largely created using some perl one-liners; then a few fixes were applied by hand. ChangeLog 2017-09-11 Tom Tromey * common/common-utils.h (skip_to_space): Remove macro, redeclare as function. (skip_to_space): Rename from skip_to_space_const. * common/common-utils.c (skip_to_space): New function. (skip_to_space): Rename from skip_to_space_const. * cli/cli-utils.h (get_number): Rename from get_number_const. (extract_arg): Rename from extract_arg_const. * cli/cli-utils.c (get_number): Rename from get_number_const. (extract_arg): Rename from extract_arg_const. (number_or_range_parser::get_number): Use ::get_number. * aarch64-linux-tdep.c, ada-lang.c, arm-linux-tdep.c, ax-gdb.c, break-catch-throw.c, breakpoint.c, cli/cli-cmds.c, cli/cli-dump.c, cli/cli-script.c, cli/cli-setshow.c, compile/compile.c, completer.c, demangle.c, disasm.c, findcmd.c, linespec.c, linux-tdep.c, linux-thread-db.c, location.c, mi/mi-parse.c, minsyms.c, nat/linux-procfs.c, printcmd.c, probe.c, python/py-breakpoint.c, record.c, rust-exp.y, serial.c, stack.c, stap-probe.c, tid-parse.c, tracepoint.c: Update all callers. --- gdb/python/py-breakpoint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gdb/python') diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index 6156eb6..d57c2fa 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -673,7 +673,7 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) TRY { gdb::unique_xmalloc_ptr - copy_holder (xstrdup (skip_spaces_const (spec))); + copy_holder (xstrdup (skip_spaces (spec))); char *copy = copy_holder.get (); switch (type) -- cgit v1.1 From c6dc63a16299e22fcb5bc13b34cb402a1bfcf6b9 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sat, 9 Sep 2017 10:14:52 -0600 Subject: Remove cleanups from find_frame_funname This changes find_frame_funname to return a unique_xmalloc_ptr and then fixes up the callers. This removes several cleanups. ChangeLog 2017-09-11 Tom Tromey * ada-lang.c (is_known_support_routine): Update. (ada_unhandled_exception_name_addr_from_raise): Update. * guile/scm-frame.c (gdbscm_frame_name): Update. * python/py-frame.c (frapy_name): Update. (frapy_function): Update. * stack.h (find_frame_funname): Update. * stack.c (find_frame_funname): Return unique_xmalloc_ptr. (print_frame): Update. --- gdb/python/py-frame.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c index c5ae391..a927b3c 100644 --- a/gdb/python/py-frame.c +++ b/gdb/python/py-frame.c @@ -119,7 +119,7 @@ static PyObject * frapy_name (PyObject *self, PyObject *args) { struct frame_info *frame; - char *name = NULL; + gdb::unique_xmalloc_ptr name; enum language lang; PyObject *result; @@ -127,19 +127,18 @@ frapy_name (PyObject *self, PyObject *args) { FRAPY_REQUIRE_VALID (self, frame); - find_frame_funname (frame, &name, &lang, NULL); + name = find_frame_funname (frame, &lang, NULL); } CATCH (except, RETURN_MASK_ALL) { - xfree (name); GDB_PY_HANDLE_EXCEPTION (except); } END_CATCH if (name) { - result = PyUnicode_Decode (name, strlen (name), host_charset (), NULL); - xfree (name); + result = PyUnicode_Decode (name.get (), strlen (name.get ()), + host_charset (), NULL); } else { @@ -334,13 +333,12 @@ frapy_function (PyObject *self, PyObject *args) TRY { - char *funname; enum language funlang; FRAPY_REQUIRE_VALID (self, frame); - find_frame_funname (frame, &funname, &funlang, &sym); - xfree (funname); + gdb::unique_xmalloc_ptr funname + = find_frame_funname (frame, &funlang, &sym); } CATCH (except, RETURN_MASK_ALL) { -- cgit v1.1 From d6541620447f43985b34e9a39488bafb38158221 Mon Sep 17 00:00:00 2001 From: Yao Qi Date: Tue, 19 Sep 2017 10:10:03 +0100 Subject: Use DISABLE_COPY_AND_ASSIGN We have many classes that copy cotr and assignment operator are deleted, so this patch replaces these existing mechanical code with macro DISABLE_COPY_AND_ASSIGN. gdb: 2017-09-19 Yao Qi * annotate.h (struct annotate_arg_emitter): Use DISABLE_COPY_AND_ASSIGN. * common/refcounted-object.h (refcounted_object): Likewise. * completer.h (struct completion_result): Likewise. * dwarf2read.c (struct dwarf2_per_objfile): Likewise. * filename-seen-cache.h (filename_seen_cache): Likewise. * gdbcore.h (thread_section_name): Likewise. * gdb_regex.h (compiled_regex): Likewise. * gdbthread.h (scoped_restore_current_thread): Likewise. * inferior.h (scoped_restore_current_inferior): Likewise. * jit.c (jit_reader): Likewise. * linespec.h (struct linespec_result): Likewise. * mi/mi-parse.h (struct mi_parse): Likewise. * nat/fork-inferior.c (execv_argv): Likewise. * progspace.h (scoped_restore_current_program_space): Likewise. * python/python-internal.h (class gdbpy_enter): Likewise. * regcache.h (regcache): Likewise. * target-descriptions.c (struct tdesc_reg): Likewise. (struct tdesc_type): Likewise. (struct tdesc_feature): Likewise. * ui-out.h (ui_out_emit_type): Likewise. --- gdb/python/python-internal.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index abfec91..a8270b2 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -624,8 +624,7 @@ class gdbpy_enter ~gdbpy_enter (); - gdbpy_enter (const gdbpy_enter &) = delete; - gdbpy_enter &operator= (const gdbpy_enter &) = delete; + DISABLE_COPY_AND_ASSIGN (gdbpy_enter); private: -- cgit v1.1 From fbbe5337a6d839309c0415765803a19f3e38f6e4 Mon Sep 17 00:00:00 2001 From: Kevin Buettner Date: Wed, 4 May 2016 16:23:08 -0700 Subject: Add `thread_from_thread_handle' method to (Python) gdb.Inferior gdb/ChangeLog: * python/py-inferior.c (gdbpy_thread_from_thread_handle): New function. (inferior_object_methods): Add gdbpy_thread_from_thread_handle. * python/python-internal.h (thread_object_type): Declare. --- gdb/python/py-inferior.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ gdb/python/python-internal.h | 2 ++ 2 files changed, 56 insertions(+) (limited to 'gdb/python') diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c index 5cad042..381586d 100644 --- a/gdb/python/py-inferior.c +++ b/gdb/python/py-inferior.c @@ -814,6 +814,56 @@ infpy_is_valid (PyObject *self, PyObject *args) Py_RETURN_TRUE; } +/* Implementation of gdb.Inferior.thread_from_thread_handle (self, handle) + -> gdb.InferiorThread. */ + +PyObject * +infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw) +{ + PyObject *handle_obj, *result; + inferior_object *inf_obj = (inferior_object *) self; + static const char *keywords[] = { "thread_handle", NULL }; + + INFPY_REQUIRE_VALID (inf_obj); + + if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj)) + return NULL; + + result = Py_None; + + if (!gdbpy_is_value_object (handle_obj)) + { + PyErr_SetString (PyExc_TypeError, + _("Argument 'handle_obj' must be a thread handle object.")); + + return NULL; + } + else + { + TRY + { + struct thread_info *thread_info; + struct value *val = value_object_to_value (handle_obj); + + thread_info = find_thread_by_handle (val, inf_obj->inferior); + if (thread_info != NULL) + { + result = (PyObject *) find_thread_object (thread_info->ptid); + if (result != NULL) + Py_INCREF (result); + } + } + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH + } + + return result; +} + + static void infpy_dealloc (PyObject *obj) { @@ -926,6 +976,10 @@ Write the given buffer object to the inferior's memory." }, METH_VARARGS | METH_KEYWORDS, "search_memory (address, length, pattern) -> long\n\ Return a long with the address of a match, or None." }, + { "thread_from_thread_handle", (PyCFunction) infpy_thread_from_thread_handle, + METH_VARARGS | METH_KEYWORDS, + "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\ +Return thread object corresponding to thread handle." }, { NULL } }; diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index a8270b2..8fc8cc5 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -377,6 +377,8 @@ extern PyTypeObject breakpoint_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("breakpoint_object"); extern PyTypeObject frame_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("frame_object"); +extern PyTypeObject thread_object_type + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("thread_object"); typedef struct gdbpy_breakpoint_object { -- cgit v1.1