From patchwork Thu Aug 16 13:23:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gary Benson X-Patchwork-Id: 28935 Received: (qmail 120788 invoked by alias); 16 Aug 2018 13:23:12 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 120762 invoked by uid 89); 16 Aug 2018 13:23:11 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=75, batch, escaped, sk:handle_ X-HELO: mx1.redhat.com Received: from mx3-rdu2.redhat.com (HELO mx1.redhat.com) (66.187.233.73) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 16 Aug 2018 13:23:09 +0000 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4259B7A7EE for ; Thu, 16 Aug 2018 13:23:08 +0000 (UTC) Received: from blade.nx (ovpn-117-165.ams2.redhat.com [10.36.117.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id E4A967C28 for ; Thu, 16 Aug 2018 13:23:07 +0000 (UTC) Received: from blade.com (localhost [127.0.0.1]) by blade.nx (Postfix) with ESMTP id 41C3680DEC46 for ; Thu, 16 Aug 2018 14:23:07 +0100 (BST) From: Gary Benson To: gdb-patches@sourceware.org Subject: [PATCH] Indicate batch mode failures by exiting with nonzero status Date: Thu, 16 Aug 2018 14:23:03 +0100 Message-Id: <1534425783-11599-1-git-send-email-gbenson@redhat.com> X-IsSubscribed: yes Hi all, This patch causes GDB in batch mode to exit with nonzero status if the last command to be executed fails. Built and regtested on RHEL 7.5 x86_64. Ok to commit? Thanks, Gary --- gdb/ChangeLog: PR gdb/13000: * gdb/main.c (last_command_failed): New static global. (handle_command_errors): Set the above on error. (catch_command_errors): Clear the above before commands. (captured_main_1): Exit with nonzero status in batch mode if the last command to be executed failed. * NEWS: Mention the above. gdb/testsuite/ChangeLog: PR gdb/13000: * gdb.base/batch-exit-status.exp: New file. * gdb.base/batch-exit-status.good-commands: Likewise. * gdb.base/batch-exit-status.bad-commands: Likewise. --- gdb/ChangeLog | 10 ++++ gdb/NEWS | 3 ++ gdb/main.c | 13 ++++- gdb/testsuite/ChangeLog | 7 +++ .../gdb.base/batch-exit-status.bad-commands | 1 + gdb/testsuite/gdb.base/batch-exit-status.exp | 63 ++++++++++++++++++++++ .../gdb.base/batch-exit-status.good-commands | 1 + 7 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 gdb/testsuite/gdb.base/batch-exit-status.bad-commands create mode 100644 gdb/testsuite/gdb.base/batch-exit-status.exp create mode 100644 gdb/testsuite/gdb.base/batch-exit-status.good-commands diff --git a/gdb/NEWS b/gdb/NEWS index 16d3d72..6af712a 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -10,6 +10,9 @@ * DWARF index cache: GDB can now automatically save indices of DWARF symbols on disk to speed up further loading of the same binaries. +* GDB in batch mode now exits with status 1 if the last command to be + executed failed. + * New commands frame apply [all | COUNT | -COUNT | level LEVEL...] [FLAG]... COMMAND diff --git a/gdb/main.c b/gdb/main.c index e925128..31a6ee0 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -343,6 +343,10 @@ captured_command_loop () quit_command (NULL, ui->instream == ui->stdin_stream); } +/* Did the last invocation of catch_command_errors throw an error? */ + +static bool last_command_failed = false; + /* Handle command errors thrown from within catch_command_errors. */ static int @@ -350,6 +354,8 @@ handle_command_errors (struct gdb_exception e) { if (e.reason < 0) { + last_command_failed = true; + exception_print (gdb_stderr, e); /* If any exception escaped to here, we better enable stdin. @@ -372,6 +378,8 @@ static int catch_command_errors (catch_command_errors_const_ftype command, const char *arg, int from_tty) { + last_command_failed = false; + TRY { int was_sync = current_ui->prompt_state == PROMPT_BLOCKED; @@ -1134,8 +1142,11 @@ captured_main_1 (struct captured_main_args *context) if (batch_flag) { + int error_status = EXIT_FAILURE; + int *exit_arg = last_command_failed ? &error_status : NULL; + /* We have hit the end of the batch file. */ - quit_force (NULL, 0); + quit_force (exit_arg, 0); } } diff --git a/gdb/testsuite/gdb.base/batch-exit-status.bad-commands b/gdb/testsuite/gdb.base/batch-exit-status.bad-commands new file mode 100644 index 0000000..4793acb --- /dev/null +++ b/gdb/testsuite/gdb.base/batch-exit-status.bad-commands @@ -0,0 +1 @@ +bork diff --git a/gdb/testsuite/gdb.base/batch-exit-status.exp b/gdb/testsuite/gdb.base/batch-exit-status.exp new file mode 100644 index 0000000..bee4d72 --- /dev/null +++ b/gdb/testsuite/gdb.base/batch-exit-status.exp @@ -0,0 +1,63 @@ +# Copyright (C) 2018 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Check that "gdb -batch" exits with appropriate status. + +standard_testfile + +set good_commands "$srcdir/$subdir/batch-exit-status.good-commands" +set bad_commands "$srcdir/$subdir/batch-exit-status.bad-commands" + +proc _test_exit_status {expect_status cmdline_opts} { + global gdb_spawn_id + + gdb_exit + if {[gdb_spawn_with_cmdline_opts $cmdline_opts] != 0} { + fail "spawn" + return + } + + set result [wait -i $gdb_spawn_id] + verbose $result + gdb_assert { [lindex $result 2] == 0 } + set actual_status [lindex $result 3] + gdb_assert { $actual_status == $expect_status } +} + +proc test_exit_status {expect_status cmdline_opts} { + with_test_prefix $cmdline_opts { + _test_exit_status $expect_status $cmdline_opts + } +} + +# gdb -batch with nothing to do should exit 0. +test_exit_status 0 "-batch" + +# Bad command-line options should cause exit 1. +test_exit_status 1 "-batch -jslkflsdjlkfjlksdjf" + +# gdb -batch with good commands should exit 0. +test_exit_status 0 "-batch -ex \"info source\"" +test_exit_status 0 "-batch -x $good_commands" + +# gdb -batch with bad commands should exit 1. +test_exit_status 1 "-batch -ex \"set not-a-thing 4\"" +test_exit_status 1 "-batch -x $bad_commands" + +# Success or failure of the last thing determines the exit code. +test_exit_status 0 "-batch -ex \"set not-a-thing 4\" -x $good_commands" +test_exit_status 0 "-batch -x $bad_commands -ex \"info source\"" +test_exit_status 1 "-batch -x $good_commands -x $bad_commands" +test_exit_status 1 "-batch -x $good_commands -ex \"set not-a-thing 4\"" diff --git a/gdb/testsuite/gdb.base/batch-exit-status.good-commands b/gdb/testsuite/gdb.base/batch-exit-status.good-commands new file mode 100644 index 0000000..80708a9 --- /dev/null +++ b/gdb/testsuite/gdb.base/batch-exit-status.good-commands @@ -0,0 +1 @@ +info mem