X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fpython%2Fpython.c;h=3a5a6b5b2dabe93182896ca71b93d253246730fa;hb=d234ef5c0cca9ae4737cfcd833555db14dc0ead0;hp=d4f8c3dfd1194755d10efb4abcdf9efbd86367b8;hpb=9dea9163560f26f9adddd13254ad32f4aea3b1d6;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/python/python.c b/gdb/python/python.c index d4f8c3dfd1..3a5a6b5b2d 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -1,6 +1,6 @@ /* General python/gdb code - Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GDB. @@ -30,16 +30,16 @@ #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; +static int gdbpy_should_print_stack = 0; #ifdef HAVE_PYTHON -#include "python.h" #include "libiberty.h" #include "cli/cli-decode.h" #include "charset.h" @@ -51,6 +51,8 @@ static int gdbpy_should_print_stack = 1; #include "version.h" #include "target.h" #include "gdbthread.h" +#include "observer.h" +#include "interps.h" static PyMethodDef GdbMethods[]; @@ -62,10 +64,17 @@ 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. */ struct gdbarch *python_gdbarch; @@ -125,6 +134,45 @@ ensure_python_env (struct gdbarch *gdbarch, 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 @@ -191,6 +239,10 @@ 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) @@ -283,7 +335,8 @@ 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; @@ -333,7 +386,7 @@ gdbpy_target_wide_charset (PyObject *self, PyObject *args) static PyObject * execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) { - char *arg; + const char *arg; PyObject *from_tty_obj = NULL, *to_string_obj = NULL; int from_tty, to_string; volatile struct gdb_exception except; @@ -369,6 +422,10 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) char *copy = xstrdup (arg); struct cleanup *cleanup = make_cleanup (xfree, copy); + make_cleanup_restore_integer (&interpreter_async); + interpreter_async = 0; + + prevent_dont_repeat (); if (to_string) result = execute_command_to_string (copy, from_tty); else @@ -401,16 +458,9 @@ 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 + gdb_py_longest pc; - if (!PyArg_ParseTuple (args, format, &pc)) + if (!PyArg_ParseTuple (args, GDB_PY_LL_ARG, &pc)) return NULL; soname = solib_name_from_address (current_program_space, pc); @@ -430,9 +480,10 @@ gdbpy_solib_name (PyObject *self, PyObject *args) static PyObject * gdbpy_decode_line (PyObject *self, PyObject *args) { - struct symtabs_and_lines sals = { NULL, 0 }; /* Initialize to appease gcc. */ + struct symtabs_and_lines sals = { NULL, 0 }; /* Initialize to + appease gcc. */ struct symtab_and_line sal; - char *arg = NULL; + const char *arg = NULL; char *copy = NULL; struct cleanup *cleanups; PyObject *result = NULL; @@ -449,10 +500,9 @@ gdbpy_decode_line (PyObject *self, PyObject *args) { if (arg) { - arg = xstrdup (arg); - make_cleanup (xfree, arg); - copy = arg; - sals = decode_line_1 (©, 0, 0, 0, 0, 0); + copy = xstrdup (arg); + make_cleanup (xfree, copy); + sals = decode_line_1 (©, 0, 0, 0, 0); make_cleanup (xfree, sals.sals); } else @@ -529,7 +579,7 @@ gdbpy_decode_line (PyObject *self, PyObject *args) static PyObject * gdbpy_parse_and_eval (PyObject *self, PyObject *args) { - char *expr_str; + const char *expr_str; struct value *result = NULL; volatile struct gdb_exception except; @@ -538,28 +588,29 @@ gdbpy_parse_and_eval (PyObject *self, PyObject *args) TRY_CATCH (except, RETURN_MASK_ALL) { - result = parse_and_eval (expr_str); + 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. STREAM is the input file; FILE is the - name of the file. - STREAM is not closed, that is the caller's responsibility. */ +/* 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 (FILE *stream, const char *file) +source_python_script (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); - + python_run_simple_file (file); do_cleanups (cleanup); } @@ -676,26 +727,147 @@ gdbpy_initialize_events (void) } } + + +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; } @@ -766,21 +938,19 @@ gdbpy_progspaces (PyObject *unused1, PyObject *unused2) source_python_script_for_objfile; it is NULL at other times. */ static struct objfile *gdbpy_current_objfile; -/* Set the current objfile to OBJFILE and then read STREAM,FILE as - Python code. */ +/* 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. */ void -source_python_script_for_objfile (struct objfile *objfile, - FILE *stream, const char *file) +source_python_script_for_objfile (struct objfile *objfile, const char *file) { struct cleanup *cleanups; 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); + python_run_simple_file (file); do_cleanups (cleanups); gdbpy_current_objfile = NULL; @@ -856,35 +1026,74 @@ eval_python_from_control_command (struct command_line *cmd) } void -source_python_script (FILE *stream, const char *file) +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. */ -struct cmd_list_element *set_python_list; -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. */ @@ -895,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 _("\ @@ -916,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, @@ -931,8 +1143,37 @@ 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); + &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, + &user_set_python_list, + &user_show_python_list); #ifdef HAVE_PYTHON #ifdef WITH_PYTHON_PATH @@ -954,8 +1195,14 @@ Enables or disables printing of Python stack traces."), /* 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. */ @@ -967,6 +1214,13 @@ Enables or disables printing of Python stack traces."), 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); @@ -988,6 +1242,19 @@ Enables or disables printing of Python stack traces."), 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 = []"); @@ -996,6 +1263,7 @@ Enables or disables printing of Python stack traces."), 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); @@ -1031,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\ @@ -1040,9 +1308,28 @@ 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\ @@ -1058,18 +1345,20 @@ def GdbSetPythonDirectory (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\ + 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 = gdb.PYTHONDIR + '/gdb/__init__.py'\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\ "); do_cleanups (cleanup); @@ -1106,6 +1395,9 @@ static PyMethodDef GdbMethods[] = { "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." }, @@ -1123,6 +1415,10 @@ Return a Type corresponding to the given name." }, 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, @@ -1155,14 +1451,16 @@ Return the name of the current target wide charset." }, Parse String and return an argv-like array.\n\ Arguments are separate by spaces and may be quoted." }, - - { "write", gdbpy_write, METH_VARARGS, + { "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." },