/* General python/gdb code
- Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ Copyright (C) 2008-2016 Free Software Foundation, Inc.
This file is part of GDB.
#include "extension-priv.h"
#include "cli/cli-utils.h"
#include <ctype.h>
+#include "location.h"
+#include "ser-event.h"
/* Declared constants and enum for python stack printing. */
static const char python_excp_none[] = "none";
#ifdef HAVE_PYTHON
/* Forward decls, these are defined later. */
-static const struct extension_language_script_ops python_extension_script_ops;
-static const struct extension_language_ops python_extension_ops;
+extern const struct extension_language_script_ops python_extension_script_ops;
+extern const struct extension_language_ops python_extension_ops;
#endif
/* The main struct describing GDB's interface to the Python
int gdb_python_initialized;
-static PyMethodDef GdbMethods[];
+extern PyMethodDef python_GdbMethods[];
#ifdef IS_PY3K
-static struct PyModuleDef GdbModuleDef;
+extern struct PyModuleDef python_GdbModuleDef;
#endif
PyObject *gdb_module;
static script_sourcer_func gdbpy_source_script;
static objfile_script_sourcer_func gdbpy_source_objfile_script;
+static objfile_script_executor_func gdbpy_execute_objfile_script;
static void gdbpy_finish_initialization
(const struct extension_language_defn *);
static int gdbpy_initialized (const struct extension_language_defn *);
const struct ext_lang_type_printers *, struct type *, char **);
static void gdbpy_free_type_printers (const struct extension_language_defn *,
struct ext_lang_type_printers *);
-static void gdbpy_clear_quit_flag (const struct extension_language_defn *);
static void gdbpy_set_quit_flag (const struct extension_language_defn *);
static int gdbpy_check_quit_flag (const struct extension_language_defn *);
static enum ext_lang_rc gdbpy_before_prompt_hook
/* The interface between gdb proper and loading of python scripts. */
-static const struct extension_language_script_ops python_extension_script_ops =
+const struct extension_language_script_ops python_extension_script_ops =
{
gdbpy_source_script,
gdbpy_source_objfile_script,
+ gdbpy_execute_objfile_script,
gdbpy_auto_load_enabled
};
/* The interface between gdb proper and python extensions. */
-static const struct extension_language_ops python_extension_ops =
+const struct extension_language_ops python_extension_ops =
{
gdbpy_finish_initialization,
gdbpy_initialized,
gdbpy_breakpoint_has_cond,
gdbpy_breakpoint_cond_says_stop,
- gdbpy_clear_quit_flag,
gdbpy_set_quit_flag,
gdbpy_check_quit_flag,
gdbpy_free_xmethod_worker_data,
gdbpy_get_matching_xmethod_workers,
gdbpy_get_xmethod_arg_types,
+ gdbpy_get_xmethod_result_type,
gdbpy_invoke_xmethod
};
ensure_python_env (struct gdbarch *gdbarch,
const struct language_defn *language)
{
- struct python_env *env = xmalloc (sizeof *env);
+ struct python_env *env = XNEW (struct python_env);
/* We should not ever enter Python unless initialized. */
if (!gdb_python_initialized)
return make_cleanup (restore_python_env, env);
}
-/* Clear the quit flag. */
-
-static void
-gdbpy_clear_quit_flag (const struct extension_language_defn *extlang)
-{
- /* This clears the flag as a side effect. */
- PyOS_InterruptOccurred ();
-}
-
/* Set the quit flag. */
static void
static void
python_interactive_command (char *arg, int from_tty)
{
- struct cleanup *cleanup;
+ struct ui *ui = current_ui;
int err;
- cleanup = make_cleanup_restore_integer (&interpreter_async);
- interpreter_async = 0;
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
arg = skip_spaces (arg);
if (arg && *arg)
{
int len = strlen (arg);
- char *script = xmalloc (len + 2);
+ char *script = (char *) xmalloc (len + 2);
strcpy (script, arg);
script[len] = '\n';
}
else
{
- err = PyRun_InteractiveLoop (instream, "<stdin>");
+ err = PyRun_InteractiveLoop (ui->instream, "<stdin>");
dont_repeat ();
}
gdbpy_print_stack ();
error (_("Error while executing Python code."));
}
-
- do_cleanups (cleanup);
}
/* A wrapper around PyRun_SimpleFile. FILE is the Python script to run
for (iter = l; iter; iter = iter->next)
size += strlen (iter->line) + 1;
- script = xmalloc (size + 1);
+ script = (char *) xmalloc (size + 1);
here = 0;
for (iter = l; iter; iter = iter->next)
{
cleanup = ensure_python_env (get_current_arch (), current_language);
- make_cleanup_restore_integer (&interpreter_async);
- interpreter_async = 0;
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
arg = skip_spaces (arg);
if (arg && *arg)
if (! str)
str = "";
- return PyString_Decode (str, strlen (str), host_charset (), NULL);
+ return host_string_to_python_string (str);
}
case var_boolean:
/* A Python function which returns a gdb parameter's value as a Python
value. */
-PyObject *
+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;
- volatile struct gdb_exception except;
if (! PyArg_ParseTuple (args, "s", &arg))
return NULL;
newarg = concat ("show ", arg, (char *) NULL);
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
found = lookup_cmd_composition (newarg, &alias, &prefix, &cmd);
}
+ CATCH (ex, RETURN_MASK_ALL)
+ {
+ except = ex;
+ }
+ END_CATCH
+
xfree (newarg);
GDB_PY_HANDLE_EXCEPTION (except);
if (!found)
const char *arg;
PyObject *from_tty_obj = NULL, *to_string_obj = NULL;
int from_tty, to_string;
- volatile struct gdb_exception except;
static char *keywords[] = {"command", "from_tty", "to_string", NULL };
- char *result = NULL;
if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O!O!", keywords, &arg,
&PyBool_Type, &from_tty_obj,
to_string = cmp;
}
- TRY_CATCH (except, RETURN_MASK_ALL)
+ std::string to_string_res;
+
+ TRY
{
/* Copy the argument text in case the command modifies it. */
char *copy = xstrdup (arg);
struct cleanup *cleanup = make_cleanup (xfree, copy);
+ struct interp *interp;
+
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
- make_cleanup_restore_integer (&interpreter_async);
- interpreter_async = 0;
+ 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_ui_out (interp);
prevent_dont_repeat ();
if (to_string)
- result = execute_command_to_string (copy, from_tty);
+ to_string_res = execute_command_to_string (copy, from_tty);
else
- {
- result = NULL;
- execute_command (copy, from_tty);
- }
-
+ execute_command (copy, from_tty);
do_cleanups (cleanup);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
/* Do any commands attached to breakpoint we stopped at. */
bpstat_do_actions ();
- if (result)
- {
- PyObject *r = PyString_FromString (result);
- xfree (result);
- return r;
- }
+ if (to_string)
+ return PyString_FromString (to_string_res.c_str ());
Py_RETURN_NONE;
}
{
char *soname;
PyObject *str_obj;
- gdb_py_longest pc;
+ gdb_py_ulongest pc;
- if (!PyArg_ParseTuple (args, GDB_PY_LL_ARG, &pc))
+ if (!PyArg_ParseTuple (args, GDB_PY_LLU_ARG, &pc))
return NULL;
soname = solib_name_from_address (current_program_space, pc);
if (soname)
- str_obj = PyString_Decode (soname, strlen (soname), host_charset (), NULL);
+ str_obj = host_string_to_python_string (soname);
else
{
str_obj = Py_None;
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;
- const char *arg = NULL;
- char *copy_to_free = NULL, *copy = NULL;
+ char *arg = NULL;
struct cleanup *cleanups;
PyObject *result = NULL;
PyObject *return_result = NULL;
PyObject *unparsed = NULL;
- volatile struct gdb_exception except;
+ struct event_location *location = NULL;
if (! PyArg_ParseTuple (args, "|s", &arg))
return NULL;
cleanups = make_cleanup (null_cleanup, NULL);
sals.sals = NULL;
- TRY_CATCH (except, RETURN_MASK_ALL)
+
+ if (arg != NULL)
{
- if (arg)
- {
- copy = xstrdup (arg);
- copy_to_free = copy;
- sals = decode_line_1 (©, 0, 0, 0);
- }
+ location = string_to_event_location_basic (&arg, python_language);
+ make_cleanup_delete_event_location (location);
+ }
+
+ TRY
+ {
+ if (location != NULL)
+ sals = decode_line_1 (location, 0, NULL, NULL, 0);
else
{
set_default_source_symtab_and_line ();
sals.nelts = 1;
}
}
-
- if (sals.sals != NULL && sals.sals != &sal)
+ CATCH (ex, RETURN_MASK_ALL)
{
- make_cleanup (xfree, copy_to_free);
- make_cleanup (xfree, sals.sals);
+ except = ex;
}
+ END_CATCH
+
+ if (sals.sals != NULL && sals.sals != &sal)
+ make_cleanup (xfree, sals.sals);
if (except.reason < 0)
{
goto error;
}
- if (copy && strlen (copy) > 0)
+ if (arg != NULL && strlen (arg) > 0)
{
- unparsed = PyString_FromString (copy);
+ unparsed = PyString_FromString (arg);
if (unparsed == NULL)
{
Py_DECREF (result);
{
const char *expr_str;
struct value *result = NULL;
- volatile struct gdb_exception except;
if (!PyArg_ParseTuple (args, "s", &expr_str))
return NULL;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
result = parse_and_eval (expr_str);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
return value_to_value_object (result);
}
gdbpy_find_pc_line (PyObject *self, PyObject *args)
{
gdb_py_ulongest pc_llu;
- volatile struct gdb_exception except;
PyObject *result = NULL; /* init for gcc -Wall */
if (!PyArg_ParseTuple (args, GDB_PY_LLU_ARG, &pc_llu))
return NULL;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
struct symtab_and_line sal;
CORE_ADDR pc;
sal = find_pc_line (pc, 0);
result = symtab_and_line_to_sal_object (sal);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
return result;
}
+/* Implementation of gdb.invalidate_cached_frames. */
+
+static PyObject *
+gdbpy_invalidate_cached_frames (PyObject *self, PyObject *args)
+{
+ reinit_frame_cache ();
+ Py_RETURN_NONE;
+}
+
/* Read a file as Python code.
This is the extension_language_script_ops.script_sourcer "method".
FILE is the file to load. FILENAME is name of the file FILE.
/* The final link of the event list. */
static struct gdbpy_event **gdbpy_event_list_end;
-/* We use a file handler, and not an async handler, so that we can
- wake up the main thread even when it is blocked in poll(). */
-static struct serial *gdbpy_event_fds[2];
+/* So that we can wake up the main thread even when it is blocked in
+ poll(). */
+static struct serial_event *gdbpy_serial_event;
/* The file handler callback. This reads from the internal pipe, and
then processes the Python event queue. This will always be run in
the main gdb thread. */
static void
-gdbpy_run_events (struct serial *scb, void *context)
+gdbpy_run_events (int error, gdb_client_data client_data)
{
struct cleanup *cleanup;
cleanup = ensure_python_env (get_current_arch (), current_language);
- /* Flush the fd. Do this before flushing the events list, so that
- any new event post afterwards is sure to re-awake the event
+ /* Clear the event fd. Do this before flushing the events list, so
+ that any new event post afterwards is sure to re-awake the event
loop. */
- while (serial_readchar (gdbpy_event_fds[0], 0) >= 0)
- ;
+ serial_event_clear (gdbpy_serial_event);
while (gdbpy_event_list)
{
/* Wake up gdb when needed. */
if (wakeup)
- {
- char c = 'q'; /* Anything. */
-
- if (serial_write (gdbpy_event_fds[1], &c, 1))
- return PyErr_SetFromErrno (PyExc_IOError);
- }
+ serial_event_set (gdbpy_serial_event);
Py_RETURN_NONE;
}
static int
gdbpy_initialize_events (void)
{
- if (serial_pipe (gdbpy_event_fds) == 0)
- {
- gdbpy_event_list_end = &gdbpy_event_list;
- serial_async (gdbpy_event_fds[0], gdbpy_run_events, NULL);
- }
+ gdbpy_event_list_end = &gdbpy_event_list;
+
+ gdbpy_serial_event = make_serial_event ();
+ add_file_handler (serial_event_fd (gdbpy_serial_event),
+ gdbpy_run_events, NULL);
return 0;
}
const char *current_gdb_prompt)
{
struct cleanup *cleanup;
- char *prompt = NULL;
+ gdb::unique_xmalloc_ptr<char> prompt;
if (!gdb_python_initialized)
return EXT_LANG_RC_NOP;
if (prompt == NULL)
goto fail;
- else
- make_cleanup (xfree, prompt);
}
}
}
/* If a prompt has been set, PROMPT will not be NULL. If it is
NULL, do not set the prompt. */
if (prompt != NULL)
- set_prompt (prompt);
+ set_prompt (prompt.get ());
do_cleanups (cleanup);
return prompt != NULL ? EXT_LANG_RC_OK : EXT_LANG_RC_NOP;
const char *arg;
static char *keywords[] = {"text", "stream", NULL };
int stream_type = 0;
- volatile struct gdb_exception except;
if (! PyArg_ParseTupleAndKeywords (args, kw, "s|i", keywords, &arg,
&stream_type))
return NULL;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
switch (stream_type)
{
fprintf_filtered (gdb_stdout, "%s", arg);
}
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
Py_RETURN_NONE;
}
Py_RETURN_NONE;
}
+/* Return non-zero if print-stack is not "none". */
+
+int
+gdbpy_print_python_errors_p (void)
+{
+ return gdbpy_should_print_stack != python_excp_none;
+}
+
/* Print a python exception trace, print just a message, or print
nothing and clear the python exception, depending on
gdbpy_should_print_stack. Only call this if a python exception is
void
gdbpy_print_stack (void)
{
- volatile struct gdb_exception except;
/* Print "none", just clear exception. */
if (gdbpy_should_print_stack == python_excp_none)
/* PyErr_Print doesn't necessarily end output with a newline.
This works because Python's stdout/stderr is fed through
printf_filtered. */
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
begin_line ();
}
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ }
+ END_CATCH
}
/* Print "message", just error print message. */
else
{
PyObject *ptype, *pvalue, *ptraceback;
- char *msg = NULL, *type = NULL;
PyErr_Fetch (&ptype, &pvalue, &ptraceback);
/* Fetch the error message contained within ptype, pvalue. */
- msg = gdbpy_exception_to_string (ptype, pvalue);
- type = gdbpy_obj_to_string (ptype);
+ gdb::unique_xmalloc_ptr<char>
+ msg (gdbpy_exception_to_string (ptype, pvalue));
+ gdb::unique_xmalloc_ptr<char> type (gdbpy_obj_to_string (ptype));
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
if (msg == NULL)
{
}
else
fprintf_filtered (gdb_stderr, "Python Exception %s %s: \n",
- type, msg);
+ type.get (), msg.get ());
+ }
+ CATCH (except, RETURN_MASK_ALL)
+ {
}
+ END_CATCH
Py_XDECREF (ptype);
Py_XDECREF (pvalue);
Py_XDECREF (ptraceback);
- xfree (msg);
}
}
/* The "current" objfile. This is set when gdb detects that a new
objfile has been loaded. It is only set for the duration of a call to
- gdbpy_source_objfile_script; it is NULL at other times. */
+ gdbpy_source_objfile_script and gdbpy_execute_objfile_script; it is NULL
+ at other times. */
static struct objfile *gdbpy_current_objfile;
/* Set the current objfile to OBJFILE and then read FILE named FILENAME
gdbpy_current_objfile = NULL;
}
+/* Set the current objfile to OBJFILE and then execute SCRIPT
+ as Python code. This does not throw any errors. If an exception
+ occurs python will print the traceback and clear the error indicator.
+ This is the extension_language_script_ops.objfile_script_executor
+ "method". */
+
+static void
+gdbpy_execute_objfile_script (const struct extension_language_defn *extlang,
+ struct objfile *objfile, const char *name,
+ const char *script)
+{
+ struct cleanup *cleanups;
+
+ if (!gdb_python_initialized)
+ return;
+
+ cleanups = ensure_python_env (get_objfile_arch (objfile), current_language);
+ gdbpy_current_objfile = objfile;
+
+ PyRun_SimpleString (script);
+
+ do_cleanups (cleanups);
+ gdbpy_current_objfile = NULL;
+}
+
/* Return the current Objfile, or None if there isn't one. */
static PyObject *
struct cleanup *cleanups;
PyObject *type_obj, *type_module = NULL, *func = NULL;
PyObject *result_obj = NULL;
- PyObject *printers_obj = ext_printers->py_type_printers;
- char *result = NULL;
+ PyObject *printers_obj = (PyObject *) ext_printers->py_type_printers;
+ gdb::unique_xmalloc_ptr<char> result;
if (printers_obj == NULL)
return EXT_LANG_RC_NOP;
Py_XDECREF (result_obj);
do_cleanups (cleanups);
if (result != NULL)
- *prettied_type = result;
- return result != NULL ? EXT_LANG_RC_OK : EXT_LANG_RC_ERROR;
+ {
+ *prettied_type = result.release ();
+ return EXT_LANG_RC_OK;
+ }
+ return EXT_LANG_RC_ERROR;
}
/* Free the result of start_type_printers.
struct ext_lang_type_printers *ext_printers)
{
struct cleanup *cleanups;
- PyObject *printers = ext_printers->py_type_printers;
+ PyObject *printers = (PyObject *) ext_printers->py_type_printers;
if (printers == NULL)
return;
/foo/lib/pythonX.Y/...
This must be done before calling Py_Initialize. */
progname = concat (ldirname (python_libdir), SLASH_STRING, "bin",
- SLASH_STRING, "python", NULL);
+ SLASH_STRING, "python", (char *) NULL);
#ifdef IS_PY3K
- oldloc = setlocale (LC_ALL, NULL);
+ oldloc = xstrdup (setlocale (LC_ALL, NULL));
setlocale (LC_ALL, "");
progsize = strlen (progname);
- if (progsize == (size_t) -1)
- {
- fprintf (stderr, "Could not convert python path to string\n");
- return;
- }
- progname_copy = PyMem_Malloc ((progsize + 1) * sizeof (wchar_t));
+ progname_copy = (wchar_t *) PyMem_Malloc ((progsize + 1) * sizeof (wchar_t));
if (!progname_copy)
{
+ xfree (oldloc);
fprintf (stderr, "out of memory\n");
return;
}
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;
}
setlocale (LC_ALL, oldloc);
+ xfree (oldloc);
/* Note that Py_SetProgramName expects the string it is passed to
remain alive for the duration of the program's execution, so
PyEval_InitThreads ();
#ifdef IS_PY3K
- gdb_module = PyModule_Create (&GdbModuleDef);
+ gdb_module = PyModule_Create (&python_GdbModuleDef);
/* Add _gdb module to the list of known built-in modules. */
_PyImport_FixupBuiltin (gdb_module, "_gdb");
#else
- gdb_module = Py_InitModule ("_gdb", GdbMethods);
+ gdb_module = Py_InitModule ("_gdb", python_GdbMethods);
#endif
if (gdb_module == NULL)
goto fail;
|| gdbpy_initialize_new_objfile_event () < 0
|| gdbpy_initialize_clear_objfiles_event () < 0
|| gdbpy_initialize_arch () < 0
- || gdbpy_initialize_xmethods () < 0)
+ || gdbpy_initialize_xmethods () < 0
+ || gdbpy_initialize_unwind () < 0)
goto fail;
gdbpy_to_string_cst = PyString_FromString ("to_string");
/* Add the initial data-directory to sys.path. */
- gdb_pythondir = concat (gdb_datadir, SLASH_STRING, "python", NULL);
+ gdb_pythondir = concat (gdb_datadir, SLASH_STRING, "python", (char *) NULL);
make_cleanup (xfree, gdb_pythondir);
sys_path = PySys_GetObject ("path");
#ifdef HAVE_PYTHON
-static PyMethodDef GdbMethods[] =
+PyMethodDef python_GdbMethods[] =
{
{ "history", gdbpy_history, METH_VARARGS,
"Get a value from history" },
METH_VARARGS | METH_KEYWORDS,
"lookup_global_symbol (name [, domain]) -> symbol\n\
Return the symbol corresponding to the given name (or None)." },
+
+ { "lookup_objfile", (PyCFunction) gdbpy_lookup_objfile,
+ METH_VARARGS | METH_KEYWORDS,
+ "lookup_objfile (name, [by_build_id]) -> objfile\n\
+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,
{ "inferiors", gdbpy_inferiors, METH_NOARGS,
"inferiors () -> (gdb.Inferior, ...).\n\
Return a tuple containing all inferiors." },
+
+ { "invalidate_cached_frames", gdbpy_invalidate_cached_frames, METH_NOARGS,
+ "invalidate_cached_frames () -> None.\n\
+Invalidate any cached frame objects in gdb.\n\
+Intended for internal use only." },
+
{NULL, NULL, 0, NULL}
};
#ifdef IS_PY3K
-static struct PyModuleDef GdbModuleDef =
+struct PyModuleDef python_GdbModuleDef =
{
PyModuleDef_HEAD_INIT,
"_gdb",
NULL,
-1,
- GdbMethods,
+ python_GdbMethods,
NULL,
NULL,
NULL,