From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 785B23858407 for ; Tue, 9 Jan 2024 14:27:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 785B23858407 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 785B23858407 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=1704810425; cv=none; b=scqSfsM/xOnGkaoomj7sqJqMeNx5cGZnVvGPlCg3r1hvDr3HhFvTipc2yqCNBvH3AavcgfTd/CB+8Db7/DCUyAzSwWaQc1c03WVgFw9c2gt7M7dCLfrndKpzfGGRREeEx6abe4rXr39+uu1ioF52D4WjIWXdcxrVmj+7UQHV9dg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1704810425; c=relaxed/simple; bh=FFaScsYEUMvtc9anUVSA/b6LDQIIHQl72cSvM6M5Xi4=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=dmRrPAaa4OUL16vDGAkNI00QsKGZ0STY63TfG8Jh1Kr4+37QrxGVNXrTMXFSoTl7UdeFx3DgvTBVIK1OgugPn9McidxyzfrMELIh1kS9NmPyowy96bV44LOAGKD+74/gA++8HISL88onxzWOrCXkoMAVw21H9+1TtJ/c2WKLxIs= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1704810422; 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=HiMrBDD6o+vCyE1qKqHNkSyjJdKgNsOeWsulZ9P3Nc0=; b=LnGuwnCd4Nb5wJTcnrUzQYIVrTrHEva85NiRykkWTV7kkeKnfr24UuOYsF/TV65MZ29emL 1cz6vRXBBYN6SgUARQ98DmpSJbGBocQ2nL/8bJ+AKIKSGe+htAchWCxg9I/DMTTP+aN8wi xfRXvxdMgczYwT26bzDk0zmHj95jLuE= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-346-XlrS-YH4M3CD7l6uc5t74Q-1; Tue, 09 Jan 2024 09:27:00 -0500 X-MC-Unique: XlrS-YH4M3CD7l6uc5t74Q-1 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-3367657a290so1880817f8f.3 for ; Tue, 09 Jan 2024 06:26:59 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1704810418; x=1705415218; 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=HiMrBDD6o+vCyE1qKqHNkSyjJdKgNsOeWsulZ9P3Nc0=; b=JLvu/a5ZAEOdYGR6hRZg+vlSEn1JHroRvANJB0ir/FK0DKsQvdMeIRsxv5LuS87vj+ Vj8juQk5EfajHGtcUe+VkXYgxaBvtEL5VZYxHtPJLxrfpMZbUVytL4Z9LmwLlXiPp6px 3hgu8SkrBIOctnNSb5gLZhQQ2O898Bvimtzb77l+IePzUvdiyhcc9PRhNdS85SQBcjhk WLs5PEtUU0eMcFwngMNQqlSlWmbP7caK4rgxQGCyMNOtZtk8XBu1hQ5zNqvk930YFet8 1UAeD6BOjCdL2P97BhZ/W2cXmCoAC5B8ujLcnVZrIghyF+bfw+q2p2xle7lqA9IogD3/ AQmQ== X-Gm-Message-State: AOJu0YwIA/O8r1h4/gwAXdq7haiJnf/9OLNjEW3Wuc/HjeFlvNlVsROo zE+VTcxyIHWexxRM/vH4xi0Juhs0AfbOFscT1Jnv+ABGJNh7OyZVhYID+mmoCLMyPHNTgl6c/R5 d5w/6rqN/xTMjnclwpzc2CQjGq3KXiLMAAVerNi3LHAxghrVhEkjIDaepyCuibNaDSw0hsItFcf S68HS+dUoTAvOuxA== X-Received: by 2002:adf:e2d2:0:b0:337:6001:9ff5 with SMTP id d18-20020adfe2d2000000b0033760019ff5mr565238wrj.60.1704810417960; Tue, 09 Jan 2024 06:26:57 -0800 (PST) X-Google-Smtp-Source: AGHT+IFOeBkflydzj3T7q4TNfbSmMbmqcmOwMgdlgMV3jrrruAXYnbN7k77hXuVUQxSLCfCKuX6pcQ== X-Received: by 2002:adf:e2d2:0:b0:337:6001:9ff5 with SMTP id d18-20020adfe2d2000000b0033760019ff5mr565229wrj.60.1704810417653; Tue, 09 Jan 2024 06:26:57 -0800 (PST) Received: from localhost (185.223.159.143.dyn.plus.net. [143.159.223.185]) by smtp.gmail.com with ESMTPSA id p11-20020a5d59ab000000b00336ebf93416sm2587435wrr.17.2024.01.09.06.26.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jan 2024 06:26:56 -0800 (PST) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess , Michael Weghorn Subject: [PATCH 10/16] gdb: add remote argument passing self tests Date: Tue, 9 Jan 2024 14:26:33 +0000 Message-Id: X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-13.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: This commit adds some remote argument passing self-tests. There are not many tests right now -- there are known bugs in the remote argument passing mechanism (see PR gdb/28392) -- but some simple cases are covered here, and I plan to add additional tests once I've fixed some of the problems with the existing code. The tests take an inferior argument string, this is the string that GDB would carry around as inferior::m_args. This string is then split using gdb::remote_args::split, this gives a vector of strings, these are the strings that are passed over the remote protocol. These split strings are validated as part of the test. The split strings are then combined using gdb::remote_args::join which gives the inferior argument string that gdbserver will use, this is held in server.cc, program_args, this joined string is then checked as part of the test. There are no changes to GDB's behaviour as part of this commit, other than adding the new tests. --- gdb/Makefile.in | 1 + gdb/unittests/remote-arg-selftests.c | 189 +++++++++++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 gdb/unittests/remote-arg-selftests.c diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 195f3a2e2d1..cc2e62b6f3c 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -476,6 +476,7 @@ SELFTESTS_SRCS = \ unittests/ptid-selftests.c \ unittests/main-thread-selftests.c \ unittests/mkdir-recursive-selftests.c \ + unittests/remote-arg-selftests.c \ unittests/rsp-low-selftests.c \ unittests/scoped_fd-selftests.c \ unittests/scoped_ignore_signal-selftests.c \ diff --git a/gdb/unittests/remote-arg-selftests.c b/gdb/unittests/remote-arg-selftests.c new file mode 100644 index 00000000000..3240ab9aeea --- /dev/null +++ b/gdb/unittests/remote-arg-selftests.c @@ -0,0 +1,189 @@ +/* Self tests for GDB's argument splitting and merging. + + Copyright (C) 2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +#include "defs.h" +#include "gdbsupport/selftest.h" +#include "gdbsupport/buildargv.h" +#include "gdbsupport/common-inferior.h" +#include "gdbsupport/remote-args.h" + +namespace selftests { +namespace remote_args_tests { + +/* The data needed to perform a single remote argument test. */ +struct arg_test_desc +{ + /* The original inferior argument string. */ + std::string input; + + /* The individual arguments once they have been split. */ + std::vector split; + + /* The new inferior argument string, created by joining SPLIT. */ + std::string joined; +}; + +/* The list of tests. */ +arg_test_desc desc[] = { + { "abc", { "abc" }, "abc" }, + { "a b c", { "a", "b", "c" }, "a b c" }, + { "\"a b\" 'c d'", { "a b", "c d" }, "a\\ b c\\ d" }, + { "\\' \\\"", { "'", "\"" }, "\\' \\\"" }, + { "'\\'", { "\\" }, "\\\\" }, + { "\"\\\\\" \"\\\\\\\"\"", { "\\", "\\\"" }, "\\\\ \\\\\\\"" }, + { "\\ \" \" ' '", { " ", " ", " "}, "\\ \\ \\ " }, + { "\"'\"", { "'" }, "\\'" }, + { "'\"' '\\\"'", { "\"", "\\\"" } , "\\\" \\\\\\\""}, + { "\"first arg\" \"\" \"third-arg\" \"'\" \"\\\"\" \"\\\\\\\"\" \" \" \"\"", + { "first arg", "", "third-arg", "'", "\"", "\\\""," ", "" }, + "first\\ arg '' third-arg \\' \\\" \\\\\\\" \\ ''"}, + { "\"\\a\" \"\\&\" \"\\#\" \"\\<\" \"\\^\"", + { "\\a", "\\&", "\\#" , "\\<" , "\\^"}, + "\\\\a \\\\\\& \\\\\\# \\\\\\< \\\\\\^" }, + { "1 '\n' 3", { "1", "\n", "3" }, "1 '\n' 3" }, +}; + +/* Convert a std::vector into std::vector. This + requires copying all of the string content. This class takes care of + freeing the memory once we are done with it. */ + +struct args_as_c_strings +{ + args_as_c_strings (std::vector args) + { + for (const auto & a : args) + m_data.push_back (xstrdup (a.c_str ())); + } + + ~args_as_c_strings () + { + free_vector_argv (m_data); + } + + std::vector &get () + { + return m_data; + } + +private: + std::vector m_data; +}; + +/* Run the remote argument passing self tests. */ + +static void +self_test () +{ + int failure_count = 0; + for (const auto &d : desc) + { + if (run_verbose ()) + { + if (&d != &desc[0]) + debug_printf ("------------------------------\n"); + debug_printf ("Input (%s)\n", d.input.c_str ()); + } + + /* Split argument string into individual arguments. */ + std::vector split_args = gdb::remote_args::split (d.input); + + if (run_verbose ()) + { + debug_printf ("Split:\n"); + + size_t len = std::max (split_args.size (), d.split.size ()); + for (size_t i = 0; i < len; ++i) + { + const char *got = "N/A"; + const char *expected = got; + + if (i < split_args.size ()) + got = split_args[i].c_str (); + + if (i < d.split.size ()) + expected = d.split[i].c_str (); + + debug_printf (" got (%s), expected (%s)\n", got, expected); + } + } + + if (split_args != d.split) + { + ++failure_count; + if (run_verbose ()) + debug_printf ("FAIL\n"); + continue; + } + + /* Now join the arguments. */ + args_as_c_strings split_args_c_str (split_args); + std::string joined_args + = gdb::remote_args::join (split_args_c_str.get ()); + + if (run_verbose ()) + debug_printf ("Joined (%s), expected (%s)\n", + joined_args.c_str (), d.joined.c_str ()); + + if (joined_args != d.joined) + { + ++failure_count; + if (run_verbose ()) + debug_printf ("FAIL\n"); + continue; + } + + /* The contents of JOINED_ARGS will not be identical to D.INPUT. + There are multiple ways that an argument can be escaped, and out + join function just picks one. However, if we split JOINED_ARGS + again then each individual argument should be the same as those in + SPLIT_ARGS. So lets test that next. */ + std::vector split_args_v2 + = gdb::remote_args::split (joined_args); + + if (split_args_v2 != split_args) + { + ++failure_count; + if (run_verbose ()) + { + debug_printf ("Re-split:\n"); + for (const auto &a : split_args_v2) + debug_printf (" got (%s)\n", a.c_str ()); + debug_printf ("FAIL\n"); + } + continue; + } + + if (run_verbose ()) + debug_printf ("PASS\n"); + } + + SELF_CHECK (failure_count == 0); +} + +} /* namespace remote_args_tests */ +} /* namespace selftests */ + +void _initialize_remote_arg_selftests (); + +void +_initialize_remote_arg_selftests () +{ + selftests::register_test ("remote-args", + selftests::remote_args_tests::self_test); +} -- 2.25.4