X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fpython%2Fpython.c;h=375042c57d9def8f5f00536185cfb9bb64b17b05;hb=d8e227793f4a8ce420f2b4a068844b5b6ec39490;hp=19098ccebaf4feee2abc328114acd99153fd6119;hpb=a6bac58e84001d33b9540e208e9ca6d6ab265bf3;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/python/python.c b/gdb/python/python.c index 19098cceba..375042c57d 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -1,6 +1,6 @@ /* General python/gdb code - Copyright (C) 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GDB. @@ -18,12 +18,18 @@ along with this program. If not, see . */ #include "defs.h" +#include "arch-utils.h" #include "command.h" #include "ui-out.h" #include "cli/cli-script.h" #include "gdbcmd.h" +#include "progspace.h" #include "objfiles.h" -#include "observer.h" +#include "value.h" +#include "language.h" +#include "exceptions.h" +#include "event-loop.h" +#include "serial.h" #include @@ -31,10 +37,6 @@ false otherwise. */ static int gdbpy_should_print_stack = 1; -/* This is true if we should auto-load python code when an objfile is - opened, false otherwise. */ -static int gdbpy_auto_load = 1; - #ifdef HAVE_PYTHON #include "python.h" @@ -42,8 +44,10 @@ static int gdbpy_auto_load = 1; #include "cli/cli-decode.h" #include "charset.h" #include "top.h" -#include "exceptions.h" +#include "solib.h" #include "python-internal.h" +#include "linespec.h" +#include "source.h" #include "version.h" #include "target.h" #include "gdbthread.h" @@ -57,6 +61,76 @@ PyObject *gdbpy_to_string_cst; PyObject *gdbpy_children_cst; PyObject *gdbpy_display_hint_cst; PyObject *gdbpy_doc_cst; +PyObject *gdbpy_enabled_cst; + +/* The GdbError exception. */ +PyObject *gdbpy_gdberror_exc; + +/* The `gdb.error' base class. */ +PyObject *gdbpy_gdb_error; + +/* The `gdb.MemoryError' exception. */ +PyObject *gdbpy_gdb_memory_error; + +/* Architecture and language to be used in callbacks from + the Python interpreter. */ +struct gdbarch *python_gdbarch; +const struct language_defn *python_language; + +/* Restore global language and architecture and Python GIL state + when leaving the Python interpreter. */ + +struct python_env +{ + PyGILState_STATE state; + struct gdbarch *gdbarch; + const struct language_defn *language; + PyObject *error_type, *error_value, *error_traceback; +}; + +static void +restore_python_env (void *p) +{ + struct python_env *env = (struct python_env *)p; + + /* Leftover Python error is forbidden by Python Exception Handling. */ + if (PyErr_Occurred ()) + { + /* This order is similar to the one calling error afterwards. */ + gdbpy_print_stack (); + warning (_("internal error: Unhandled Python exception")); + } + + PyErr_Restore (env->error_type, env->error_value, env->error_traceback); + + PyGILState_Release (env->state); + python_gdbarch = env->gdbarch; + python_language = env->language; + xfree (env); +} + +/* Called before entering the Python interpreter to install the + current language and architecture to be used for Python values. */ + +struct cleanup * +ensure_python_env (struct gdbarch *gdbarch, + const struct language_defn *language) +{ + struct python_env *env = xmalloc (sizeof *env); + + env->state = PyGILState_Ensure (); + env->gdbarch = python_gdbarch; + env->language = python_language; + + python_gdbarch = gdbarch; + python_language = language; + + /* Save it and ensure ! PyErr_Occurred () afterwards. */ + PyErr_Fetch (&env->error_type, &env->error_value, &env->error_traceback); + + return make_cleanup (restore_python_env, env); +} + /* Given a command_line, return a command string suitable for passing to Python. Lines in the string are separated by newlines. The @@ -79,6 +153,7 @@ compute_python_string (struct command_line *l) for (iter = l; iter; iter = iter->next) { int len = strlen (iter->line); + strcpy (&script[here], iter->line); here += len; script[here++] = '\n'; @@ -96,13 +171,11 @@ eval_python_from_control_command (struct command_line *cmd) int ret; char *script; struct cleanup *cleanup; - PyGILState_STATE state; if (cmd->body_count != 1) error (_("Invalid \"python\" block structure.")); - state = PyGILState_Ensure (); - cleanup = make_cleanup_py_restore_gil (&state); + cleanup = ensure_python_env (get_current_arch (), current_language); script = compute_python_string (cmd->body_list[0]); ret = PyRun_SimpleString (script); @@ -122,11 +195,8 @@ static void python_command (char *arg, int from_tty) { struct cleanup *cleanup; - PyGILState_STATE state; - - state = PyGILState_Ensure (); - cleanup = make_cleanup_py_restore_gil (&state); + cleanup = ensure_python_env (get_current_arch (), current_language); while (arg && *arg && isspace (*arg)) ++arg; if (arg && *arg) @@ -140,6 +210,7 @@ python_command (char *arg, int from_tty) else { struct command_line *l = get_command_line (python_control, ""); + make_cleanup_free_command_lines (&l); execute_control_command_untraced (l); } @@ -152,11 +223,10 @@ python_command (char *arg, int from_tty) /* Transform a gdb parameters's value into a Python value. May return NULL (and set a Python exception) on error. Helper function for get_parameter. */ - -static PyObject * -parameter_to_python (struct cmd_list_element *cmd) +PyObject * +gdbpy_parameter_value (enum var_types type, void *var) { - switch (cmd->var_type) + switch (type) { case var_string: case var_string_noescape: @@ -164,7 +234,8 @@ parameter_to_python (struct cmd_list_element *cmd) case var_filename: case var_enum: { - char *str = * (char **) cmd->var; + char *str = * (char **) var; + if (! str) str = ""; return PyString_Decode (str, strlen (str), host_charset (), NULL); @@ -172,7 +243,7 @@ parameter_to_python (struct cmd_list_element *cmd) case var_boolean: { - if (* (int *) cmd->var) + if (* (int *) var) Py_RETURN_TRUE; else Py_RETURN_FALSE; @@ -180,7 +251,8 @@ parameter_to_python (struct cmd_list_element *cmd) case var_auto_boolean: { - enum auto_boolean ab = * (enum auto_boolean *) cmd->var; + enum auto_boolean ab = * (enum auto_boolean *) var; + if (ab == AUTO_BOOLEAN_TRUE) Py_RETURN_TRUE; else if (ab == AUTO_BOOLEAN_FALSE) @@ -190,29 +262,31 @@ parameter_to_python (struct cmd_list_element *cmd) } case var_integer: - if ((* (int *) cmd->var) == INT_MAX) + if ((* (int *) var) == INT_MAX) Py_RETURN_NONE; /* Fall through. */ case var_zinteger: - return PyLong_FromLong (* (int *) cmd->var); + return PyLong_FromLong (* (int *) var); case var_uinteger: { - unsigned int val = * (unsigned int *) cmd->var; + unsigned int val = * (unsigned int *) var; + if (val == UINT_MAX) Py_RETURN_NONE; return PyLong_FromUnsignedLong (val); } } - return PyErr_Format (PyExc_RuntimeError, "programmer error: unhandled type"); + return PyErr_Format (PyExc_RuntimeError, + _("Programmer error: unhandled type.")); } /* A Python function which returns a gdb parameter's value as a Python value. */ -static PyObject * -get_parameter (PyObject *self, PyObject *args) +PyObject * +gdbpy_parameter (PyObject *self, PyObject *args) { struct cmd_list_element *alias, *prefix, *cmd; char *arg, *newarg; @@ -232,51 +306,383 @@ get_parameter (PyObject *self, PyObject *args) GDB_PY_HANDLE_EXCEPTION (except); if (!found) return PyErr_Format (PyExc_RuntimeError, - "could not find parameter `%s'", arg); + _("Could not find parameter `%s'."), arg); if (! cmd->var) - return PyErr_Format (PyExc_RuntimeError, "`%s' is not a variable", arg); - return parameter_to_python (cmd); + return PyErr_Format (PyExc_RuntimeError, + _("`%s' is not a parameter."), arg); + return gdbpy_parameter_value (cmd->var_type, cmd->var); +} + +/* Wrapper for target_charset. */ + +static PyObject * +gdbpy_target_charset (PyObject *self, PyObject *args) +{ + const char *cset = target_charset (python_gdbarch); + + return PyUnicode_Decode (cset, strlen (cset), host_charset (), NULL); +} + +/* Wrapper for target_wide_charset. */ + +static PyObject * +gdbpy_target_wide_charset (PyObject *self, PyObject *args) +{ + const char *cset = target_wide_charset (python_gdbarch); + + return PyUnicode_Decode (cset, strlen (cset), host_charset (), NULL); } /* A Python function which evaluates a string using the gdb CLI. */ static PyObject * -execute_gdb_command (PyObject *self, PyObject *args) +execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) { - struct cmd_list_element *alias, *prefix, *cmd; - char *arg, *newarg; - PyObject *from_tty_obj = NULL; - int from_tty; - int cmp; + 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_ParseTuple (args, "s|O!", &arg, &PyBool_Type, &from_tty_obj)) + if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O!O!", keywords, &arg, + &PyBool_Type, &from_tty_obj, + &PyBool_Type, &to_string_obj)) return NULL; from_tty = 0; if (from_tty_obj) { - cmp = PyObject_IsTrue (from_tty_obj); + int cmp = PyObject_IsTrue (from_tty_obj); if (cmp < 0) - return NULL; + return NULL; from_tty = cmp; } + to_string = 0; + if (to_string_obj) + { + int cmp = PyObject_IsTrue (to_string_obj); + if (cmp < 0) + return NULL; + to_string = cmp; + } + TRY_CATCH (except, RETURN_MASK_ALL) { - execute_command (arg, from_tty); + /* Copy the argument text in case the command modifies it. */ + char *copy = xstrdup (arg); + struct cleanup *cleanup = make_cleanup (xfree, copy); + + if (to_string) + result = execute_command_to_string (copy, from_tty); + else + { + result = NULL; + execute_command (copy, from_tty); + } + + do_cleanups (cleanup); } GDB_PY_HANDLE_EXCEPTION (except); /* Do any commands attached to breakpoint we stopped at. */ bpstat_do_actions (); + if (result) + { + PyObject *r = PyString_FromString (result); + xfree (result); + return r; + } Py_RETURN_NONE; } +/* Implementation of gdb.solib_name (Long) -> String. + Returns the name of the shared library holding a given address, or None. */ + +static PyObject * +gdbpy_solib_name (PyObject *self, PyObject *args) +{ + char *soname; + PyObject *str_obj; +#ifdef PY_LONG_LONG + unsigned PY_LONG_LONG pc; + /* To be compatible with Python 2.4 the format strings are not const. */ + char *format = "K"; +#else + unsigned long pc; + char *format = "k"; +#endif + + if (!PyArg_ParseTuple (args, format, &pc)) + return NULL; + + soname = solib_name_from_address (current_program_space, pc); + if (soname) + str_obj = PyString_Decode (soname, strlen (soname), host_charset (), NULL); + else + { + str_obj = Py_None; + Py_INCREF (Py_None); + } + + return str_obj; +} + +/* A Python function which is a wrapper for decode_line_1. */ + +static PyObject * +gdbpy_decode_line (PyObject *self, PyObject *args) +{ + struct symtabs_and_lines sals = { NULL, 0 }; /* Initialize to + appease gcc. */ + struct symtab_and_line sal; + char *arg = NULL; + char *copy = NULL; + struct cleanup *cleanups; + PyObject *result = NULL; + PyObject *return_result = NULL; + PyObject *unparsed = NULL; + volatile struct gdb_exception except; + + if (! PyArg_ParseTuple (args, "|s", &arg)) + return NULL; + + cleanups = ensure_python_env (get_current_arch (), current_language); + + TRY_CATCH (except, RETURN_MASK_ALL) + { + if (arg) + { + arg = xstrdup (arg); + make_cleanup (xfree, arg); + copy = arg; + sals = decode_line_1 (©, 0, 0, 0, 0, 0); + make_cleanup (xfree, sals.sals); + } + else + { + set_default_source_symtab_and_line (); + sal = get_current_source_symtab_and_line (); + sals.sals = &sal; + sals.nelts = 1; + } + } + if (except.reason < 0) + { + do_cleanups (cleanups); + /* We know this will always throw. */ + GDB_PY_HANDLE_EXCEPTION (except); + } + + if (sals.nelts) + { + int i; + + result = PyTuple_New (sals.nelts); + if (! result) + goto error; + for (i = 0; i < sals.nelts; ++i) + { + PyObject *obj; + char *str; + + obj = symtab_and_line_to_sal_object (sals.sals[i]); + if (! obj) + { + Py_DECREF (result); + goto error; + } + + PyTuple_SetItem (result, i, obj); + } + } + else + { + result = Py_None; + Py_INCREF (Py_None); + } + + return_result = PyTuple_New (2); + if (! return_result) + { + Py_DECREF (result); + goto error; + } + + if (copy && strlen (copy) > 0) + unparsed = PyString_FromString (copy); + else + { + unparsed = Py_None; + Py_INCREF (Py_None); + } + + PyTuple_SetItem (return_result, 0, unparsed); + PyTuple_SetItem (return_result, 1, result); + + do_cleanups (cleanups); + + return return_result; + + error: + do_cleanups (cleanups); + return NULL; +} + +/* Parse a string and evaluate it as an expression. */ +static PyObject * +gdbpy_parse_and_eval (PyObject *self, PyObject *args) +{ + 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) + { + result = parse_and_eval (expr_str); + } + GDB_PY_HANDLE_EXCEPTION (except); + + return value_to_value_object (result); +} + +/* Read a file as Python code. STREAM is the input file; FILE is the + name of the file. + STREAM is not closed, that is the caller's responsibility. */ + +void +source_python_script (FILE *stream, const char *file) +{ + struct cleanup *cleanup; + + cleanup = ensure_python_env (get_current_arch (), current_language); + + /* Note: If an exception occurs python will print the traceback and + clear the error indicator. */ + PyRun_SimpleFile (stream, file); + + do_cleanups (cleanup); +} + +/* Posting and handling events. */ + +/* A single event. */ +struct gdbpy_event +{ + /* The Python event. This is just a callable object. */ + PyObject *event; + /* The next event. */ + struct gdbpy_event *next; +}; + +/* All pending events. */ +static struct gdbpy_event *gdbpy_event_list; +/* 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]; + +/* 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) +{ + struct cleanup *cleanup; + int r; + + 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 + loop. */ + while (serial_readchar (gdbpy_event_fds[0], 0) >= 0) + ; + + while (gdbpy_event_list) + { + /* Dispatching the event might push a new element onto the event + loop, so we update here "atomically enough". */ + struct gdbpy_event *item = gdbpy_event_list; + gdbpy_event_list = gdbpy_event_list->next; + if (gdbpy_event_list == NULL) + gdbpy_event_list_end = &gdbpy_event_list; + + /* Ignore errors. */ + if (PyObject_CallObject (item->event, NULL) == NULL) + PyErr_Clear (); + + Py_DECREF (item->event); + xfree (item); + } + + do_cleanups (cleanup); +} + +/* Submit an event to the gdb thread. */ +static PyObject * +gdbpy_post_event (PyObject *self, PyObject *args) +{ + struct gdbpy_event *event; + PyObject *func; + int wakeup; + + if (!PyArg_ParseTuple (args, "O", &func)) + return NULL; + + if (!PyCallable_Check (func)) + { + PyErr_SetString (PyExc_RuntimeError, + _("Posted event is not callable")); + return NULL; + } + + Py_INCREF (func); + + /* From here until the end of the function, we have the GIL, so we + can operate on our global data structures without worrying. */ + wakeup = gdbpy_event_list == NULL; + + event = XNEW (struct gdbpy_event); + event->event = func; + event->next = NULL; + *gdbpy_event_list_end = event; + gdbpy_event_list_end = &event->next; + + /* 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); + } + + Py_RETURN_NONE; +} + +/* Initialize the Python event handler. */ +static void +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); + } +} + /* Printing. */ /* A python function to write a single string using gdb's filtered @@ -285,6 +691,7 @@ static PyObject * gdbpy_write (PyObject *self, PyObject *args) { char *arg; + if (! PyArg_ParseTuple (args, "s", &arg)) return NULL; printf_filtered ("%s", arg); @@ -306,96 +713,88 @@ void gdbpy_print_stack (void) { if (gdbpy_should_print_stack) - PyErr_Print (); + { + PyErr_Print (); + /* PyErr_Print doesn't necessarily end output with a newline. + This works because Python's stdout/stderr is fed through + printf_filtered. */ + begin_line (); + } else PyErr_Clear (); } -/* 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_new_objfile; it is NULL at other times. */ -static struct objfile *gdbpy_current_objfile; +/* Return the current Progspace. + There always is one. */ -/* The file name we attempt to read. */ -#define GDBPY_AUTO_FILENAME "-gdb.py" +static PyObject * +gdbpy_get_current_progspace (PyObject *unused1, PyObject *unused2) +{ + PyObject *result; -/* This is a new_objfile observer callback which loads python code - based on the path to the objfile. */ -static void -gdbpy_new_objfile (struct objfile *objfile) + result = pspace_to_pspace_object (current_program_space); + if (result) + Py_INCREF (result); + return result; +} + +/* Return a sequence holding all the Progspaces. */ + +static PyObject * +gdbpy_progspaces (PyObject *unused1, PyObject *unused2) { - char *realname; - char *filename, *debugfile; - int len; - FILE *input; - PyGILState_STATE state; - struct cleanup *cleanups; + struct program_space *ps; + PyObject *list; - if (!gdbpy_auto_load || !objfile || !objfile->name) - return; + list = PyList_New (0); + if (!list) + return NULL; - state = PyGILState_Ensure (); + ALL_PSPACES (ps) + { + PyObject *item = pspace_to_pspace_object (ps); - gdbpy_current_objfile = objfile; + if (!item || PyList_Append (list, item) == -1) + { + Py_DECREF (list); + return NULL; + } + } - realname = gdb_realpath (objfile->name); - len = strlen (realname); - filename = xmalloc (len + sizeof (GDBPY_AUTO_FILENAME)); - memcpy (filename, realname, len); - strcpy (filename + len, GDBPY_AUTO_FILENAME); + return list; +} - input = fopen (filename, "r"); - debugfile = filename; + - cleanups = make_cleanup (xfree, filename); - make_cleanup (xfree, realname); +/* 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 + source_python_script_for_objfile; it is NULL at other times. */ +static struct objfile *gdbpy_current_objfile; - if (!input && debug_file_directory) - { - /* Also try the same file in the separate debug info directory. */ - debugfile = xmalloc (strlen (filename) - + strlen (debug_file_directory) + 1); - strcpy (debugfile, debug_file_directory); - /* FILENAME is absolute, so we don't need a "/" here. */ - strcat (debugfile, filename); - - make_cleanup (xfree, debugfile); - input = fopen (debugfile, "r"); - } +/* Set the current objfile to OBJFILE and then read STREAM,FILE as + Python code. */ - if (!input && gdb_datadir) - { - /* Also try the same file in a subdirectory of gdb's data - directory. */ - debugfile = xmalloc (strlen (gdb_datadir) + strlen (filename) - + strlen ("/auto-load") + 1); - strcpy (debugfile, gdb_datadir); - strcat (debugfile, "/auto-load"); - /* FILENAME is absolute, so we don't need a "/" here. */ - strcat (debugfile, filename); - - make_cleanup (xfree, debugfile); - input = fopen (debugfile, "r"); - } +void +source_python_script_for_objfile (struct objfile *objfile, + FILE *stream, const char *file) +{ + struct cleanup *cleanups; - if (input) - { - /* We don't want to throw an exception here -- but the user - would like to know that something went wrong. */ - if (PyRun_SimpleFile (input, debugfile)) - gdbpy_print_stack (); - fclose (input); - } + cleanups = ensure_python_env (get_objfile_arch (objfile), current_language); + gdbpy_current_objfile = objfile; + + /* Note: If an exception occurs python will print the traceback and + clear the error indicator. */ + PyRun_SimpleFile (stream, file); do_cleanups (cleanups); gdbpy_current_objfile = NULL; - - PyGILState_Release (state); } /* Return the current Objfile, or None if there isn't one. */ + static PyObject * gdbpy_get_current_objfile (PyObject *unused1, PyObject *unused2) { @@ -411,6 +810,7 @@ gdbpy_get_current_objfile (PyObject *unused1, PyObject *unused2) } /* Return a sequence holding all the Objfiles. */ + static PyObject * gdbpy_objfiles (PyObject *unused1, PyObject *unused2) { @@ -424,6 +824,7 @@ gdbpy_objfiles (PyObject *unused1, PyObject *unused2) ALL_OBJFILES (objf) { PyObject *item = objfile_to_objfile_object (objf); + if (!item || PyList_Append (list, item) == -1) { Py_DECREF (list); @@ -449,6 +850,7 @@ python_command (char *arg, int from_tty) { struct command_line *l = get_command_line (python_control, ""); struct cleanup *cleanups = make_cleanup_free_command_lines (&l); + execute_control_command_untraced (l); do_cleanups (cleanups); } @@ -460,14 +862,21 @@ eval_python_from_control_command (struct command_line *cmd) error (_("Python scripting is not supported in this copy of GDB.")); } +void +source_python_script (FILE *stream, const char *file) +{ + throw_error (UNSUPPORTED_ERROR, + _("Python scripting is not supported in this copy of GDB.")); +} + #endif /* HAVE_PYTHON */ /* Lists for 'maint set python' commands. */ -static struct cmd_list_element *set_python_list; -static struct cmd_list_element *show_python_list; +struct cmd_list_element *set_python_list; +struct cmd_list_element *show_python_list; /* Function for use by 'maint set python' prefix command. */ @@ -532,16 +941,18 @@ Enables or disables printing of Python stack traces."), &set_python_list, &show_python_list); - add_setshow_boolean_cmd ("auto-load", class_maintenance, - &gdbpy_auto_load, _("\ -Enable or disable auto-loading of Python code when an object is opened."), _("\ -Show whether Python code will be auto-loaded when an object is opened."), _("\ -Enables or disables auto-loading of Python code when an object is opened."), - NULL, NULL, - &set_python_list, - &show_python_list); - #ifdef HAVE_PYTHON +#ifdef WITH_PYTHON_PATH + /* Work around problem where python gets confused about where it is, + and then can't find its libraries, etc. + NOTE: Python assumes the following layout: + /foo/bin/python + /foo/lib/pythonX.Y/... + This must be done before calling Py_Initialize. */ + Py_SetProgramName (concat (ldirname (python_libdir), SLASH_STRING, "bin", + SLASH_STRING, "python", NULL)); +#endif + Py_Initialize (); PyEval_InitThreads (); @@ -550,29 +961,82 @@ Enables or disables auto-loading of Python code when an object is opened."), /* The casts to (char*) are for python 2.4. */ PyModule_AddStringConstant (gdb_module, "VERSION", (char*) version); PyModule_AddStringConstant (gdb_module, "HOST_CONFIG", (char*) host_name); - PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG", (char*) target_name); + PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG", + (char*) target_name); + + /* gdb.parameter ("data-directory") doesn't necessarily exist when the python + script below is run (depending on order of _initialize_* functions). + Define the initial value of gdb.PYTHONDIR here. */ + { + char *gdb_pythondir; + + gdb_pythondir = concat (gdb_datadir, SLASH_STRING, "python", NULL); + PyModule_AddStringConstant (gdb_module, "PYTHONDIR", gdb_pythondir); + xfree (gdb_pythondir); + } + + gdbpy_gdb_error = PyErr_NewException ("gdb.error", PyExc_RuntimeError, NULL); + PyModule_AddObject (gdb_module, "error", gdbpy_gdb_error); + gdbpy_gdb_memory_error = PyErr_NewException ("gdb.MemoryError", + gdbpy_gdb_error, NULL); + PyModule_AddObject (gdb_module, "MemoryError", gdbpy_gdb_memory_error); + + gdbpy_gdberror_exc = PyErr_NewException ("gdb.GdbError", NULL, NULL); + PyModule_AddObject (gdb_module, "GdbError", gdbpy_gdberror_exc); + + gdbpy_initialize_auto_load (); gdbpy_initialize_values (); gdbpy_initialize_frames (); gdbpy_initialize_commands (); + gdbpy_initialize_symbols (); + gdbpy_initialize_symtabs (); + gdbpy_initialize_blocks (); gdbpy_initialize_functions (); + gdbpy_initialize_parameters (); gdbpy_initialize_types (); + gdbpy_initialize_pspace (); gdbpy_initialize_objfile (); + gdbpy_initialize_breakpoints (); + gdbpy_initialize_lazy_string (); + gdbpy_initialize_thread (); + gdbpy_initialize_inferior (); + gdbpy_initialize_events (); PyRun_SimpleString ("import gdb"); PyRun_SimpleString ("gdb.pretty_printers = []"); - observer_attach_new_objfile (gdbpy_new_objfile); - gdbpy_to_string_cst = PyString_FromString ("to_string"); gdbpy_children_cst = PyString_FromString ("children"); gdbpy_display_hint_cst = PyString_FromString ("display_hint"); gdbpy_doc_cst = PyString_FromString ("__doc__"); + gdbpy_enabled_cst = PyString_FromString ("enabled"); + + /* Release the GIL while gdb runs. */ + PyThreadState_Swap (NULL); + PyEval_ReleaseLock (); + +#endif /* HAVE_PYTHON */ +} + +#ifdef HAVE_PYTHON + +/* Perform the remaining python initializations. + These must be done after GDB is at least mostly initialized. + E.g., The "info pretty-printer" command needs the "info" prefix + command installed. */ + +void +finish_python_initialization (void) +{ + struct cleanup *cleanup; + + cleanup = ensure_python_env (get_current_arch (), current_language); - /* Create a couple objects which are used for Python's stdout and - stderr. */ PyRun_SimpleString ("\ +import os\n\ import sys\n\ +\n\ class GdbOutputFile:\n\ def close(self):\n\ # Do nothing.\n\ @@ -593,33 +1057,73 @@ class GdbOutputFile:\n\ \n\ sys.stderr = GdbOutputFile()\n\ sys.stdout = GdbOutputFile()\n\ +\n\ +# Ideally this would live in the gdb module, but it's intentionally written\n\ +# in python, and we need this to bootstrap the gdb module.\n\ +\n\ +def GdbSetPythonDirectory (dir):\n\ + \"Set gdb.PYTHONDIR and update sys.path,etc.\"\n\ + old_dir = gdb.PYTHONDIR\n\ + gdb.PYTHONDIR = dir\n\ + # GDB's python scripts are stored inside gdb.PYTHONDIR. So insert\n\ + # that directory name at the start of sys.path to allow the Python\n\ + # interpreter to find them.\n\ + if old_dir in sys.path:\n\ + sys.path.remove (old_dir)\n\ + sys.path.insert (0, gdb.PYTHONDIR)\n\ +\n\ + # Tell python where to find submodules of gdb.\n\ + gdb.__path__ = [gdb.PYTHONDIR + '/gdb']\n\ +\n\ + # The gdb module is implemented in C rather than in Python. As a result,\n\ + # the associated __init.py__ script is not not executed by default when\n\ + # the gdb module gets imported. Execute that script manually if it\n\ + # exists.\n\ + ipy = gdb.PYTHONDIR + '/gdb/__init__.py'\n\ + if os.path.exists (ipy):\n\ + execfile (ipy)\n\ +\n\ +# Install the default gdb.PYTHONDIR.\n\ +GdbSetPythonDirectory (gdb.PYTHONDIR)\n\ "); - /* Release the GIL while gdb runs. */ - PyThreadState_Swap (NULL); - PyEval_ReleaseLock (); + do_cleanups (cleanup); +} #endif /* HAVE_PYTHON */ -} -#if HAVE_PYTHON +#ifdef HAVE_PYTHON static PyMethodDef GdbMethods[] = { { "history", gdbpy_history, METH_VARARGS, "Get a value from history" }, - { "execute", execute_gdb_command, METH_VARARGS, + { "execute", (PyCFunction) execute_gdb_command, METH_VARARGS | METH_KEYWORDS, "Execute a gdb command" }, - { "get_parameter", get_parameter, METH_VARARGS, + { "parameter", gdbpy_parameter, METH_VARARGS, "Return a gdb parameter's value" }, + { "breakpoints", gdbpy_breakpoints, METH_NOARGS, + "Return a tuple of all breakpoint objects" }, + + { "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\ +Return the newest frame object." }, { "selected_frame", gdbpy_selected_frame, METH_NOARGS, "selected_frame () -> gdb.Frame.\n\ Return the selected frame object." }, @@ -631,12 +1135,55 @@ Return a string explaining unwind stop reason." }, METH_VARARGS | METH_KEYWORDS, "lookup_type (name [, block]) -> type\n\ Return a Type corresponding to the given name." }, + { "lookup_symbol", (PyCFunction) gdbpy_lookup_symbol, + METH_VARARGS | METH_KEYWORDS, + "lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this)\n\ +Return a tuple with the symbol corresponding to the given name (or None) and\n\ +a boolean indicating if name is a field of the current implied argument\n\ +`this' (when the current language is object-oriented)." }, + { "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\ +The first element contains any unparsed portion of the String parameter\n\ +(or None if the string was fully parsed). The second element contains\n\ +a tuple that contains all the locations that match, represented as\n\ +gdb.Symtab_and_line objects (or None)."}, + { "parse_and_eval", gdbpy_parse_and_eval, METH_VARARGS, + "parse_and_eval (String) -> Value.\n\ +Parse String as an expression, evaluate it, and return the result as a Value." + }, + + { "post_event", gdbpy_post_event, METH_VARARGS, + "Post an event into gdb's event loop." }, + + { "target_charset", gdbpy_target_charset, METH_NOARGS, + "target_charset () -> string.\n\ +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." }, + + { "string_to_argv", gdbpy_string_to_argv, METH_VARARGS, + "string_to_argv (String) -> Array.\n\ +Parse String and return an argv-like array.\n\ +Arguments are separate by spaces and may be quoted." + }, { "write", gdbpy_write, METH_VARARGS, "Write a string using gdb's filtered stream." }, { "flush", gdbpy_flush, METH_NOARGS, "Flush gdb's filtered stdout stream." }, - + { "selected_thread", gdbpy_selected_thread, METH_NOARGS, + "selected_thread () -> gdb.InferiorThread.\n\ +Return the selected thread object." }, + { "inferiors", gdbpy_inferiors, METH_NOARGS, + "inferiors () -> (gdb.Inferior, ...).\n\ +Return a tuple containing all inferiors." }, {NULL, NULL, 0, NULL} };