From patchwork Mon Nov 25 14:16:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 101832 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 664783858C56 for ; Mon, 25 Nov 2024 14:18:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 664783858C56 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=dYkXQBJJ X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 2917D3858C35 for ; Mon, 25 Nov 2024 14:16:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2917D3858C35 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 2917D3858C35 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732544178; cv=none; b=vrCFR8+AtBnS9pTpTQlGjDziGA9c8xuaLEgd+s8Bx6hQ9jxgj0Ti2V+jEmmOK9HSbsizSzkaoI5FDVSA3MFmFwfARoS2GDbjTV4CFYfmFV3TXmUkv1I4MzpPcZsV+dGbOu2FarqBPjvVIkSmtKHYqLljAa8c7qAXclRORqwmDwo= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732544178; c=relaxed/simple; bh=hkunssRQgEwmGO8B4lW6lCFXEjAffcel7MaPGgY2MdU=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=jf37Q7OJTWecHolQ6KuZb42lzWqvzxP//HVNihb5ZI+UahbaBLaHafGlqaGUQTCrD1CVcKEKktP2NVjalkdjK5AbtermRyfkVysXLoOIcmTb6wdrTtAkp1BKyxLI2DbBuNBMKod68YewKNeARUjqfDo9FGp8Q1kLCheOCyRcogM= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2917D3858C35 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1732544177; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EiO12sBVKW0K+YUs7/MZYOOqpLeroPPTOUac7eIfIy8=; b=dYkXQBJJBaZdPcVUE/DJ0SoCR96pnRpHdZBJY6jmJhgiweQo7oqMAVcXwxJjBfEMMMiShA IHoEWbYIKeIF02enKzquO63KihTmxWCqDivOSNOb65c/MEu9iDxjjrLHTEzT8FOXAOaAGz zFxdRVfQ3j4iXUuRX17oYQMoUB+UWPc= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-180-3zTQQOLNP-Gitj4fR_bhPA-1; Mon, 25 Nov 2024 09:16:16 -0500 X-MC-Unique: 3zTQQOLNP-Gitj4fR_bhPA-1 X-Mimecast-MFC-AGG-ID: 3zTQQOLNP-Gitj4fR_bhPA Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-3822ecd84b3so2384231f8f.3 for ; Mon, 25 Nov 2024 06:16:16 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732544174; x=1733148974; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=EiO12sBVKW0K+YUs7/MZYOOqpLeroPPTOUac7eIfIy8=; b=rQkhzPRJfqXugEHNkNlPg/Eqy4B2qwx/wnjArau419jJklAdd2oXWFvv5C1nTImLFO 2kD9sy9PNUEQ6hP7dRaHdwi3Q6pMWTlPm8U1vsZIaFm7unNwWnXuUut9tH3gnmAErkRa 0TyUz4pNDXluaWY3DcWCd1KgTLZPLdH48yYK+uTWgqOCKWM5AT+D2G+B7VFjs9/QcsNU 14IQGqA7OHTHSp2SUygpd1oVfaiW2tShaB1DVK3Ole2FnCMXPkgVqMMy0ywRYRJ5Oywb UxkHLXQFUes1d47pT2Msw33pC6aN669QNr+b1ZYfawt9GD8zQQQoAocQltTl+tKfxFxf FbyQ== X-Gm-Message-State: AOJu0YxIuCq837IetIvz8jUaQySsiMbNlF9XmBGaWvaEeQq3Wk2OFChr OfSK+kUT1BI7N+n3MG6/usLsdsCTdgZnn6jhJHd5Slnp7FBUIiH9bXxTGJVIqd1i4/2Ja+IcyTI EOY7dmVaBp6+4ZNcQfcubGV9W6Do4GbGe7JFVPkWy9lZ1d1aFduY+JxkEDFNKP5KeYgf/MLebPU rnTLmWZ3nH7hQXA/cd7bx4YYfA7a3EuGH1aAK4dZ7MGtY= X-Gm-Gg: ASbGnctUgW484q1kwS98j5dZPTA53l95/eU5qUQ5ftuBckdOr5z7HkDIirvvx/BzB3c iJKQ6W07ijRgv6yNB9OKUDR0n5skTi7p6wrwG8KL41Of+/ODMoCW4e4I94yNPk1JMD8IEHojrGQ EAlriQLbJBtEO3zfDqbL0Ja1ao/sxQmoMdFQalDaH+qG5NNo/6iU7B1kJrOEDZZItNNcrnHvSW7 us5WPJeLEjWPVwrDL1GnMECEKDjyrAW0hhywfH0nBVWTNtIFX+d/2jSdCsUM3CNaTqFy31isOfg nQ== X-Received: by 2002:a5d:64ac:0:b0:382:43ab:7d7f with SMTP id ffacd0b85a97d-38260bf3cfbmr9761154f8f.58.1732544174352; Mon, 25 Nov 2024 06:16:14 -0800 (PST) X-Google-Smtp-Source: AGHT+IHNpklzZ1xfX6cVeGygeLm3lIEqXUVZRJOREPxJFR8MkaGxiCrrQdo4ekI2Rkg9F84sthL1hw== X-Received: by 2002:a5d:64ac:0:b0:382:43ab:7d7f with SMTP id ffacd0b85a97d-38260bf3cfbmr9761107f8f.58.1732544173723; Mon, 25 Nov 2024 06:16:13 -0800 (PST) Received: from localhost (197.209.200.146.dyn.plus.net. [146.200.209.197]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-433b45adde1sm199751255e9.10.2024.11.25.06.16.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 06:16:13 -0800 (PST) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCHv2 2/2] gdb: allow core file containing special characters on the command line Date: Mon, 25 Nov 2024 14:16:07 +0000 Message-Id: <522ad1692a5cc56c41d693112c2be6d37c3dc897.1732544034.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: tP_c6PS42-Yn1S0je6y_EvLPp9lDFcYCTtKADmnQev4_1732544175 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org After the commit: commit 03ad29c86c232484f9090582bbe6f221bc87c323 Date: Wed Jun 19 11:14:08 2024 +0100 gdb: 'target ...' commands now expect quoted/escaped filenames it was no longer possible to pass GDB the name of a core file containing any special characters (white space or quote characters) on the command line. For example: $ gdb -c /tmp/core\ file.core Junk after filename "/tmp/core": file.core (gdb) The problem is that the above commit changed the 'target core' command to expect quoted filenames, so before the above commit a user could write: (gdb) target core /tmp/core file.core [New LWP 2345783] Core was generated by `./mkcore'. Program terminated with signal SIGSEGV, Segmentation fault. #0 0x0000000000401111 in ?? () (gdb) But after the above commit the user must write: (gdb) target core /tmp/core\ file.core or (gdb) target core "/tmp/core file.core" This is part of a move to make GDB's filename argument handling consistent. Anyway, the problem with the '-c' command line flag is that it forwards the filename unmodified through to the 'core-file' command, which in turn forwards to the 'target core' command. So when the user, at a shell writes: $ gdb -c "core file.core" this arrives in GDB as the unquoted string 'core file.core' (without the single quotes). GDB then forwards this to the 'core-file' command as if the user had written this at a GDB prompt: (gdb) core-file core file.core Which then fails to parse due to the unquoted white space between 'core' and 'file.core'. The solution I propose is to escape any special characters in the core file name passed from the command line before calling 'core-file' command from main.c. I've updated the corefile.exp test to include a test for passing a core file containing a white space character. While I was at it I've modernised the part of corefile.exp that I was touching. --- gdb/main.c | 17 ++-- gdb/testsuite/gdb.base/corefile.exp | 116 +++++++++++++--------------- gdbsupport/common-utils.cc | 21 +++++ gdbsupport/common-utils.h | 5 ++ 4 files changed, 88 insertions(+), 71 deletions(-) diff --git a/gdb/main.c b/gdb/main.c index 4370e95ada4..14337fbda22 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -1235,7 +1235,8 @@ captured_main_1 (struct captured_main_args *context) if (corearg != NULL) { - ret = catch_command_errors (core_file_command, corearg, + ret = catch_command_errors (core_file_command, + make_quoted_string (corearg).c_str (), !batch_flag); } else if (pidarg != NULL) @@ -1253,16 +1254,18 @@ captured_main_1 (struct captured_main_args *context) ret = catch_command_errors (attach_command, pid_or_core_arg, !batch_flag); if (ret == 0) - ret = catch_command_errors (core_file_command, - pid_or_core_arg, - !batch_flag); + ret = catch_command_errors + (core_file_command, + make_quoted_string (pid_or_core_arg).c_str (), + !batch_flag); } else { /* Can't be a pid, better be a corefile. */ - ret = catch_command_errors (core_file_command, - pid_or_core_arg, - !batch_flag); + ret = catch_command_errors + (core_file_command, + make_quoted_string (pid_or_core_arg).c_str (), + !batch_flag); } } diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp index dc3c8b1dfc8..039f1894bc0 100644 --- a/gdb/testsuite/gdb.base/corefile.exp +++ b/gdb/testsuite/gdb.base/corefile.exp @@ -34,81 +34,69 @@ if {$corefile == ""} { return 0 } -# Test that we can simply startup with a "-core=$corefile" command line arg -# and recognize that the core file is a valid, usable core file. -# To do this, we must shutdown the currently running gdb and restart -# with the -core args. We can't use gdb_start because it looks for -# the first gdb prompt, and the message we are looking for occurs -# before the first prompt. +# Start GDB with COREFILE passed as a command line argument. COREOPT +# is prefixed before COREFILE and is the command line flag to specify +# the corefile, i.e. one of '--core=', '-core=', '-c '. # -# Another problem is that on some systems (solaris for example), there -# is apparently a limit on the length of a fully specified path to -# the corefile executable, at about 80 chars. For this case, consider -# it a pass, but note that the program name is bad. - -gdb_exit -if {$verbose>1} { - send_user "Spawning $GDB $INTERNAL_GDBFLAGS $GDBFLAGS -core=$corefile\n" -} - -set oldtimeout $timeout -set timeout [expr "$timeout + 60"] -verbose "Timeout is now $timeout seconds" 2 -eval "spawn $GDB $INTERNAL_GDBFLAGS $GDBFLAGS -core=$corefile" -expect { - -re "Couldn't find .* registers in core file.*$gdb_prompt $" { - fail "args: -core=[file tail $corefile] (couldn't find regs)" - } - -re "Core was generated by .*corefile.*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { - pass "args: -core=[file tail $corefile]" - } - -re "Core was generated by .*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { - pass "args: -core=[file tail $corefile] (with bad program name)" - } - -re ".*registers from core file: File in wrong format.* $" { - fail "args: -core=[file tail $corefile] (could not read registers from core file)" - } - -re ".*$gdb_prompt $" { fail "args: -core=[file tail $corefile]" } - timeout { fail "(timeout) starting with -core" } -} - - +# If BINFILE is not the empty string then it is also added as a +# command line argument and is the executable to load. # -# Test that startup with both an executable file and -core argument. -# See previous comments above, they are still applicable. -# - -close +# TESTNAME is used for naming the tests. +proc start_gdb_with_corefile { testname coreopt corefile {binfile ""} } { + gdb_exit -if {$verbose>1} { - send_user "Spawning $GDB $INTERNAL_GDBFLAGS $GDBFLAGS $binfile -core=$corefile\n" -} + global GDBFLAGS + save_vars { GDBFLAGS } { + append GDBFLAGS " $binfile $coreopt$corefile" + set res [gdb_spawn] + if { $res != 0 } { + fail "$testname (start GDB)" + return + } -eval "spawn $GDB $INTERNAL_GDBFLAGS $GDBFLAGS $binfile -core=$corefile" -expect { - -re "Core was generated by .*corefile.*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { - pass "args: execfile -core=[file tail $corefile]" - } - -re "Core was generated by .*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { - pass "args: execfile -core=[file tail $corefile] (with bad program name)" - } - -re ".*registers from core file: File in wrong format.* $" { - fail "args: execfile -core=[file tail $corefile] (could not read registers from core file)" + gdb_test_multiple "" $testname { + -re -wrap "Couldn't find .* registers in core file.*" { + fail "$gdb_test_name (couldn't find regs)" + } + -re -wrap "Core was generated by `[string_to_regexp $corefile]'\\.\r\n.*\#0 \[^\r\n\]+\(\).*" { + pass $gdb_test_name + } + -re -wrap "Core was generated by .*\r\n\#0 .*\(\).*" { + # This case is hit when the executable name is + # truncated in the output. + pass "$gdb_test_name (with bad program name)" + } + -re -wrap ".*registers from core file: File in wrong format.*" { + fail "$gdb_test_name (could not read registers from core file)" + } + -re -wrap "" { + fail "$gdb_test_name (core not loaded)" + } + } } - -re ".*$gdb_prompt $" { fail "args: execfile -core=[file tail $corefile]" } - timeout { fail "(timeout) starting with -core" } } -set timeout $oldtimeout -verbose "Timeout is now $timeout seconds" 2 -close +# Create a copy of the corefile, but with a space in the filename. +set alt_corefile [standard_output_file "core\\ file.core"] +remote_exec host "cp $corefile $alt_corefile" + +# Test that we can start GDB with a corefile command line argument and +# recognize that the core file is a valid, usable core file. We test +# using '--core=...', '-core=...', and '-c ...' style arguments. We +# also test with, and without an executable. +foreach_with_prefix coreopt {--core= -core= "-c "} { + start_gdb_with_corefile "just core file" $coreopt $corefile + start_gdb_with_corefile "core file and executable" $coreopt $corefile $binfile + start_gdb_with_corefile "core file with white space in name" \ + $coreopt $alt_corefile + start_gdb_with_corefile "core file with white space in name and executable" \ + $coreopt $alt_corefile $binfile +} # Now restart normally. -gdb_start -gdb_reinitialize_dir $srcdir/$subdir -gdb_load ${binfile} +clean_restart $binfile # Test basic corefile recognition via core-file command. diff --git a/gdbsupport/common-utils.cc b/gdbsupport/common-utils.cc index 91c14a0f139..af25bf0ee9c 100644 --- a/gdbsupport/common-utils.cc +++ b/gdbsupport/common-utils.cc @@ -222,6 +222,27 @@ extract_string_maybe_quoted (const char **arg) return result; } +/* See gdbsupport/common-utils.h. */ + +std::string +make_quoted_string (const char *str) +{ + gdb_assert (str != nullptr); + + std::string result; + + for (; *str != '\0'; ++str) + { + const char ch = *str; + + if (strchr ("\"' \t\n", ch) != nullptr) + result.push_back ('\\'); + result.push_back (ch); + } + + return result; +} + /* The bit offset of the highest byte in a ULONGEST, for overflow checking. */ diff --git a/gdbsupport/common-utils.h b/gdbsupport/common-utils.h index 2fb22916409..65158388881 100644 --- a/gdbsupport/common-utils.h +++ b/gdbsupport/common-utils.h @@ -84,6 +84,11 @@ char *savestring (const char *ptr, size_t len); std::string extract_string_maybe_quoted (const char **arg); +/* Return a copy of STR, but with any white space, single quote, or + double quote characters escaped with a backslash. */ + +std::string make_quoted_string (const char *str); + /* The strerror() function can return NULL for errno values that are out of range. Provide a "safe" version that always returns a printable string. This version is also thread-safe. */