/* General python/gdb code
- Copyright (C) 2008-2017 Free Software Foundation, Inc.
+ Copyright (C) 2008-2019 Free Software Foundation, Inc.
This file is part of GDB.
#include "cli/cli-decode.h"
#include "charset.h"
#include "top.h"
-#include "solib.h"
#include "python-internal.h"
#include "linespec.h"
#include "source.h"
-#include "version.h"
+#include "common/version.h"
#include "target.h"
#include "gdbthread.h"
#include "interps.h"
#include "event-top.h"
-#include "py-ref.h"
#include "py-event.h"
/* True if Python has been successfully initialized, false
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
python_language = language;
/* Save it and ensure ! PyErr_Occurred () afterwards. */
- PyErr_Fetch (&m_error_type, &m_error_value, &m_error_traceback);
+ m_error.emplace ();
}
gdbpy_enter::~gdbpy_enter ()
warning (_("internal error: Unhandled Python exception"));
}
- PyErr_Restore (m_error_type, m_error_value, m_error_traceback);
+ m_error->restore ();
PyGILState_Release (m_state);
python_gdbarch = m_gdbarch;
/* 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;
if (arg && *arg)
{
- int len = strlen (arg);
- char *script = (char *) xmalloc (len + 2);
-
- strcpy (script, arg);
- script[len] = '\n';
- script[len + 1] = '\0';
- err = eval_python_command (script);
- xfree (script);
+ std::string script = std::string (arg) + "\n";
+ err = eval_python_command (script.c_str ());
}
else
{
/* 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<char> 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 ();
}
/* 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;
}
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."));
}
/* 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);
}
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 ());
}
}
case var_filename:
case var_enum:
{
- char *str = * (char **) var;
+ const char *str = *(char **) var;
if (! str)
str = "";
- return host_string_to_python_string (str);
+ return host_string_to_python_string (str).release ();
}
case var_boolean:
Py_RETURN_NONE;
/* Fall through. */
case var_zinteger:
+ case var_zuinteger_unlimited:
return PyLong_FromLong (* (int *) var);
case var_uinteger:
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,
static PyObject *
gdbpy_parameter (PyObject *self, PyObject *args)
{
- struct gdb_exception except = exception_none;
struct cmd_list_element *alias, *prefix, *cmd;
const char *arg;
- char *newarg;
int found = -1;
if (! PyArg_ParseTuple (args, "s", &arg))
return NULL;
- newarg = concat ("show ", arg, (char *) NULL);
+ std::string newarg = std::string ("show ") + arg;
TRY
{
- found = lookup_cmd_composition (newarg, &alias, &prefix, &cmd);
+ found = lookup_cmd_composition (newarg.c_str (), &alias, &prefix, &cmd);
}
CATCH (ex, RETURN_MASK_ALL)
{
- except = ex;
+ GDB_PY_HANDLE_EXCEPTION (ex);
}
END_CATCH
- xfree (newarg);
- GDB_PY_HANDLE_EXCEPTION (except);
if (!found)
return PyErr_Format (PyExc_RuntimeError,
_("Could not find parameter `%s'."), arg);
std::string to_string_res;
+ scoped_restore preventer = prevent_dont_repeat ();
+
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 ();
+
+ 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)
{
}
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<const char *> vec;
+ };
- if (!PyArg_ParseTuple (args, GDB_PY_LLU_ARG, &pc))
+ char *regex = NULL;
+ std::vector<symbol_search> 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<char> 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<char> 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, NULL,
+ symtab_paths.vec.size (), files);
+ }
else
+ symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL, 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)
{
- str_obj = Py_None;
- Py_INCREF (Py_None);
+ /* Minimal symbols included? */
+ if (minsyms_p)
+ {
+ if (p.msymbol.minsym != NULL)
+ count++;
+ }
+
+ if (p.symbol != NULL)
+ count++;
}
- return str_obj;
+ /* Check throttle bounds and exit if in excess. */
+ if (throttle != 0 && count > throttle)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("Number of breakpoints exceeds throttled maximum."));
+ return NULL;
+ }
+
+ 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. */
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<symtab_and_line> decoded_sals;
+ symtab_and_line def_sal;
+ gdb::array_view<symtab_and_line> 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 ();
}
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 *
if (gdbpy_event_list == NULL)
gdbpy_event_list_end = &gdbpy_event_list;
- /* Ignore errors. */
gdbpy_ref<> call_result (PyObject_CallObject (item->event, NULL));
if (call_result == NULL)
- PyErr_Clear ();
+ gdbpy_print_stack ();
Py_DECREF (item->event);
xfree (item);
/* Print "message", just error print message. */
else
{
- PyObject *ptype, *pvalue, *ptraceback;
-
- PyErr_Fetch (&ptype, &pvalue, &ptraceback);
+ gdbpy_err_fetch fetched_error;
- /* Fetch the error message contained within ptype, pvalue. */
- gdb::unique_xmalloc_ptr<char>
- msg (gdbpy_exception_to_string (ptype, pvalue));
- gdb::unique_xmalloc_ptr<char> type (gdbpy_obj_to_string (ptype));
+ gdb::unique_xmalloc_ptr<char> msg = fetched_error.to_string ();
+ gdb::unique_xmalloc_ptr<char> type;
+ /* Don't compute TYPE if MSG already indicates that there is an
+ error. */
+ if (msg != NULL)
+ type = fetched_error.type_to_string ();
TRY
{
- if (msg == NULL)
+ if (msg == NULL || type == NULL)
{
/* An error occurred computing the string representation of the
error message. */
fprintf_filtered (gdb_stderr,
_("Error occurred computing Python error" \
"message.\n"));
+ PyErr_Clear ();
}
else
fprintf_filtered (gdb_stderr, "Python Exception %s %s: \n",
{
}
END_CATCH
-
- Py_XDECREF (ptype);
- Py_XDECREF (pvalue);
- Py_XDECREF (ptraceback);
}
}
-\f
-
-/* Return the current Progspace.
- There always is one. */
+/* Like gdbpy_print_stack, but if the exception is a
+ KeyboardException, throw a gdb "quit" instead. */
-static PyObject *
-gdbpy_get_current_progspace (PyObject *unused1, PyObject *unused2)
+void
+gdbpy_print_stack_or_quit ()
{
- PyObject *result;
-
- result = pspace_to_pspace_object (current_program_space);
- if (result)
- Py_INCREF (result);
- return result;
+ if (PyErr_ExceptionMatches (PyExc_KeyboardInterrupt))
+ {
+ PyErr_Clear ();
+ throw_quit ("Quit");
+ }
+ gdbpy_print_stack ();
}
+\f
+
/* Return a sequence holding all the Progspaces. */
static PyObject *
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;
}
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
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);
}
/* 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);
/* 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, "");
}
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
/foo/bin/python
/foo/lib/pythonX.Y/...
This must be done before calling Py_Initialize. */
- progname = concat (ldirname (python_libdir).c_str (), SLASH_STRING, "bin",
- SLASH_STRING, "python", (char *) NULL);
+ gdb::unique_xmalloc_ptr<char> 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
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
|| 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_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;
#endif /* HAVE_PYTHON */
+/* See python.h. */
+cmd_list_element *python_cmd_element = nullptr;
+
void
_initialize_python (void)
{
);
add_com_alias ("pi", "python-interactive", class_obscure, 1);
- add_com ("python", class_obscure, python_command,
+ python_cmd_element = add_com ("python", class_obscure, python_command,
#ifdef HAVE_PYTHON
_("\
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\
{ "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\
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\
"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." },
{ "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\
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}
};
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 */