From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12165 invoked by alias); 9 Nov 2011 15:36:23 -0000 Received: (qmail 11932 invoked by uid 22791); 9 Nov 2011 15:36:20 -0000 X-SWARE-Spam-Status: No, hits=-6.4 required=5.0 tests=AWL,BAYES_05,RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,SPF_HELO_PASS,TW_DB X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 09 Nov 2011 15:36:01 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id pA9Fa0QI002583 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 9 Nov 2011 10:36:00 -0500 Received: from localhost.localdomain (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id pA9FZxEK010893 for ; Wed, 9 Nov 2011 10:36:00 -0500 From: Phil Muldoon To: gdb-patches@sourceware.org Subject: [python] [patch] PR python/13329 Reply-to: pmuldoon@redhat.com X-URL: http://www.redhat.com Date: Wed, 09 Nov 2011 15:36:00 -0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-11/txt/msg00228.txt.bz2 This patch changes the behavior of 'python stack-print' to three modes: full, message or none. The default has been set to "message". full - will print the exception message and the stack. message - will print the exception type and message only. none - nothing will be printed. This patch also fixes a bug where we were calling gdbpy_print_stack after a few PyRun_SimpleString calls. This is not necessary as that API deals with the exception internally and prints its own stack. This is backwards compatible with the deprecated maint set python print-sack. on - will set the mode to "full". off - will set the mode to "none". Tested with no regressions. Cheers, Phil -- 2011-11-09 Phil Muldoon PR python/13329 * python/python.c: Declare python_excp_none, python_excp_full, python_excp_message, python_excp_enums (set_python_excp_mode): New function. (_initialize_python): Set 'print-stack' command to an enum accepting command. (gdbpy_print_stack): Rewrite. (eval_python_from_control_command): Do not call gdbpy_print_stack. (python_command): Ditto. * NEWS: Update 'print-stack' text. 2011-11-09 Phil Muldoon PR python/13329 * gdb.texinfo (Python Commands): Update 'print-stack' to reflect the three values it can now take. 2011-11-09 Phil Muldoon PR python/13329 * gdb.python/py-function.exp: Set python print-stack "on" to "full. * gdb.python/python.exp: Ditto. -- diff --git a/gdb/NEWS b/gdb/NEWS index 1713049..ecf6849 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -23,9 +23,10 @@ existing one. ** The "maint set python print-stack on|off" command has been - deprecated, and a new command: "set python print-stack on|off" has - replaced it. Additionally, the default for "print-stack" is now - "off". + deprecated, and a new command: "set python print-stack + none|full|message" has replaced it. Additionally, the default + for "print-stack" is now "message", which just prints the error + message without the stack trace. ** A prompt substitution hook (prompt_hook) is now available to the Python API. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index d2bdefa..dc5daa9 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -21348,11 +21348,12 @@ print-stack} @kindex set python print-stack @item set python print-stack -By default, @value{GDBN} will not print a stack trace when an error -occurs in a Python script. This can be controlled using @code{set -python print-stack}: if @code{on}, then Python stack printing is -enabled; if @code{off}, the default, then Python stack printing is -disabled. +By default, @value{GDBN} will print only the message component of a +Python exception when an error occurs in a Python script. This can be +controlled using @code{set python print-stack}: if @code{full}, then +full Python stack printing is enabled; if @code{none}, then Python stack +and message printing is disabled; if @code{message}, the default, only +the message component of the error is printed. @end table It is also possible to execute a Python script from the @value{GDBN} diff --git a/gdb/python/python.c b/gdb/python/python.c index 108e542..93a80c6 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -35,9 +35,29 @@ #include -/* 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 +}; + +/* 0 if we should not print the stack when catching a Python error, + 1 to print the full stack, 2 to just print the message. */ +static int gdbpy_should_print_stack = 2; + +/* The extended 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. */ +static const char *gdbpy_should_print_stack_extended = + python_excp_message; #ifdef HAVE_PYTHON @@ -233,10 +253,7 @@ eval_python_from_control_command (struct command_line *cmd) 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); } @@ -258,10 +275,7 @@ python_command (char *arg, int from_tty) if (arg && *arg) { if (PyRun_SimpleString (arg)) - { - gdbpy_print_stack (); - error (_("Error while executing Python code.")); - } + error (_("Error while executing Python code.")); } else { @@ -881,22 +895,57 @@ gdbpy_flush (PyObject *self, PyObject *args, PyObject *kw) 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) + switch (gdbpy_should_print_stack) { + PyObject *ptype, *pvalue, *ptraceback; + char *msg = NULL, *type = NULL; + + case 0: + /* Print "none", just clear exception. */ + PyErr_Clear (); + break; + + case 1: + /* Print "full" message and backtrace. */ 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 (); + break; + + case 2: + /* Print "message", just error print message. */ + 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); + break; } - else - PyErr_Clear (); } @@ -1106,6 +1155,21 @@ user_show_python (char *args, int from_tty) cmd_show_list (user_show_python_list, from_tty, ""); } +/* When setting the 'python print-stack' with an enum, set the + gdbpy_should_print_stack correspondingly. */ +static void +set_python_excp_mode (char *args, int i, struct cmd_list_element *c) +{ + const char *user_arg = *(const char **) c->var; + + if (strncmp (user_arg, python_excp_none, 4) == 0) + gdbpy_should_print_stack = 0; + else if (strncmp (user_arg, python_excp_full, 3) == 0) + gdbpy_should_print_stack = 1; + else if (strncmp (user_arg, python_excp_message, 7) == 0) + gdbpy_should_print_stack = 2; +} + /* Initialize the Python code. */ /* Provide a prototype to silence -Wmissing-prototypes. */ @@ -1176,14 +1240,16 @@ Enables or disables printing of Python stack traces."), &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_extended, _("\ +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."), + set_python_excp_mode, NULL, + &user_set_python_list, + &user_show_python_list); #ifdef HAVE_PYTHON #ifdef WITH_PYTHON_PATH diff --git a/gdb/testsuite/gdb.python/py-function.exp b/gdb/testsuite/gdb.python/py-function.exp index d579435..f670d52 100644 --- a/gdb/testsuite/gdb.python/py-function.exp +++ b/gdb/testsuite/gdb.python/py-function.exp @@ -93,7 +93,7 @@ gdb_py_test_multiple "Test Normal Error" \ "NormalError ()" "" \ "end" "" -gdb_test_no_output "set python print-stack on" +gdb_test_no_output "set python print-stack full" gdb_test "print \$normalerror()" "Traceback.*File.*line 5.*in invoke.*RuntimeError.*This is a Normal Error.*" \ "Test a Runtime error. There should be a stack trace." diff --git a/gdb/testsuite/gdb.python/py-prettyprint.exp b/gdb/testsuite/gdb.python/py-prettyprint.exp index b0e7d62..9786d71 100644 --- a/gdb/testsuite/gdb.python/py-prettyprint.exp +++ b/gdb/testsuite/gdb.python/py-prettyprint.exp @@ -97,7 +97,7 @@ proc run_lang_tests {exefile lang} { gdb_test_no_output "python pp_ls_encoding = 'UTF-8'" gdb_test "print estring2" "\"embedded \", " - gdb_test_no_output "set python print-stack on" + gdb_test_no_output "set python print-stack full" gdb_test "print hint_error" "Exception: hint failed\r\nhint_error_val" gdb_test "print c" " = container \"container\" with 2 elements = {$nl *.0. = 23,$nl *.1. = 72$nl}" diff --git a/gdb/testsuite/gdb.python/python.exp b/gdb/testsuite/gdb.python/python.exp index 94d6d0d..2062d00 100644 --- a/gdb/testsuite/gdb.python/python.exp +++ b/gdb/testsuite/gdb.python/python.exp @@ -203,12 +203,13 @@ 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." gdb_test "show python print-stack" \ - "Whether Python stack will be printed on error is off.*" \ + "The mode of Python stack printing on error is \"message\".*" \ "Test print-backtrace show setting. Default off." -gdb_py_test_silent_cmd "set python print-stack on" \ +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 @@ -313,7 +314,7 @@ gdb_test_multiple "set extended-prompt \\w " \ 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" } }