/* General python/gdb code
- Copyright (C) 2008-2015 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";
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
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;
PyObject *from_tty_obj = NULL, *to_string_obj = NULL;
int from_tty, to_string;
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;
}
+ 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);
+
+ scoped_restore save_uiout = make_scoped_restore (¤t_uiout);
- make_cleanup_restore_integer (&interpreter_async);
- interpreter_async = 0;
+ /* 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);
}
CATCH (except, RETURN_MASK_ALL)
/* 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;
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;
+ struct event_location *location = NULL;
if (! PyArg_ParseTuple (args, "|s", &arg))
return NULL;
sals.sals = NULL;
+ if (arg != NULL)
+ {
+ location = string_to_event_location_basic (&arg, python_language);
+ make_cleanup_delete_event_location (location);
+ }
+
TRY
{
- if (arg)
- {
- copy = xstrdup (arg);
- copy_to_free = copy;
- sals = decode_line_1 (©, 0, 0, 0);
- }
+ if (location != NULL)
+ sals = decode_line_1 (location, 0, NULL, NULL, 0);
else
{
set_default_source_symtab_and_line ();
END_CATCH
if (sals.sals != NULL && sals.sals != &sal)
- {
- make_cleanup (xfree, copy_to_free);
- make_cleanup (xfree, sals.sals);
- }
+ 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);
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;
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
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
{
}
else
fprintf_filtered (gdb_stderr, "Python Exception %s %s: \n",
- type, msg);
+ type.get (), msg.get ());
}
CATCH (except, RETURN_MASK_ALL)
{
Py_XDECREF (ptype);
Py_XDECREF (pvalue);
Py_XDECREF (ptraceback);
- xfree (msg);
}
}
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
/* 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");
{ "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}
};