X-Git-Url: https://repo.jachan.dev/binutils.git/blobdiff_plain/2bb8f231957e2beecfb689a896252b8d9fb67e23..94c8b7253a5e165ee92f7302f3247764d69b55e5:/gdb/python/python.c diff --git a/gdb/python/python.c b/gdb/python/python.c index 1f5ab4230e..1a0562a227 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -1,6 +1,6 @@ /* General python/gdb code - Copyright (C) 2008-2017 Free Software Foundation, Inc. + Copyright (C) 2008-2018 Free Software Foundation, Inc. This file is part of GDB. @@ -90,7 +90,6 @@ const struct extension_language_defn extension_language_python = #include "cli/cli-decode.h" #include "charset.h" #include "top.h" -#include "solib.h" #include "python-internal.h" #include "linespec.h" #include "source.h" @@ -100,6 +99,7 @@ const struct extension_language_defn extension_language_python = #include "interps.h" #include "event-top.h" #include "py-ref.h" +#include "py-event.h" /* True if Python has been successfully initialized, false otherwise. */ @@ -189,12 +189,7 @@ const struct extension_language_ops python_extension_ops = gdbpy_before_prompt_hook, - gdbpy_clone_xmethod_worker_data, - gdbpy_free_xmethod_worker_data, gdbpy_get_matching_xmethod_workers, - gdbpy_get_xmethod_arg_types, - gdbpy_get_xmethod_result_type, - gdbpy_invoke_xmethod }; /* Architecture and language to be used in callbacks from @@ -288,7 +283,7 @@ eval_python_command (const char *command) /* Implementation of the gdb "python-interactive" command. */ static void -python_interactive_command (char *arg, int from_tty) +python_interactive_command (const char *arg, int from_tty) { struct ui *ui = current_ui; int err; @@ -351,7 +346,7 @@ python_run_simple_file (FILE *file, const char *filename) /* Because we have a string for a filename, and are using Python to open the file, we need to expand any tilde in the path first. */ gdb::unique_xmalloc_ptr full_path (tilde_expand (filename)); - gdbpy_ref<> python_file (PyFile_FromString (full_path.get (), "r")); + gdbpy_ref<> python_file (PyFile_FromString (full_path.get (), (char *) "r")); if (python_file == NULL) { gdbpy_print_stack (); @@ -364,32 +359,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; } @@ -401,16 +383,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) + if (cmd->body_list_1 != nullptr) 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.get ()); + ret = PyRun_SimpleString (script.c_str ()); if (ret) error (_("Error while executing Python code.")); } @@ -418,7 +398,7 @@ gdbpy_eval_from_control_command (const struct extension_language_defn *extlang, /* Implementation of the gdb "python" command. */ static void -python_command (char *arg, int from_tty) +python_command (const char *arg, int from_tty) { gdbpy_enter enter_py (get_current_arch (), current_language); @@ -432,11 +412,9 @@ python_command (char *arg, int from_tty) } else { - struct command_line *l = get_command_line (python_control, ""); - struct cleanup *cleanup = make_cleanup_free_command_lines (&l); + counted_command_line l = get_command_line (python_control, ""); - execute_control_command_untraced (l); - do_cleanups (cleanup); + execute_control_command_untraced (l.get ()); } } @@ -456,7 +434,7 @@ gdbpy_parameter_value (enum var_types type, void *var) case var_filename: case var_enum: { - char *str = * (char **) var; + const char *str = *(char **) var; if (! str) str = ""; @@ -488,6 +466,7 @@ gdbpy_parameter_value (enum var_types type, void *var) Py_RETURN_NONE; /* Fall through. */ case var_zinteger: + case var_zuinteger_unlimited: return PyLong_FromLong (* (int *) var); case var_uinteger: @@ -498,6 +477,12 @@ gdbpy_parameter_value (enum var_types type, void *var) Py_RETURN_NONE; return PyLong_FromUnsignedLong (val); } + + case var_zuinteger: + { + unsigned int val = * (unsigned int *) var; + return PyLong_FromUnsignedLong (val); + } } return PyErr_Format (PyExc_RuntimeError, @@ -571,11 +556,11 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) const char *arg; PyObject *from_tty_obj = NULL, *to_string_obj = NULL; int from_tty, to_string; - static char *keywords[] = {"command", "from_tty", "to_string", NULL }; + static const char *keywords[] = { "command", "from_tty", "to_string", NULL }; - if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O!O!", keywords, &arg, - &PyBool_Type, &from_tty_obj, - &PyBool_Type, &to_string_obj)) + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!O!", keywords, &arg, + &PyBool_Type, &from_tty_obj, + &PyBool_Type, &to_string_obj)) return NULL; from_tty = 0; @@ -600,24 +585,43 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) TRY { - /* Copy the argument text in case the command modifies it. */ - std::string copy (arg); struct interp *interp; - scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0); + std::string arg_copy = arg; + bool first = true; + char *save_ptr = nullptr; + auto reader + = [&] () + { + const char *result = strtok_r (first ? &arg_copy[0] : nullptr, + "\n", &save_ptr); + first = false; + return result; + }; - scoped_restore save_uiout = make_scoped_restore (¤t_uiout); + counted_command_line lines = read_command_lines_1 (reader, 1, nullptr); - /* Use the console interpreter uiout to have the same print format - for console or MI. */ - interp = interp_lookup (current_ui, "console"); - current_uiout = interp_ui_out (interp); + { + scoped_restore save_async = make_scoped_restore (¤t_ui->async, + 0); - scoped_restore preventer = prevent_dont_repeat (); - if (to_string) - to_string_res = execute_command_to_string (©[0], from_tty); - else - execute_command (©[0], from_tty); + scoped_restore save_uiout = make_scoped_restore (¤t_uiout); + + /* Use the console interpreter uiout to have the same print format + for console or MI. */ + interp = interp_lookup (current_ui, "console"); + current_uiout = interp->interp_ui_out (); + + scoped_restore preventer = prevent_dont_repeat (); + if (to_string) + to_string_res = execute_control_commands_to_string (lines.get (), + from_tty); + else + execute_control_commands (lines.get (), from_tty); + } + + /* Do any commands attached to breakpoint we stopped at. */ + bpstat_do_actions (); } CATCH (except, RETURN_MASK_ALL) { @@ -625,37 +629,193 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) } END_CATCH - /* Do any commands attached to breakpoint we stopped at. */ - bpstat_do_actions (); - if (to_string) return PyString_FromString (to_string_res.c_str ()); Py_RETURN_NONE; } -/* Implementation of gdb.solib_name (Long) -> String. - Returns the name of the shared library holding a given address, or None. */ +/* Implementation of Python rbreak command. Take a REGEX and + optionally a MINSYMS, THROTTLE and SYMTABS keyword and return a + Python list that contains newly set breakpoints that match that + criteria. REGEX refers to a GDB format standard regex pattern of + symbols names to search; MINSYMS is an optional boolean (default + False) that indicates if the function should search GDB's minimal + symbols; THROTTLE is an optional integer (default unlimited) that + indicates the maximum amount of breakpoints allowable before the + function exits (note, if the throttle bound is passed, no + breakpoints will be set and a runtime error returned); SYMTABS is + an optional Python iterable that contains a set of gdb.Symtabs to + constrain the search within. */ static PyObject * -gdbpy_solib_name (PyObject *self, PyObject *args) +gdbpy_rbreak (PyObject *self, PyObject *args, PyObject *kw) { - char *soname; - PyObject *str_obj; - gdb_py_ulongest pc; + /* A simple type to ensure clean up of a vector of allocated strings + when a C interface demands a const char *array[] type + interface. */ + struct symtab_list_type + { + ~symtab_list_type () + { + for (const char *elem: vec) + xfree ((void *) elem); + } + std::vector vec; + }; - if (!PyArg_ParseTuple (args, GDB_PY_LLU_ARG, &pc)) + char *regex = NULL; + std::vector symbols; + unsigned long count = 0; + PyObject *symtab_list = NULL; + PyObject *minsyms_p_obj = NULL; + int minsyms_p = 0; + unsigned int throttle = 0; + static const char *keywords[] = {"regex","minsyms", "throttle", + "symtabs", NULL}; + symtab_list_type symtab_paths; + + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!IO", keywords, + ®ex, &PyBool_Type, + &minsyms_p_obj, &throttle, + &symtab_list)) return NULL; - soname = solib_name_from_address (current_program_space, pc); - if (soname) - str_obj = host_string_to_python_string (soname); + /* Parse minsyms keyword. */ + if (minsyms_p_obj != NULL) + { + int cmp = PyObject_IsTrue (minsyms_p_obj); + if (cmp < 0) + return NULL; + minsyms_p = cmp; + } + + /* The "symtabs" keyword is any Python iterable object that returns + a gdb.Symtab on each iteration. If specified, iterate through + the provided gdb.Symtabs and extract their full path. As + python_string_to_target_string returns a + gdb::unique_xmalloc_ptr and a vector containing these types + cannot be coerced to a const char **p[] via the vector.data call, + release the value from the unique_xmalloc_ptr and place it in a + simple type symtab_list_type (which holds the vector and a + destructor that frees the contents of the allocated strings. */ + if (symtab_list != NULL) + { + gdbpy_ref<> iter (PyObject_GetIter (symtab_list)); + + if (iter == NULL) + return NULL; + + while (true) + { + gdbpy_ref<> next (PyIter_Next (iter.get ())); + + if (next == NULL) + { + if (PyErr_Occurred ()) + return NULL; + break; + } + + gdbpy_ref<> obj_name (PyObject_GetAttrString (next.get (), + "filename")); + + if (obj_name == NULL) + return NULL; + + /* Is the object file still valid? */ + if (obj_name == Py_None) + continue; + + gdb::unique_xmalloc_ptr filename = + python_string_to_target_string (obj_name.get ()); + + if (filename == NULL) + return NULL; + + /* Make sure there is a definite place to store the value of + filename before it is released. */ + symtab_paths.vec.push_back (nullptr); + symtab_paths.vec.back () = filename.release (); + } + } + + if (symtab_list) + { + const char **files = symtab_paths.vec.data (); + + symbols = search_symbols (regex, FUNCTIONS_DOMAIN, + symtab_paths.vec.size (), files); + } else + symbols = search_symbols (regex, FUNCTIONS_DOMAIN, 0, NULL); + + /* Count the number of symbols (both symbols and optionally minimal + symbols) so we can correctly check the throttle limit. */ + for (const symbol_search &p : symbols) + { + /* Minimal symbols included? */ + if (minsyms_p) + { + if (p.msymbol.minsym != NULL) + count++; + } + + if (p.symbol != NULL) + count++; + } + + /* Check throttle bounds and exit if in excess. */ + if (throttle != 0 && count > throttle) { - str_obj = Py_None; - Py_INCREF (Py_None); + PyErr_SetString (PyExc_RuntimeError, + _("Number of breakpoints exceeds throttled maximum.")); + return NULL; } - return str_obj; + gdbpy_ref<> return_list (PyList_New (0)); + + if (return_list == NULL) + return NULL; + + /* Construct full path names for symbols and call the Python + breakpoint constructor on the resulting names. Be tolerant of + individual breakpoint failures. */ + for (const symbol_search &p : symbols) + { + std::string symbol_name; + + /* Skipping minimal symbols? */ + if (minsyms_p == 0) + if (p.msymbol.minsym != NULL) + continue; + + if (p.msymbol.minsym == NULL) + { + struct symtab *symtab = symbol_symtab (p.symbol); + const char *fullname = symtab_to_fullname (symtab); + + symbol_name = fullname; + symbol_name += ":"; + symbol_name += SYMBOL_LINKAGE_NAME (p.symbol); + } + else + symbol_name = MSYMBOL_LINKAGE_NAME (p.msymbol.minsym); + + gdbpy_ref<> argList (Py_BuildValue("(s)", symbol_name.c_str ())); + gdbpy_ref<> obj (PyObject_CallObject ((PyObject *) + &breakpoint_object_type, + argList.get ())); + + /* Tolerate individual breakpoint failures. */ + if (obj == NULL) + gdbpy_print_stack (); + else + { + if (PyList_Append (return_list.get (), obj.get ()) == -1) + return NULL; + } + } + return return_list.release (); } /* A Python function which is a wrapper for decode_line_1. */ @@ -663,115 +823,76 @@ 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; - struct cleanup *cleanups; + const char *arg = NULL; gdbpy_ref<> result; gdbpy_ref<> unparsed; - struct event_location *location = NULL; + event_location_up location; if (! PyArg_ParseTuple (args, "|s", &arg)) return NULL; - cleanups = make_cleanup (null_cleanup, NULL); - - sals.sals = NULL; - if (arg != NULL) - { - location = string_to_event_location_basic (&arg, python_language); - make_cleanup_delete_event_location (location); - } + location = string_to_event_location_basic (&arg, python_language, + symbol_name_match_type::WILD); + std::vector decoded_sals; + symtab_and_line def_sal; + gdb::array_view sals; TRY { if (location != NULL) - sals = decode_line_1 (location, 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 - - if (sals.sals != NULL && sals.sals != &sal) - make_cleanup (xfree, sals.sals); - - if (except.reason < 0) - { - do_cleanups (cleanups); /* 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 (size_t i = 0; i < sals.size (); ++i) { - do_cleanups (cleanups); - 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; - } + PyObject *obj = symtab_and_line_to_sal_object (sals[i]); + if (obj == NULL) + return NULL; PyTuple_SetItem (result.get (), i, obj); } } else - { - result.reset (Py_None); - Py_INCREF (Py_None); - } + result = gdbpy_ref<>::new_reference (Py_None); 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 - { - unparsed.reset (Py_None); - Py_INCREF (Py_None); - } + unparsed = gdbpy_ref<>::new_reference (Py_None); PyTuple_SetItem (return_result.get (), 0, unparsed.release ()); PyTuple_SetItem (return_result.get (), 1, result.release ()); - do_cleanups (cleanups); - return return_result.release (); } @@ -798,36 +919,6 @@ gdbpy_parse_and_eval (PyObject *self, PyObject *args) return value_to_value_object (result); } -/* Implementation of gdb.find_pc_line function. - Returns the gdb.Symtab_and_line object corresponding to a PC value. */ - -static PyObject * -gdbpy_find_pc_line (PyObject *self, PyObject *args) -{ - gdb_py_ulongest pc_llu; - PyObject *result = NULL; /* init for gcc -Wall */ - - if (!PyArg_ParseTuple (args, GDB_PY_LLU_ARG, &pc_llu)) - return NULL; - - TRY - { - struct symtab_and_line sal; - CORE_ADDR pc; - - pc = (CORE_ADDR) pc_llu; - sal = find_pc_line (pc, 0); - result = symtab_and_line_to_sal_object (sal); - } - CATCH (except, RETURN_MASK_ALL) - { - GDB_PY_HANDLE_EXCEPTION (except); - } - END_CATCH - - return result; -} - /* Implementation of gdb.invalidate_cached_frames. */ static PyObject * @@ -969,6 +1060,10 @@ gdbpy_before_prompt_hook (const struct extension_language_defn *extlang, gdbpy_enter enter_py (get_current_arch (), current_language); + if (!evregpy_no_listeners_p (gdb_py_events.before_prompt) + && evpy_emit_event (NULL, gdb_py_events.before_prompt) < 0) + return EXT_LANG_RC_ERROR; + if (gdb_python_module && PyObject_HasAttrString (gdb_python_module, "prompt_hook")) { @@ -1042,11 +1137,11 @@ static PyObject * gdbpy_write (PyObject *self, PyObject *args, PyObject *kw) { const char *arg; - static char *keywords[] = {"text", "stream", NULL }; + static const char *keywords[] = { "text", "stream", NULL }; int stream_type = 0; - if (! PyArg_ParseTupleAndKeywords (args, kw, "s|i", keywords, &arg, - &stream_type)) + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|i", keywords, &arg, + &stream_type)) return NULL; TRY @@ -1083,11 +1178,11 @@ gdbpy_write (PyObject *self, PyObject *args, PyObject *kw) static PyObject * gdbpy_flush (PyObject *self, PyObject *args, PyObject *kw) { - static char *keywords[] = {"stream", NULL }; + static const char *keywords[] = { "stream", NULL }; int stream_type = 0; - if (! PyArg_ParseTupleAndKeywords (args, kw, "|i", keywords, - &stream_type)) + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "|i", keywords, + &stream_type)) return NULL; switch (stream_type) @@ -1185,20 +1280,6 @@ gdbpy_print_stack (void) -/* Return the current Progspace. - There always is one. */ - -static PyObject * -gdbpy_get_current_progspace (PyObject *unused1, PyObject *unused2) -{ - PyObject *result; - - result = pspace_to_pspace_object (current_program_space); - if (result) - Py_INCREF (result); - return result; -} - /* Return a sequence holding all the Progspaces. */ static PyObject * @@ -1212,9 +1293,9 @@ gdbpy_progspaces (PyObject *unused1, PyObject *unused2) ALL_PSPACES (ps) { - PyObject *item = pspace_to_pspace_object (ps); + gdbpy_ref<> item = pspace_to_pspace_object (ps); - if (!item || PyList_Append (list.get (), item) == -1) + if (item == NULL || PyList_Append (list.get (), item.get ()) == -1) return NULL; } @@ -1278,37 +1359,10 @@ gdbpy_execute_objfile_script (const struct extension_language_defn *extlang, static PyObject * gdbpy_get_current_objfile (PyObject *unused1, PyObject *unused2) { - PyObject *result; - if (! gdbpy_current_objfile) Py_RETURN_NONE; - result = objfile_to_objfile_object (gdbpy_current_objfile); - if (result) - Py_INCREF (result); - return result; -} - -/* Return a sequence holding all the Objfiles. */ - -static PyObject * -gdbpy_objfiles (PyObject *unused1, PyObject *unused2) -{ - struct objfile *objf; - - gdbpy_ref<> list (PyList_New (0)); - if (list == NULL) - return NULL; - - ALL_OBJFILES (objf) - { - PyObject *item = objfile_to_objfile_object (objf); - - if (!item || PyList_Append (list.get (), item) == -1) - return NULL; - } - - return list.release (); + return objfile_to_objfile_object (gdbpy_current_objfile).release (); } /* Compute the list of active python type printers and store them in @@ -1443,23 +1497,21 @@ gdbpy_free_type_printers (const struct extension_language_defn *extlang, command. */ static void -python_interactive_command (char *arg, int from_tty) +python_interactive_command (const char *arg, int from_tty) { arg = skip_spaces (arg); if (arg && *arg) error (_("Python scripting is not supported in this copy of GDB.")); else { - struct command_line *l = get_command_line (python_control, ""); - struct cleanup *cleanups = make_cleanup_free_command_lines (&l); + counted_command_line l = get_command_line (python_control, ""); - execute_control_command_untraced (l); - do_cleanups (cleanups); + execute_control_command_untraced (l.get ()); } } static void -python_command (char *arg, int from_tty) +python_command (const char *arg, int from_tty) { python_interactive_command (arg, from_tty); } @@ -1476,7 +1528,7 @@ static struct cmd_list_element *user_show_python_list; /* Function for use by 'set python' prefix command. */ static void -user_set_python (char *args, int from_tty) +user_set_python (const char *args, int from_tty) { help_list (user_set_python_list, "set python ", all_commands, gdb_stdout); @@ -1485,7 +1537,7 @@ user_set_python (char *args, int from_tty) /* Function for use by 'show python' prefix command. */ static void -user_show_python (char *args, int from_tty) +user_show_python (const char *args, int from_tty) { cmd_show_list (user_show_python_list, from_tty, ""); } @@ -1520,21 +1572,23 @@ 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 +#ifdef IS_PY3K +/* This is called via the PyImport_AppendInittab mechanism called + during initialization, to make the built-in _gdb module known to + Python. */ +PyMODINIT_FUNC +init__gdb_module (void) +{ + return PyModule_Create (&python_GdbModuleDef); +} +#endif static bool do_start_initialization () { - char *progname; #ifdef IS_PY3K - int i; size_t progsize, count; - char *oldloc; wchar_t *progname_copy; #endif @@ -1545,35 +1599,36 @@ do_start_initialization () /foo/bin/python /foo/lib/pythonX.Y/... This must be done before calling Py_Initialize. */ - progname = concat (ldirname (python_libdir), SLASH_STRING, "bin", - SLASH_STRING, "python", (char *) NULL); + gdb::unique_xmalloc_ptr 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); + progsize = strlen (progname.get ()); 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); + count = mbstowcs (progname_copy, progname.get (), 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 it is not freed after this call. */ Py_SetProgramName (progname_copy); + + /* Define _gdb as a built-in module. */ + PyImport_AppendInittab ("_gdb", init__gdb_module); #else - Py_SetProgramName (progname); + Py_SetProgramName (progname.release ()); #endif #endif @@ -1581,9 +1636,7 @@ do_start_initialization () PyEval_InitThreads (); #ifdef IS_PY3K - gdb_module = PyModule_Create (&python_GdbModuleDef); - /* Add _gdb module to the list of known built-in modules. */ - _PyImport_FixupBuiltin (gdb_module, "_gdb"); + gdb_module = PyImport_ImportModule ("_gdb"); #else gdb_module = Py_InitModule ("_gdb", python_GdbMethods); #endif @@ -1628,6 +1681,9 @@ do_start_initialization () || gdbpy_initialize_values () < 0 || gdbpy_initialize_frames () < 0 || gdbpy_initialize_commands () < 0 + || gdbpy_initialize_instruction () < 0 + || gdbpy_initialize_record () < 0 + || gdbpy_initialize_btrace () < 0 || gdbpy_initialize_symbols () < 0 || gdbpy_initialize_symtabs () < 0 || gdbpy_initialize_blocks () < 0 @@ -1646,23 +1702,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_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; @@ -1731,7 +1781,7 @@ Evaluate a Python command.\n\ \n\ The command can be given as an argument, for instance:\n\ \n\ - python print 23\n\ + python print (23)\n\ \n\ If no argument is given, the following lines are read and used\n\ as the Python commands. Type a line containing \"end\" to indicate\n\ @@ -1890,15 +1940,11 @@ set to True." }, { "default_visualizer", gdbpy_default_visualizer, METH_VARARGS, "Find the default visualizer for a Value." }, - { "current_progspace", gdbpy_get_current_progspace, METH_NOARGS, - "Return the current Progspace." }, { "progspaces", gdbpy_progspaces, METH_NOARGS, "Return a sequence of all progspaces." }, { "current_objfile", gdbpy_get_current_objfile, METH_NOARGS, "Return the current Objfile being loaded, or None." }, - { "objfiles", gdbpy_objfiles, METH_NOARGS, - "Return a sequence of all loaded objfiles." }, { "newest_frame", gdbpy_newest_frame, METH_NOARGS, "newest_frame () -> gdb.Frame.\n\ @@ -1910,6 +1956,18 @@ Return the selected frame object." }, "stop_reason_string (Integer) -> String.\n\ Return a string explaining unwind stop reason." }, + { "start_recording", gdbpy_start_recording, METH_VARARGS, + "start_recording ([method] [, format]) -> gdb.Record.\n\ +Start recording with the given method. If no method is given, will fall back\n\ +to the system default method. If no format is given, will fall back to the\n\ +default format for the given method."}, + { "current_recording", gdbpy_current_recording, METH_NOARGS, + "current_recording () -> gdb.Record.\n\ +Return current recording object." }, + { "stop_recording", gdbpy_stop_recording, METH_NOARGS, + "stop_recording () -> None.\n\ +Stop current recording." }, + { "lookup_type", (PyCFunction) gdbpy_lookup_type, METH_VARARGS | METH_KEYWORDS, "lookup_type (name [, block]) -> type\n\ @@ -1932,11 +1990,6 @@ Look up the specified objfile.\n\ If by_build_id is True, the objfile is looked up by using name\n\ as its build id." }, - { "block_for_pc", gdbpy_block_for_pc, METH_VARARGS, - "Return the block containing the given pc value, or None." }, - { "solib_name", gdbpy_solib_name, METH_VARARGS, - "solib_name (Long) -> String.\n\ -Return the name of the shared library holding a given address, or None." }, { "decode_line", gdbpy_decode_line, METH_VARARGS, "decode_line (String) -> Tuple. Decode a string argument the way\n\ that 'break' or 'edit' does. Return a tuple containing two elements.\n\ @@ -1948,9 +2001,6 @@ gdb.Symtab_and_line objects (or None)."}, "parse_and_eval (String) -> Value.\n\ Parse String as an expression, evaluate it, and return the result as a Value." }, - { "find_pc_line", gdbpy_find_pc_line, METH_VARARGS, - "find_pc_line (pc) -> Symtab_and_line.\n\ -Return the gdb.Symtab_and_line object corresponding to the pc value." }, { "post_event", gdbpy_post_event, METH_VARARGS, "Post an event into gdb's event loop." }, @@ -1961,7 +2011,9 @@ Return the name of the current target charset." }, { "target_wide_charset", gdbpy_target_wide_charset, METH_NOARGS, "target_wide_charset () -> string.\n\ Return the name of the current target wide charset." }, - + { "rbreak", (PyCFunction) gdbpy_rbreak, METH_VARARGS | METH_KEYWORDS, + "rbreak (Regex) -> List.\n\ +Return a Tuple containing gdb.Breakpoint objects that match the given Regex." }, { "string_to_argv", gdbpy_string_to_argv, METH_VARARGS, "string_to_argv (String) -> Array.\n\ Parse String and return an argv-like array.\n\ @@ -1986,6 +2038,14 @@ Return a tuple containing all inferiors." }, Invalidate any cached frame objects in gdb.\n\ Intended for internal use only." }, + { "convenience_variable", gdbpy_convenience_variable, METH_VARARGS, + "convenience_variable (NAME) -> value.\n\ +Return the value of the convenience variable $NAME,\n\ +or None if not set." }, + { "set_convenience_variable", gdbpy_set_convenience_variable, METH_VARARGS, + "convenience_variable (NAME, VALUE) -> None.\n\ +Set the value of the convenience variable $NAME." }, + {NULL, NULL, 0, NULL} }; @@ -2003,4 +2063,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 */