From patchwork Mon Dec 4 02:46:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zeck S X-Patchwork-Id: 81244 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 95D563857BB7 for ; Mon, 4 Dec 2023 03:24:54 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-io1-xd2b.google.com (mail-io1-xd2b.google.com [IPv6:2607:f8b0:4864:20::d2b]) by sourceware.org (Postfix) with ESMTPS id 138623858C42 for ; Mon, 4 Dec 2023 03:24:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 138623858C42 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 138623858C42 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::d2b ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701660281; cv=none; b=CqLRrTxnAX67Efow1gckAt+p/vBHYZuto2uOEuA8phcLfsUP1mLqw5xZ1QlNVhAeP0TDP9DScRjTMWnR0c6KcaMggZvjXzWFPMb3CiIQWq8Z0y+Kqg65M21VwnMC704UjHpD2TNJbm9tQfZVnaF7zhAtFBhjgnv7L4sXMYY7N7A= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701660281; c=relaxed/simple; bh=KsvRa8l+2qQDqNzijwd6944KMhqt14fCy+ZTsfz+B58=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=vJe4XMdWuji7vxUxrL0dkXHY+Ru7ywidcxQ2CssTJHq07kQcqvsIKHHkLp6aTHlz2/UV+hp8LfltzzifGQxzntbEXWQ+cN0RJ86fQYjYx+pJMG4oghhtp03v/hf3wA0rCXyo830KMxr4/7IC1718U/6nobVKTs6SFWoFhlxWYnI= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-io1-xd2b.google.com with SMTP id ca18e2360f4ac-7b37dd4bb35so154781339f.3 for ; Sun, 03 Dec 2023 19:24:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701660278; x=1702265078; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=CysXttv7OEpBGMiUB1wqITXb+palMGR8X6X4Iob8ui0=; b=WfYZq3cxYnI2e8iq14nGghNBtEcDxBtMFidyJr8mAiImkyGKEHzl0lMuBIJY1DaPc1 dPMzC5d1tG/MDCEn81lgoJBgCtG5C3YnYE15QGykH7tkSNhdAj4Pgsg0/44ykQY6hqOx 8SqNaicW85n4jTxjCSsbEu+dL+2+XhCQsUTJsnSW5t7u0OVL1U+sWNqHF69hhjsWccaD Z2rEREsb4ya1JdkL2IqHXAEuZpOFoLWHb2FzW9td3+2UK4gOl7rO1xesBWC2Fr/okzSf 6FQkW1peCj25jn5XOaV2ZAe4y92kkGAqxpWN3/Osspmw4LfdykZS3fmJj5JsB62KZq8A L1Zw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701660278; x=1702265078; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=CysXttv7OEpBGMiUB1wqITXb+palMGR8X6X4Iob8ui0=; b=P9WF4blfQKjvW3b8Gscur4DyGFsPoSH6VxzMWqRugfq1fAhzmxwXLmPN4eHq9o34T0 v44clcSlkSF4BZ2eAUuMK8i8gfBzF61nSJvup8bGd1kYP6wLuyBonEn4V27vQcYIXv00 Uh0LKqw8WDNwLgpep3IMokJxauzrzTEJo01SRuGtfqyfjsk3YlvQ5lQE3rtTvwFwJnn4 400d5pj4duBhQRLFYpn1NLIw6AW7x9gs+AzkqvrU4ml9bDFoaWxl6gSknbvwQwlsNZ6y 3iiW8L1DHaxU6QHUIdgrbdYdgrDaseex/AAE8gJvt/KEQpbBpKOL5x+gge7HEHTKlUTa Zkzg== X-Gm-Message-State: AOJu0YxSC3UwJUoYF+8JKP7s+Fk9cEbzDNeiGnL/nA9IHWlQVTTfBF8x 9eZJjSxWzQ7XLsF/sJcTU1Ne3tWuOTc= X-Google-Smtp-Source: AGHT+IHD9fZY8VRUShT+Eiz6pz+eaypPM0npaLtX3KzxxyQPAerwAAMePe91GJqeEFqWWO28VflUOQ== X-Received: by 2002:a05:6602:3282:b0:7b4:28f8:2bfd with SMTP id d2-20020a056602328200b007b428f82bfdmr4162637ioz.38.1701660277679; Sun, 03 Dec 2023 19:24:37 -0800 (PST) Received: from localhost.localdomain (66-85-86-66-85-86-131.cpe.sparklight.net. [66.85.86.131]) by smtp.gmail.com with ESMTPSA id k2-20020a0566022d8200b007836c7e8dccsm2468986iow.17.2023.12.03.19.24.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Dec 2023 19:24:37 -0800 (PST) From: Zeck S To: gdb-patches@sourceware.org Cc: Zeck S Subject: [PATCH] add qemu user mode emulation dejagnu config Date: Sun, 3 Dec 2023 20:46:36 -0600 Message-ID: <20231204024634.419445-3-zeck654321@gmail.com> X-Mailer: git-send-email 2.41.0 MIME-Version: 1.0 X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, 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 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 I created this board config, to help test a patch I made for fixing mdebug symbol support. https://sourceware.org/pipermail/gdb-patches/2023-October/203473.html The only compiler I have that produces mdebug, targets big endian mips. Distros supporting this arch are very few now. Also full system emulation would be slow. So I decided to try QEMU user mode emulation instead. I can build object files with this old compiler, link with gnu ld and the exectuables work fine in qemu-mips. The board config adds -static to ld flags. That way no LD prefix is needed for QEMU and no built libraries are required to use this. I tested and developed this board with qemu-mips and mips gcc, but other architectures should be easy to add. I run the test suite with the board like this: runtest gdb.base/*.exp --ignore gdb.threads/access-mem-running-thread-exit.exp CC_FOR_TARGET=mips-unknown-linux-gnu-gcc CXX_FOR_TARGET=mips-unknown-linux-gnu-g++ --target mips --target_board qemu-user --log_dialog and get these results (the tests take some time to run) === gdb Summary === # of expected passes 76013 # of unexpected failures 1381 # of expected failures 1 # of known failures 24 # of unresolved testcases 250 # of untested testcases 43 # of unsupported tests 1163 # of paths in test names 221 # of duplicate test names 3 I tried to elminate problems stemming from the board being deficient in its setup. Oddities (or at least things that were odd to me) are documented in comments. There seem to be some actual bugs found. There are also problems from limitations of QEMU. My particular use case is odd, I admit, but it seems like this board would make testing and fixing bugs related to many non-x86 archs more accessible. I had no prior experience with DejaGnu, Expect, or TCL, so if something is weird, that's probably why. If there is some other preferred direction to go, for me to validate my other patch, let me know. This route was just what made sense to me. I will gladly address any feedback! Thanks Z.S. --- gdb/testsuite/boards/qemu-user.exp | 267 +++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 gdb/testsuite/boards/qemu-user.exp diff --git a/gdb/testsuite/boards/qemu-user.exp b/gdb/testsuite/boards/qemu-user.exp new file mode 100644 index 00000000000..f79714d9c97 --- /dev/null +++ b/gdb/testsuite/boards/qemu-user.exp @@ -0,0 +1,267 @@ +# Copyright 2020-2023 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 . + +# NOTICE: +# QEMU user mode gdbstub has multithreading problems +# https://gitlab.com/qemu-project/qemu/-/issues/1671 +# run with --ignore gdb.threads/access-mem-running-thread-exit.exp +# since this test in particular seems to hang. Could be related. + +# This technique is from native-extended-gdbserver.exp +# We must load this explicitly here, and rename the procedures we want +# to override. If we didn't do this, given that mi-support.exp is +# loaded later in the test files, the procedures loaded then would +# override our definitions. +load_lib mi-support.exp + +set qemu "" +set qemu_arch "" +set qemu_user_spawn_id "" +set qemu_user_last_load_file "" +set port "2345" + +# add sections for other architectures +# as needed +case "$target_triplet" in { + { "mips" } { + set qemu "qemu-mips" + set qemu_arch "mips" + } + default { + puts "No target hardware for $target_triplet" + } +} + +# QEMU supports some of extended-remote, but not the run command +# which causes problems for the test suite +set_board_info gdb_protocol "remote" +set_board_info use_gdb_stub 1 +set_board_info gdb,do_reload_on_run 1 +set_board_info exit_is_reliable 1 +# static link so we do not need to configure an QEMU LD prefix and install +# libraries for the target architecture +set_board_info ldflags "-static" + +# technique from simavr.exp +# +# Load executable into GDB +# +proc gdb_load { arg } { + global gdb_prompt + global verbose + global spawn_id + global qemu + global qemu_user_last_load_file + global qemu_user_spawn_id + global port + + # keep track of last loaded file + # to simulate run restart like behavior + if { $arg == "" } { + set arg $qemu_user_last_load_file + if { $arg == "" } { + global last_loaded_file + # this fallback is needed + # for tests like gdb.base/break-unload-file.exp + set arg $last_loaded_file + } + } else { + set qemu_user_last_load_file $arg + } + + if { $arg != "" } { + if {[gdb_file_cmd $arg]} then { return -1 } + } + + # Close any previous qemu user instance. + if { $qemu_user_spawn_id != "" } { + verbose -log "qemu user: closing previous spawn id $qemu_user_spawn_id" + if [catch { close -i $qemu_user_spawn_id } != 0] { + warning "qemu user: failed to close connection to previous qemu user instance" + } + + # some tests get QEMU + # into a state where the process doesn't want to die + # so -nowait to not hang the entire test run + wait -nowait -i $qemu_user_spawn_id + set qemu_user_spawn_id "" + } + + # technique from gdbserver-support.exp + # Loop till we find a free port. + # This is to cope with qemu sometimes getting + # into a bad state and not closing. + # Do a pkill -f qemu-mips -9 after running tests + # to remove stragglers + while 1 { + # Run QEMU user + set cmd "spawn -noecho $qemu -g $port $arg" + verbose -log "Spawning qemu user: $cmd" + eval $cmd + set qemu_user_spawn_id $spawn_id + + # without inferior_spawn_id + # tests such as gdb.base/a2-run.exp + # can't look at the right process output + global inferior_spawn_id + set inferior_spawn_id $spawn_id + + expect { + -i $qemu_user_spawn_id + -timeout 1 + -re ".*qemu: could not open gdbserver on.*" { + verbose -log "Port $port is already in use." + if [catch { close -i $qemu_user_spawn_id } != 0] { + warning "qemu user: failed to close connection to previous qemu user instance" + } + # Bump the port number to avoid the conflict. + wait -i $qemu_user_spawn_id + incr port + continue + } + } + break + } + + # arch needs set because some tests + # take actions that need arch to be correct + # immediately, before file command loads the binary + # for example gdb.base/break-unload-file.exp + global qemu_arch + send_gdb "set arch $qemu_arch\n" + + # Connect to qemu user. + send_gdb "target remote :$port\n" + gdb_expect { + # qemu user mode gdb stub does not support non stop mode + # this is so tests that attempt it die quickly + -re ".*Non-stop mode requested, but remote does not support non-stop.*" { + error "qemu user does not support non-stop" + } + # cannot have multiple targets connected + # some tests end up causing this to be attempted in gdb.multi + -re ".*Already connected to a remote target. Disconnect?.*" { + send_gdb "y\n" + gdb_expect { + -re ".*$gdb_prompt $" { + error "connected to new target while connected to existing" + } + } + } + -re ".*$gdb_prompt $" { + if $verbose>1 then { + send_user "Connected to QEMU target\n" + } + } + -re "Remote debugging using .*$gdb_prompt $" { + verbose "Set target to remote for QEMU" + } + timeout { + verbose -log "qemu-user: unable to connect to qemu user, closing qemu user spawn id" + close -i $qemu_user_spawn_id + verbose -log "qemu-user: unable to connect to qemu user, waiting for qemu user process exit" + wait -i $qemu_user_spawn_id + set qemu_user_spawn_id "" + error "unable to connect to qemu user stub" + } + } + + return 0 +} + +# technique from native-extended-gdbserver.exp +# for overriding mi-support.exp procs +if { [info procs original_mi_gdb_load] == "" } { + rename mi_gdb_load original_gdbserver_mi_gdb_load +} + +# same ideas as gdb_load, but adapted for mi +proc mi_gdb_load { arg } { + global gdb_prompt + global verbose + global spawn_id + global qemu + global qemu_user_last_load_file + global qemu_user_spawn_id + global port + + if { $arg == "" } { + set arg $qemu_user_last_load_file + if { $arg == "" } { + global last_loaded_file + set arg $last_loaded_file + } + } else { + set qemu_user_last_load_file $arg + } + + if { $arg != "" } { + if {[mi_gdb_file_cmd $arg]} then { return -1 } + } + + #Close any previous qemu user instance. + if { $qemu_user_spawn_id != "" } { + verbose -log "qemu user: closing previous spawn id $qemu_user_spawn_id" + if [catch { close -i $qemu_user_spawn_id } != 0] { + warning "qemu user: failed to close previous qemu user instance" + } + + # some tests get QEMU/its gdb stub + # into a state where the process doesn't want to die + # so -nowait to not hang the entire test run + wait -nowait -i $qemu_user_spawn_id + set qemu_user_spawn_id "" + } + + # technique from gdbserver-support.exp + # Loop till we find a free port. + while 1 { + # Run QEMU user + set cmd "spawn -noecho $qemu -g $port $arg" + verbose -log "Spawning qemu user: $cmd" + eval $cmd + set qemu_user_spawn_id $spawn_id + + # without inferior_spawn_id + # tests such as gdb.base/a2-run.exp + # can't look at the right process output + global inferior_spawn_id + set inferior_spawn_id $spawn_id + + expect { + -i $qemu_user_spawn_id + -timeout 1 + -re ".*qemu: could not open gdbserver on.*" { + verbose -log "Port $port is already in use." + if [catch { close -i $qemu_user_spawn_id } != 0] { + warning "qemu user: failed to close connection to previous qemu user instance" + } + # Bump the port number to avoid the conflict. + wait -i $qemu_user_spawn_id + incr port + continue + } + } + break + } + + return 0 +} + +# technique from stdio-gdb-server-base.exp +proc mi_gdb_target_load { } { + global port + return [mi_gdb_target_cmd "remote" ":$port"] +}