X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fpython%2Fpython.c;h=3a5a6b5b2dabe93182896ca71b93d253246730fa;hb=d234ef5c0cca9ae4737cfcd833555db14dc0ead0;hp=77a00693ea38eda4fa0a4a89c369d13747fb781d;hpb=86c6265d62c78d255c648eb33242ed74ec58772d;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/python/python.c b/gdb/python/python.c index 77a00693ea..3a5a6b5b2d 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. @@ -23,33 +23,36 @@ #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 "python.h" #include /* True if we should print the stack when catching a Python error, 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; +static int gdbpy_should_print_stack = 0; #ifdef HAVE_PYTHON -#include "python.h" #include "libiberty.h" #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" +#include "observer.h" +#include "interps.h" static PyMethodDef GdbMethods[]; @@ -60,7 +63,17 @@ PyObject *gdbpy_to_string_cst; PyObject *gdbpy_children_cst; PyObject *gdbpy_display_hint_cst; PyObject *gdbpy_doc_cst; +PyObject *gdbpy_enabled_cst; +PyObject *gdbpy_value_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. */ @@ -75,12 +88,24 @@ 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; @@ -103,9 +128,51 @@ ensure_python_env (struct gdbarch *gdbarch, 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); } +/* A wrapper around PyRun_SimpleFile. FILENAME is the name of + the Python script to run. + + One of the parameters of PyRun_SimpleFile is a FILE *. + The problem is that type FILE is extremely system and compiler + dependent. So, unless the Python library has been compiled using + the same build environment as GDB, we run the risk of getting + a crash due to inconsistencies between the definition used by GDB, + and the definition used by Python. A mismatch can very likely + lead to a crash. + + There is also the situation where the Python library and GDB + are using two different versions of the C runtime library. + This is particularly visible on Windows, where few users would + build Python themselves (this is no trivial task on this platform), + and thus use binaries built by someone else instead. Python, + being built with VC, would use one version of the msvcr DLL + (Eg. msvcr100.dll), while MinGW uses msvcrt.dll. A FILE * + from one runtime does not necessarily operate correctly in + the other runtime. + + To work around this potential issue, we create the FILE object + using Python routines, thus making sure that it is compatible + with the Python library. */ + +static void +python_run_simple_file (const char *filename) +{ + char *filename_copy; + PyObject *python_file; + struct cleanup *cleanup; + + filename_copy = xstrdup (filename); + cleanup = make_cleanup (xfree, filename_copy); + python_file = PyFile_FromString (filename_copy, "r"); + make_cleanup_py_decref (python_file); + PyRun_SimpleFile (PyFile_AsFile (python_file), filename); + do_cleanups (cleanup); +} /* Given a command_line, return a command string suitable for passing to Python. Lines in the string are separated by newlines. The @@ -128,6 +195,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'; @@ -169,8 +237,12 @@ static void python_command (char *arg, int from_tty) { struct cleanup *cleanup; + cleanup = ensure_python_env (get_current_arch (), current_language); + make_cleanup_restore_integer (&interpreter_async); + interpreter_async = 0; + while (arg && *arg && isspace (*arg)) ++arg; if (arg && *arg) @@ -184,6 +256,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); } @@ -196,11 +269,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: @@ -208,7 +280,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); @@ -216,7 +289,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; @@ -224,7 +297,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) @@ -234,32 +308,35 @@ 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 * +PyObject * gdbpy_parameter (PyObject *self, PyObject *args) { struct cmd_list_element *alias, *prefix, *cmd; - char *arg, *newarg; + const char *arg; + char *newarg; int found = -1; volatile struct gdb_exception except; @@ -276,43 +353,87 @@ gdbpy_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 parameter", 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; + 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_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) { /* Copy the argument text in case the command modifies it. */ char *copy = xstrdup (arg); struct cleanup *cleanup = make_cleanup (xfree, copy); - execute_command (copy, from_tty); + + make_cleanup_restore_integer (&interpreter_async); + interpreter_async = 0; + + prevent_dont_repeat (); + 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); @@ -320,30 +441,433 @@ execute_gdb_command (PyObject *self, PyObject *args) /* 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; + gdb_py_longest pc; + + if (!PyArg_ParseTuple (args, GDB_PY_LL_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); + 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; + const 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) + { + copy = xstrdup (arg); + make_cleanup (xfree, copy); + sals = decode_line_1 (©, 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) +{ + 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) + { + char *copy = xstrdup (expr_str); + struct cleanup *cleanup = make_cleanup (xfree, copy); + + result = parse_and_eval (copy); + do_cleanups (cleanup); + } + GDB_PY_HANDLE_EXCEPTION (except); + + return value_to_value_object (result); +} + +/* Read a file as Python code. + FILE is the name of the file. + This does not throw any errors. If an exception occurs python will print + the traceback and clear the error indicator. */ + +void +source_python_script (const char *file) +{ + struct cleanup *cleanup; + + cleanup = ensure_python_env (get_current_arch (), current_language); + python_run_simple_file (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); + } +} + + + +static void +before_prompt_hook (const char *current_gdb_prompt) +{ + struct cleanup *cleanup; + char *prompt = NULL; + + cleanup = ensure_python_env (get_current_arch (), current_language); + + if (PyObject_HasAttrString (gdb_module, "prompt_hook")) + { + PyObject *hook; + + hook = PyObject_GetAttrString (gdb_module, "prompt_hook"); + if (hook == NULL) + goto fail; + + if (PyCallable_Check (hook)) + { + PyObject *result; + PyObject *current_prompt; + + current_prompt = PyString_FromString (current_gdb_prompt); + if (current_prompt == NULL) + goto fail; + + result = PyObject_CallFunctionObjArgs (hook, current_prompt, NULL); + + Py_DECREF (current_prompt); + + if (result == NULL) + goto fail; + + make_cleanup_py_decref (result); + + /* Return type should be None, or a String. If it is None, + fall through, we will not set a prompt. If it is a + string, set PROMPT. Anything else, set an exception. */ + if (result != Py_None && ! PyString_Check (result)) + { + PyErr_Format (PyExc_RuntimeError, + _("Return from prompt_hook must " \ + "be either a Python string, or None")); + goto fail; + } + + if (result != Py_None) + { + prompt = python_string_to_host_string (result); + + 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); + + do_cleanups (cleanup); + return; + + fail: + gdbpy_print_stack (); + do_cleanups (cleanup); + return; +} + /* Printing. */ /* A python function to write a single string using gdb's filtered - output stream. */ + output stream . The optional keyword STREAM can be used to write + to a particular stream. The default stream is to gdb_stdout. */ + static PyObject * -gdbpy_write (PyObject *self, PyObject *args) +gdbpy_write (PyObject *self, PyObject *args, PyObject *kw) { - char *arg; - if (! PyArg_ParseTuple (args, "s", &arg)) + const char *arg; + static char *keywords[] = {"text", "stream", NULL }; + int stream_type = 0; + + if (! PyArg_ParseTupleAndKeywords (args, kw, "s|i", keywords, &arg, + &stream_type)) return NULL; - printf_filtered ("%s", arg); + + switch (stream_type) + { + case 1: + { + fprintf_filtered (gdb_stderr, "%s", arg); + break; + } + case 2: + { + fprintf_filtered (gdb_stdlog, "%s", arg); + break; + } + default: + fprintf_filtered (gdb_stdout, "%s", arg); + } + Py_RETURN_NONE; } -/* A python function to flush gdb's filtered output stream. */ +/* A python function to flush a gdb stream. The optional keyword + STREAM can be used to flush a particular stream. The default stream + is gdb_stdout. */ + static PyObject * -gdbpy_flush (PyObject *self, PyObject *args) +gdbpy_flush (PyObject *self, PyObject *args, PyObject *kw) { - gdb_flush (gdb_stdout); + static char *keywords[] = {"stream", NULL }; + int stream_type = 0; + + if (! PyArg_ParseTupleAndKeywords (args, kw, "|i", keywords, + &stream_type)) + return NULL; + + switch (stream_type) + { + case 1: + { + gdb_flush (gdb_stderr); + break; + } + case 2: + { + gdb_flush (gdb_stdlog); + break; + } + default: + gdb_flush (gdb_stdout); + } + Py_RETURN_NONE; } @@ -354,93 +878,86 @@ 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. */ + +static PyObject * +gdbpy_get_current_progspace (PyObject *unused1, PyObject *unused2) +{ + PyObject *result; -/* The file name we attempt to read. */ -#define GDBPY_AUTO_FILENAME "-gdb.py" + result = pspace_to_pspace_object (current_program_space); + if (result) + Py_INCREF (result); + return 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) +/* Return a sequence holding all the Progspaces. */ + +static PyObject * +gdbpy_progspaces (PyObject *unused1, PyObject *unused2) { - char *realname; - char *filename, *debugfile; - int len; - FILE *input; - 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; - cleanups = ensure_python_env (get_objfile_arch (objfile), current_language); + 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; + - 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 FILE as Python code. + This does not throw any errors. If an exception occurs python will print + the traceback and clear the error indicator. */ - 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, 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; + + python_run_simple_file (file); do_cleanups (cleanups); gdbpy_current_objfile = NULL; } /* Return the current Objfile, or None if there isn't one. */ + static PyObject * gdbpy_get_current_objfile (PyObject *unused1, PyObject *unused2) { @@ -456,6 +973,7 @@ gdbpy_get_current_objfile (PyObject *unused1, PyObject *unused2) } /* Return a sequence holding all the Objfiles. */ + static PyObject * gdbpy_objfiles (PyObject *unused1, PyObject *unused2) { @@ -469,6 +987,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); @@ -494,6 +1013,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); } @@ -505,29 +1025,75 @@ eval_python_from_control_command (struct command_line *cmd) error (_("Python scripting is not supported in this copy of GDB.")); } +void +source_python_script (const char *file) +{ + throw_error (UNSUPPORTED_ERROR, + _("Python scripting is not supported in this copy of GDB.")); +} + +int +gdbpy_should_stop (struct breakpoint_object *bp_obj) +{ + internal_error (__FILE__, __LINE__, + _("gdbpy_should_stop called when Python scripting is " \ + "not supported.")); +} + +int +gdbpy_breakpoint_has_py_cond (struct breakpoint_object *bp_obj) +{ + internal_error (__FILE__, __LINE__, + _("gdbpy_breakpoint_has_py_cond called when Python " \ + "scripting is not supported.")); +} + #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; +static struct cmd_list_element *maint_set_python_list; +static struct cmd_list_element *maint_show_python_list; + +/* Lists for 'set python' commands. */ + +static struct cmd_list_element *user_set_python_list; +static struct cmd_list_element *user_show_python_list; /* Function for use by 'maint set python' prefix command. */ static void -set_python (char *args, int from_tty) +maint_set_python (char *args, int from_tty) { - help_list (set_python_list, "maintenance set python ", -1, gdb_stdout); + help_list (maint_set_python_list, "maintenance set python ", + class_deprecated, gdb_stdout); } /* Function for use by 'maint show python' prefix command. */ static void -show_python (char *args, int from_tty) +maint_show_python (char *args, int from_tty) { - cmd_show_list (show_python_list, from_tty, ""); + cmd_show_list (maint_show_python_list, from_tty, ""); +} + +/* Function for use by 'set python' prefix command. */ + +static void +user_set_python (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) +{ + cmd_show_list (user_show_python_list, from_tty, ""); } /* Initialize the Python code. */ @@ -538,6 +1104,9 @@ extern initialize_file_ftype _initialize_python; void _initialize_python (void) { + char *cmd_name; + struct cmd_list_element *cmd; + add_com ("python", class_obscure, python_command, #ifdef HAVE_PYTHON _("\ @@ -559,13 +1128,13 @@ This command is only a placeholder.") #endif /* HAVE_PYTHON */ ); - add_prefix_cmd ("python", no_class, show_python, + add_prefix_cmd ("python", no_class, maint_show_python, _("Prefix command for python maintenance settings."), - &show_python_list, "maintenance show python ", 0, + &maint_show_python_list, "maintenance show python ", 0, &maintenance_show_cmdlist); - add_prefix_cmd ("python", no_class, set_python, + add_prefix_cmd ("python", no_class, maint_set_python, _("Prefix command for python maintenance settings."), - &set_python_list, "maintenance set python ", 0, + &maint_set_python_list, "maintenance set python ", 0, &maintenance_set_cmdlist); add_setshow_boolean_cmd ("print-stack", class_maintenance, @@ -574,19 +1143,50 @@ Enable or disable printing of Python stack dump on error."), _("\ Show whether Python stack will be printed on error."), _("\ Enables or disables printing of Python stack traces."), NULL, NULL, - &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."), + &maint_set_python_list, + &maint_show_python_list); + + /* Deprecate maint set/show python print-stack in favour of + non-maintenance alternatives. */ + cmd_name = "print-stack"; + cmd = lookup_cmd (&cmd_name, maint_set_python_list, "", -1, 0); + deprecate_cmd (cmd, "set python print-stack"); + cmd_name = "print-stack"; /* Reset name. */ + cmd = lookup_cmd (&cmd_name, maint_show_python_list, "", -1, 0); + deprecate_cmd (cmd, "show python print-stack"); + + /* Add set/show python print-stack. */ + add_prefix_cmd ("python", no_class, user_show_python, + _("Prefix command for python preference settings."), + &user_show_python_list, "show python ", 0, + &showlist); + + add_prefix_cmd ("python", no_class, user_set_python, + _("Prefix command for python preference settings."), + &user_set_python_list, "set python ", 0, + &setlist); + + add_setshow_boolean_cmd ("print-stack", no_class, + &gdbpy_should_print_stack, _("\ +Enable or disable printing of Python stack dump on error."), _("\ +Show whether Python stack will be printed on error."), _("\ +Enables or disables printing of Python stack traces."), NULL, NULL, - &set_python_list, - &show_python_list); + &user_set_python_list, + &user_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 (); @@ -595,29 +1195,101 @@ 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); + + /* Add stream constants. */ + PyModule_AddIntConstant (gdb_module, "STDOUT", 0); + PyModule_AddIntConstant (gdb_module, "STDERR", 1); + PyModule_AddIntConstant (gdb_module, "STDLOG", 2); + + /* 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 (); + + gdbpy_initialize_eventregistry (); + gdbpy_initialize_py_events (); + gdbpy_initialize_event (); + gdbpy_initialize_stop_event (); + gdbpy_initialize_signal_event (); + gdbpy_initialize_breakpoint_event (); + gdbpy_initialize_continue_event (); + gdbpy_initialize_exited_event (); + gdbpy_initialize_thread_event (); + gdbpy_initialize_new_objfile_event () ; + + observer_attach_before_prompt (before_prompt_hook); 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"); + gdbpy_value_cst = PyString_FromString ("value"); + + /* 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\ @@ -627,7 +1299,7 @@ class GdbOutputFile:\n\ return False\n\ \n\ def write(self, s):\n\ - gdb.write(s)\n\ + gdb.write(s, stream=gdb.STDOUT)\n \ \n\ def writelines(self, iterable):\n\ for line in iterable:\n\ @@ -636,38 +1308,96 @@ class GdbOutputFile:\n\ def flush(self):\n\ gdb.flush()\n\ \n\ -sys.stderr = GdbOutputFile()\n\ sys.stdout = GdbOutputFile()\n\ +\n\ +class GdbOutputErrorFile:\n\ + def close(self):\n\ + # Do nothing.\n\ + return None\n\ +\n\ + def isatty(self):\n\ + return False\n\ +\n\ + def write(self, s):\n\ + gdb.write(s, stream=gdb.STDERR)\n \ +\n\ + def writelines(self, iterable):\n\ + for line in iterable:\n\ + self.write(line)\n \ +\n\ + def flush(self):\n\ + gdb.flush()\n\ +\n\ +sys.stderr = GdbOutputErrorFile()\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__ = [os.path.join (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 = os.path.join (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\ +# Default prompt hook does nothing.\n\ +prompt_hook = None\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" }, { "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." }, @@ -679,12 +1409,61 @@ 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." }, - - { "write", gdbpy_write, METH_VARARGS, + { "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)." }, + { "lookup_global_symbol", (PyCFunction) gdbpy_lookup_global_symbol, + METH_VARARGS | METH_KEYWORDS, + "lookup_global_symbol (name [, domain]) -> symbol\n\ +Return the symbol corresponding to the given name (or None)." }, + { "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", (PyCFunction)gdbpy_write, METH_VARARGS | METH_KEYWORDS, "Write a string using gdb's filtered stream." }, - { "flush", gdbpy_flush, METH_NOARGS, + { "flush", (PyCFunction)gdbpy_flush, METH_VARARGS | METH_KEYWORDS, "Flush gdb's filtered stdout stream." }, - + { "selected_thread", gdbpy_selected_thread, METH_NOARGS, + "selected_thread () -> gdb.InferiorThread.\n\ +Return the selected thread object." }, + { "selected_inferior", gdbpy_selected_inferior, METH_NOARGS, + "selected_inferior () -> gdb.Inferior.\n\ +Return the selected inferior object." }, + { "inferiors", gdbpy_inferiors, METH_NOARGS, + "inferiors () -> (gdb.Inferior, ...).\n\ +Return a tuple containing all inferiors." }, {NULL, NULL, 0, NULL} };