From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14770 invoked by alias); 12 Oct 2017 22:11:23 -0000 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 Received: (qmail 14760 invoked by uid 89); 12 Oct 2017 22:11:23 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.9 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: smtp.polymtl.ca Received: from smtp.polymtl.ca (HELO smtp.polymtl.ca) (132.207.4.11) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 12 Oct 2017 22:11:21 +0000 Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id v9CMBE1J022142 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 12 Oct 2017 18:11:19 -0400 Received: by simark.ca (Postfix, from userid 112) id 85E441E541; Thu, 12 Oct 2017 18:11:14 -0400 (EDT) Received: from simark.ca (localhost [127.0.0.1]) by simark.ca (Postfix) with ESMTP id 8BC021E517; Thu, 12 Oct 2017 18:11:02 -0400 (EDT) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII; format=flowed Content-Transfer-Encoding: 7bit Date: Thu, 12 Oct 2017 22:11:00 -0000 From: Simon Marchi To: Pedro Alves Cc: gdb-patches@sourceware.org Subject: Re: [PATCH] Add several "quit with live inferior" tests In-Reply-To: <1507805601-22576-1-git-send-email-palves@redhat.com> References: <1507805601-22576-1-git-send-email-palves@redhat.com> Message-ID: <5ecf8183d97c76fc4ca009d6f3e10432@polymtl.ca> X-Sender: simon.marchi@polymtl.ca User-Agent: Roundcube Webmail/1.3.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Thu, 12 Oct 2017 22:11:14 +0000 X-IsSubscribed: yes X-SW-Source: 2017-10/txt/msg00331.txt.bz2 On 2017-10-12 06:53, Pedro Alves wrote: > In my multi-target branch, I had managed to break GDB exiting > successfuly in response to "quit" or SIGHUP/SIGTERM when: > > - you're debugging with "target extended-remote", > - have more than one inferior loaded in gdb, some running, and at > least one not running, and, > - quit gdb with the inferior that is not running yet selected. > > The testsuite still passed cleanly anyway. I only noticed because I > was left with a bunch of core dumps in the gdb/testsuite/ directory -- > the testsuite infrastructure closes GDB's pty after running each > testcase, which results in GDB getting a SIGHUP and should make GDB > exit gracefully. If GDB crashes at that point though, there's no > indication about it in gdb.sum/gdb.log. > > This commit adds a multitude of tests exercising quitting GDB with > live inferiors, some of which would have caught the problem. I think you accidentally a file (quit.c). Should it be named the same as the exp file (quit-live.c)? It's a quite complex test, but you wrote it very clearly, so it's easy to follow. I just have minor comments. > gdb/testsuite/ChangeLog: > yyyy-mm-dd Pedro Alves > > * gdb.base/quit-live.exp: New file. > --- > gdb/testsuite/gdb.base/quit-live.exp | 180 > +++++++++++++++++++++++++++++++++++ > 1 file changed, 180 insertions(+) > create mode 100644 gdb/testsuite/gdb.base/quit-live.exp > > diff --git a/gdb/testsuite/gdb.base/quit-live.exp > b/gdb/testsuite/gdb.base/quit-live.exp > new file mode 100644 > index 0000000..ef235d9 > --- /dev/null > +++ b/gdb/testsuite/gdb.base/quit-live.exp > @@ -0,0 +1,180 @@ > +# Copyright (C) 2017 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 > . > + > +# Test quitting GDB with live inferiors. > +# > +# Exercises combinations of: > +# > +# - quitting with "quit"command, or with SIGTERM/SIGHUP signals. missing space > +# > +# - quitting with live inferior selected, or file_stratum inferior > +# selected. > +# > +# - quitting after "run", or after "attach". > +# > +# - quitting with local executable, or executable loaded from target > +# directly (via default "target:/" sysroot), or with no executable > +# loaded. > + > +# Note: sending an asynchronous SIGHUP with kill is not the exact same > +# as closing GDB's input, and that resulting in SIGHUP. However, it's > +# still a good approximation, and it has the advantage that because > +# GDB still has a terminal, internal errors (if any) are visible in > +# gdb.sum/gdb.log. > + > +standard_testfile quit.c > + > +if {[build_executable "failed to build" $testfile $srcfile debug]} { > + return > +} > + > +# Send signal SIG to GDB, and expect GDB to exit. > + > +proc test_quit_with_sig {sig} { > + set gdb_pid [exp_pid -i [board_info host fileid]] > + remote_exec host "kill -$sig ${gdb_pid}" > + > + set test "quit with SIG$sig" > + # If GDB mishandles the signal and doesn't exit, this > + # should FAIL with timeout. We don't expect a GDB prompt, > + # so we see one, we'll FAIL too. "so if we see one" ? In this case, does the test fail if there's any output (no necessarily a gdb_prompt)? > + gdb_test_multiple "" $test { > + eof { > + pass $test > + } > + } > +} > + > +# Call the "quit" command with an inferior live. > +# > +# APPEAR_HOW specifies how the running inferior appears in GDB. Can > +# be either: > +# > +# - "run" > +# > +# Appear via the "run" command. > +# > +# - "attach" > +# > +# Appear via the "attach" command. > +# > +# - "attach-nofile" > +# > +# Appear via the "attach" command, but with no program preloaded in > +# GDB so that GDB reads the program directly from the target when > +# remote debugging (i.e., from the target:/ sysroot). This makes > +# sure that GDB doesn't misbehave if it decides to close the > +# 'target:/.../program' exec_file after closing the remote > +# connection. > +# > +# EXTRA_INFERIOR is a boolean that specifies whether the "quit" > +# command is typed with an extra executable-only (before "run") > +# inferior selected or whether it is typed when the live inferior is > +# selected, with no extra inferior. > +# > +# QUIT_HOW specifies how to tell GDB to quit. It can be either "quit" > +# (for "quit" command), "sighup" or "sigterm" (for quitting with > +# SIGHUP and SIGTERM signals, respectively). > + > +proc quit_with_live_inferior {appear_how extra_inferior quit_how} { > + global srcfile testfile binfile > + global gdb_spawn_id gdb_prompt > + > + set test_spawn_id "" > + > + if {$appear_how != "attach-nofile"} { > + clean_restart $binfile > + } else { > + clean_restart > + } > + > + if {$appear_how == "run"} { > + if ![runto_main] then { > + fail "can't run to main" > + return > + } > + } elseif {$appear_how == "attach" || $appear_how == > "attach-nofile"} { > + set test_spawn_id [spawn_wait_for_attach $binfile] > + set testpid [spawn_id_get_pid $test_spawn_id] > + > + if {[gdb_test "attach $testpid" \ > + "Attaching to .*process $testpid.*Reading symbols from.*" \ > + "attach"] != 0} { > + kill_wait_spawned_process $test_spawn_id > + return > + } > + } else { > + error "unhandled '\$appear_how': $appear_how" > + } > + > + if {$extra_inferior} { > + gdb_test "add-inferior" "Added inferior 2*" \ > + "add empty inferior 2" > + gdb_test "inferior 2" "Switching to inferior 2.*" \ > + "switch to inferior 2" > + } > + > + # Make regexp that matches the "quit" command's output. > + proc make_re {how} { > + multi_line \ > + "A debugging session is active.\[ \t\r\n\]*Inferior 1\[^\r\n\]* > will be $how\." \ > + "" \ > + "Quit anyway\\? \\(y or n\\) $" > + } > + > + if {$appear_how == "run"} { > + set quit_anyway_re [make_re "killed"] > + } else { > + set quit_anyway_re [make_re "detached"] > + } > + > + if {$quit_how == "quit"} { > + set test "quit with \"quit\"" > + gdb_test_multiple "quit" $test { > + -re $quit_anyway_re { > + send_gdb "y\n" > + gdb_test_multiple "" $test { > + eof { > + pass $test > + } > + } > + } > + } > + } elseif {$quit_how == "sighup"} { > + test_quit_with_sig HUP > + } elseif {$quit_how == "sigterm"} { > + test_quit_with_sig TERM > + } else { > + error "unhandled '\$quit_how': $quit_how" > + } > + > + if {$test_spawn_id != ""} { > + kill_wait_spawned_process $test_spawn_id > + } > +} > + > +with_test_prefix "quit with live inferior" { I think this prefix is not very useful, since it contains all the tests, although I'm not against it either. > + foreach_with_prefix appear_how {"run" "attach" "attach-nofile"} { > + if {$appear_how != "run" && ![can_spawn_for_attach]} { > + continue > + } > + > + foreach_with_prefix extra_inferior {0 1} { > + foreach_with_prefix quit_how {"quit" "sigterm" "sighup"} { > + quit_with_live_inferior $appear_how $extra_inferior $quit_how > + } > + } > + } > +} Thanks, Simon