/* General python/gdb code
- Copyright (C) 2008-2018 Free Software Foundation, Inc.
+ Copyright (C) 2008-2019 Free Software Foundation, Inc.
This file is part of GDB.
#include "python-internal.h"
#include "linespec.h"
#include "source.h"
-#include "version.h"
+#include "gdbsupport/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
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;
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
{
A FILE * from one runtime does not necessarily operate correctly in
the other runtime.
- To work around this potential issue, we create on Windows hosts the
- FILE object using Python routines, thus making sure that it is
- compatible with the Python library. */
+ To work around this potential issue, we run code in Python to load
+ the script. */
static void
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<char> full_path (tilde_expand (filename));
- gdbpy_ref<> python_file (PyFile_FromString (full_path.get (), (char *) "r"));
- if (python_file == NULL)
+
+ if (gdb_python_module == nullptr
+ || ! PyObject_HasAttrString (gdb_python_module, "_execute_file"))
+ error (_("Installation error: gdb._execute_file function is missing"));
+
+ gdbpy_ref<> return_value
+ (PyObject_CallMethod (gdb_python_module, "_execute_file", "s",
+ full_path.get ()));
+ if (return_value == nullptr)
{
- gdbpy_print_stack ();
- error (_("Error while opening file: %s"), full_path.get ());
+ /* Use PyErr_PrintEx instead of gdbpy_print_stack to better match the
+ behavior of the non-Windows codepath. */
+ PyErr_PrintEx(0);
}
- PyRun_SimpleFile (PyFile_AsFile (python_file.get ()), filename);
-
#endif /* _WIN32 */
}
if (! str)
str = "";
- return host_string_to_python_string (str);
+ return host_string_to_python_string (str).release ();
}
case var_boolean:
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
+ try
{
- found = lookup_cmd_composition (newarg, &alias, &prefix, &cmd);
+ found = lookup_cmd_composition (newarg.c_str (), &alias, &prefix, &cmd);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
- 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;
- TRY
+ scoped_restore preventer = prevent_dont_repeat ();
+
+ try
{
+ gdbpy_allow_threads allow_threads;
+
struct interp *interp;
std::string arg_copy = arg;
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);
/* Do any commands attached to breakpoint we stopped at. */
bpstat_do_actions ();
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
GDB_PY_HANDLE_EXCEPTION (except);
}
- END_CATCH
if (to_string)
return PyString_FromString (to_string_res.c_str ());
{
const char **files = symtab_paths.vec.data ();
- symbols = search_symbols (regex, FUNCTIONS_DOMAIN,
- symtab_paths.vec.size (), files);
+ symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL,
+ symtab_paths.vec.size (), files, false);
}
else
- symbols = search_symbols (regex, FUNCTIONS_DOMAIN, 0, NULL);
+ symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL, 0, NULL, false);
/* Count the number of symbols (both symbols and optionally minimal
symbols) so we can correctly check the throttle limit. */
std::vector<symtab_and_line> decoded_sals;
symtab_and_line def_sal;
gdb::array_view<symtab_and_line> sals;
- TRY
+ try
{
if (location != NULL)
{
sals = def_sal;
}
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
/* We know this will always throw. */
gdbpy_convert_exception (ex);
return NULL;
}
- END_CATCH
if (!sals.empty ())
{
if (!PyArg_ParseTuple (args, "s", &expr_str))
return NULL;
- TRY
+ try
{
+ gdbpy_allow_threads allow_threads;
result = parse_and_eval (expr_str);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
GDB_PY_HANDLE_EXCEPTION (except);
}
- END_CATCH
return value_to_value_object (result);
}
&stream_type))
return NULL;
- TRY
+ try
{
switch (stream_type)
{
fprintf_filtered (gdb_stdout, "%s", arg);
}
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
GDB_PY_HANDLE_EXCEPTION (except);
}
- END_CATCH
Py_RETURN_NONE;
}
/* PyErr_Print doesn't necessarily end output with a newline.
This works because Python's stdout/stderr is fed through
printf_filtered. */
- TRY
+ try
{
begin_line ();
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
}
- END_CATCH
}
/* Print "message", just error print message. */
else
{
- PyObject *ptype, *pvalue, *ptraceback;
+ gdbpy_err_fetch fetched_error;
- PyErr_Fetch (&ptype, &pvalue, &ptraceback);
+ 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 ();
- /* 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));
-
- TRY
+ 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",
type.get (), msg.get ());
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
}
- END_CATCH
+ }
+}
+
+/* Like gdbpy_print_stack, but if the exception is a
+ KeyboardException, throw a gdb "quit" instead. */
- Py_XDECREF (ptype);
- Py_XDECREF (pvalue);
- Py_XDECREF (ptraceback);
+void
+gdbpy_print_stack_or_quit ()
+{
+ if (PyErr_ExceptionMatches (PyExc_KeyboardInterrupt))
+ {
+ PyErr_Clear ();
+ throw_quit ("Quit");
}
+ gdbpy_print_stack ();
}
\f
std::string oldloc = setlocale (LC_ALL, NULL);
setlocale (LC_ALL, "");
progsize = strlen (progname.get ());
- progname_copy = (wchar_t *) PyMem_Malloc ((progsize + 1) * sizeof (wchar_t));
+ progname_copy = (wchar_t *) xmalloc ((progsize + 1) * sizeof (wchar_t));
if (!progname_copy)
{
fprintf (stderr, "out of memory\n");
if (gdb_module == NULL)
return false;
- /* The casts to (char*) are for python 2.4. */
- if (PyModule_AddStringConstant (gdb_module, "VERSION", (char*) version) < 0
- || PyModule_AddStringConstant (gdb_module, "HOST_CONFIG",
- (char*) host_name) < 0
+ if (PyModule_AddStringConstant (gdb_module, "VERSION", version) < 0
+ || PyModule_AddStringConstant (gdb_module, "HOST_CONFIG", host_name) < 0
|| PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG",
- (char*) target_name) < 0)
+ target_name) < 0)
return false;
/* Add stream constants. */
printed. For example:\n\
\n\
(gdb) python-interactive 2 + 3\n\
- 5\n\
-")
+ 5")
#else /* HAVE_PYTHON */
_("\
Start a Python interactive prompt.\n\
warning (_("\n"
"Could not load the Python gdb module from `%s'.\n"
"Limited Python support is available from the _gdb module.\n"
- "Suggest passing --data-directory=/path/to/gdb/data-directory.\n"),
+ "Suggest passing --data-directory=/path/to/gdb/data-directory."),
gdb_pythondir.c_str ());
/* We return "success" here as we've already emitted the
warning. */
METH_VARARGS | METH_KEYWORDS,
"lookup_global_symbol (name [, domain]) -> symbol\n\
Return the symbol corresponding to the given name (or None)." },
+ { "lookup_static_symbol", (PyCFunction) gdbpy_lookup_static_symbol,
+ METH_VARARGS | METH_KEYWORDS,
+ "lookup_static_symbol (name [, domain]) -> symbol\n\
+Return the static-linkage symbol corresponding to the given name (or None)." },
{ "lookup_objfile", (PyCFunction) gdbpy_lookup_objfile,
METH_VARARGS | METH_KEYWORDS,