#include <ctype.h>
-/* True if we should print the stack when catching a Python error,
- false otherwise. */
-static int gdbpy_should_print_stack = 0;
+/* Declared constants and enum for python stack printing. */
+static const char python_excp_none[] = "none";
+static const char python_excp_full[] = "full";
+static const char python_excp_message[] = "message";
+
+/* "set python print-stack" choices. */
+static const char *python_excp_enums[] =
+ {
+ python_excp_none,
+ python_excp_full,
+ python_excp_message,
+ NULL
+ };
+
+/* The exception printing variable. 'full' if we want to print the
+ error message and stack, 'none' if we want to print nothing, and
+ 'message' if we only want to print the error message. 'message' is
+ the default. */
+static const char *gdbpy_should_print_stack = python_excp_message;
#ifdef HAVE_PYTHON
ret = PyRun_SimpleString (script);
xfree (script);
if (ret)
- {
- gdbpy_print_stack ();
- error (_("Error while executing Python code."));
- }
+ error (_("Error while executing Python code."));
do_cleanups (cleanup);
}
if (arg && *arg)
{
if (PyRun_SimpleString (arg))
- {
- gdbpy_print_stack ();
- error (_("Error while executing Python code."));
- }
+ error (_("Error while executing Python code."));
}
else
{
Py_RETURN_NONE;
}
-/* Print a python exception trace, or print nothing and clear the
- python exception, depending on gdbpy_should_print_stack. Only call
- this if a python exception is set. */
+/* Print a python exception trace, print just a message, or print
+ nothing and clear the python exception, depending on
+ gdbpy_should_print_stack. Only call this if a python exception is
+ set. */
void
gdbpy_print_stack (void)
{
- if (gdbpy_should_print_stack)
+ /* Print "none", just clear exception. */
+ if (gdbpy_should_print_stack == python_excp_none)
+ {
+ PyErr_Clear ();
+ }
+ /* Print "full" message and backtrace. */
+ else if (gdbpy_should_print_stack == python_excp_full)
{
PyErr_Print ();
/* PyErr_Print doesn't necessarily end output with a newline.
printf_filtered. */
begin_line ();
}
+ /* Print "message", just error print message. */
else
- PyErr_Clear ();
+ {
+ PyObject *ptype, *pvalue, *ptraceback;
+ char *msg = NULL, *type = NULL;
+
+ PyErr_Fetch (&ptype, &pvalue, &ptraceback);
+
+ /* Fetch the error message contained within ptype, pvalue. */
+ msg = gdbpy_exception_to_string (ptype, pvalue);
+ type = gdbpy_obj_to_string (ptype);
+ if (msg == NULL)
+ {
+ /* An error occurred computing the string representation of the
+ error message. */
+ fprintf_filtered (gdb_stderr,
+ _("Error occurred computing Python error" \
+ "message.\n"));
+ }
+ else
+ fprintf_filtered (gdb_stderr, "Python Exception %s %s: \n",
+ type, msg);
+
+ Py_XDECREF (ptype);
+ Py_XDECREF (pvalue);
+ Py_XDECREF (ptraceback);
+ xfree (msg);
+ }
}
\f
\f
-/* Lists for 'maint set python' commands. */
-
-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
-maint_set_python (char *args, int from_tty)
-{
- help_list (maint_set_python_list, "maintenance set python ",
- class_deprecated, gdb_stdout);
-}
-
-/* Function for use by 'maint show python' prefix command. */
-
-static void
-maint_show_python (char *args, int from_tty)
-{
- cmd_show_list (maint_show_python_list, from_tty, "");
-}
-
/* Function for use by 'set python' prefix command. */
static void
#endif /* HAVE_PYTHON */
);
- add_prefix_cmd ("python", no_class, maint_show_python,
- _("Prefix command for python maintenance settings."),
- &maint_show_python_list, "maintenance show python ", 0,
- &maintenance_show_cmdlist);
- add_prefix_cmd ("python", no_class, maint_set_python,
- _("Prefix command for python maintenance settings."),
- &maint_set_python_list, "maintenance set python ", 0,
- &maintenance_set_cmdlist);
-
- add_setshow_boolean_cmd ("print-stack", class_maintenance,
- &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,
- &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_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);
+ add_setshow_enum_cmd ("print-stack", no_class, python_excp_enums,
+ &gdbpy_should_print_stack, _("\
+Set mode for Python stack dump on error."), _("\
+Show the mode of Python stack printing on error."), _("\
+none == no stack or message will be printed.\n\
+full == a message and a stack will be printed.\n\
+message == an error message without a stack will be printed."),
+ NULL, NULL,
+ &user_set_python_list,
+ &user_show_python_list);
#ifdef HAVE_PYTHON
#ifdef WITH_PYTHON_PATH
gdb_test "python gdb.write(\"Normal stream\\n\", stream=gdb.STDOUT)" "Normal stream" "Test stdout write"
gdb_test "python gdb.write(\"Log stream\\n\", stream=gdb.STDLOG)" "Log stream" "Test stdlog write"
-# Deprecate maint set/show python print-stack
-gdb_test "maint show python print-stack" \
- "Warning: command 'maintenance show python print-stack' is deprecated.*Use 'show python print-stack'.*" \
- "Test deprecation maint show warning."
-gdb_test "maint set python print-stack off" \
- "Warning: command 'maintenance set python print-stack' is deprecated.*Use 'set python print-stack'.*" \
- "Test deprecation maint set warning."
+# print-stack
gdb_test "show python print-stack" \
- "Whether Python stack will be printed on error is off.*" \
- "Test print-backtrace show setting. Default off."
-gdb_py_test_silent_cmd "set python print-stack on" \
+ "The mode of Python stack printing on error is \"message\".*" \
+ "Test print-backtrace show setting. Default is message."
+gdb_py_test_silent_cmd "set python print-stack full" \
"Test print-backtrace set setting" 1
gdb_test "show python print-stack" \
- "Whether Python stack will be printed on error is on.*" \
+ "The mode of Python stack printing on error is \"full\".*" \
+ "Test print-backtrace show setting to full."
# Test prompt substituion
gdb_test_multiple "set extended-prompt some param \\p{python print-stack} " \
"set extended prompt parameter" {
- -re "\[\r\n\]some param True $" {
+ -re "\[\r\n\]some param full $" {
pass "set extended prompt parameter"
}
}
+
+# Start with a fresh gdb.
+clean_restart ${testfile}
+
+# The following tests require execution.
+
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+# print-stack settings
+gdb_test "show python print-stack" \
+ "The mode of Python stack printing on error is \"message\".*" \
+ "Test print-backtrace show setting. Default is message."
+gdb_py_test_silent_cmd "set python print-stack full" \
+ "Test print-backtrace set setting" 1
+gdb_test "show python print-stack" \
+ "The mode of Python stack printing on error is \"full\".*" \
+ "Test print-backtrace show setting to full."
+gdb_py_test_silent_cmd "set python print-stack none" \
+ "Test print-backtrace set setting" 1
+gdb_test "show python print-stack" \
+ "The mode of Python stack printing on error is \"none\".*" \
+ "Test print-backtrace show setting to none."
+
+gdb_py_test_silent_cmd "set python print-stack message" \
+ "Test print-backtrace set setting" 1
+
+gdb_py_test_multiple "prompt substitution readline" \
+ "python" "" \
+ "pCounter = 0" "" \
+ "def error_prompt(current):" "" \
+ " raise RuntimeError(\"Python exception called\")" "" \
+ "end" ""
+
+gdb_test_multiple "python gdb.prompt_hook = error_prompt" "set the hook" {
+ -re "Python Exception <type 'exceptions.RuntimeError'> Python exception called.*" {
+ pass "set hook"
+ }
+}
+
+gdb_py_test_silent_cmd "python gdb.prompt_hook = None" \
+ "set the hook to default" 1
+
+gdb_py_test_silent_cmd "set python print-stack full" \
+ "Test print-backtrace set setting" 1
+
+gdb_test_multiple "python gdb.prompt_hook = error_prompt" "set the hook" {
+ -re "Traceback.*File.*line.*RuntimeError.*Python exception called.*" {
+ pass "set hook"
+ }
+}
+
+gdb_py_test_silent_cmd "python gdb.prompt_hook = None" \
+ "set the hook to default" 1