From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id KJ+7HWDwMmYLgQIAWB0awg (envelope-from ) for ; Wed, 01 May 2024 21:46:08 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=SppP66MS; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 535861E0C1; Wed, 1 May 2024 21:46:08 -0400 (EDT) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 291921E030 for ; Wed, 1 May 2024 21:46:06 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A7373385EC56 for ; Thu, 2 May 2024 01:46:05 +0000 (GMT) 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 BC7323858CD1 for ; Thu, 2 May 2024 01:45:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BC7323858CD1 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 BC7323858CD1 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=1714614345; cv=none; b=pNzDh8Jp3xI5MIURq8hLz58ZcYADicBgXnasncsPHAe9zt+/wKpJuIjtT0b6PSOe5BGSl/0GF0PYYjP+BbyW2Rlsy8oGd8b1pXybIHe0IBmoiXXlmndFR/FZTJlLzMzHVA8ZA4mPEGuHaaXNc525SdiSL4pjcsKoCgO2+Oq4wIY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714614345; c=relaxed/simple; bh=SyJc7Ah6FOIGma5FCNTWbU8XttoftXhbKgZhQlUd9FI=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=KLvE/SR0wPoqyVNZgu1/zPW/nGsapTPbwkRtPBPPCrKzAG9/EQCqcG9MPPqJ05UQxTDGS5ZeJPrfc1aR/e+Aih39HrstQpA0PzVjb0NmnqpNzL49BvMhgtMkxspozDjpeK/h3bzE0LAbajX+BpWqLoF6c3PqafwpdsLIGe6DIaY= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1714614342; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ChYynIRPipDioO0YdV89btwoxb9AkRtLRCIMDv3nNP0=; b=SppP66MS0XjdfdYWmUReGg58eQQup3p0FNwjiOmInl7PLHsmYqgGxv/M2MDZjMwytNbDDx jyjv7gvHSlSC7v6PqaWOmeEWMtNYxrkTQaPL0Vba8te/MwoeyIe/bAljeWQuAlgxzZ8rQB w0tebMVRSCtNetcsS9UL3KGBxeGPfaY= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-620-gEc6t5ySPtKnvmBXiTJiLw-1; Wed, 01 May 2024 21:45:41 -0400 X-MC-Unique: gEc6t5ySPtKnvmBXiTJiLw-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id DFF591C0AF48 for ; Thu, 2 May 2024 01:45:40 +0000 (UTC) Received: from f39-zbm-amd (unknown [10.22.16.14]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 849CD1C060D0 for ; Thu, 2 May 2024 01:45:40 +0000 (UTC) Date: Wed, 1 May 2024 18:45:38 -0700 From: Kevin Buettner To: gdb-patches@sourceware.org Subject: Re: [PATCH v3] [gdb/testsuite] New test: gdb.base/check-errno.exp Message-ID: <20240501184538.1de5556c@f39-zbm-amd> In-Reply-To: <20240502013934.389445-1-kevinb@redhat.com> References: <20240502013934.389445-1-kevinb@redhat.com> Organization: Red Hat MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-11.1 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_H4, 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+public-inbox=simark.ca@sourceware.org I had intended for the following text to be included just before the main body of the commit log: [ This v3 patch fixes the binfile names for the pthreads-static and pthreads-static-macros scenarios. Aside from documenting the potential for XPASSes in check-errno.exp, I haven't figured out what to do about the XPASSes flagged by Linaro CI. ] Kevin On Wed, 1 May 2024 18:38:03 -0700 Kevin Buettner wrote: > Printing the value of 'errno' from GDB is sometimes problematic. The > situation has improved in recent years, though there are still > scenarios for which "print errno" doesn't work. > > The test, gdb.base/check-errno.exp, introduced by this commit, > tests whether or not GDB can print errno with a binary compiled > in the following different ways: > > - default: no switches aside from -g (and whatever else is added by the > testing framework) > - macros: macros included in the debuginfo; this is enabled by using > -g3 when using gcc or clang > - static: statically linked binary > - static-macros: statically linked binary w/ macro definitions included > in debuginfo > - pthreads: libpthread linked binary > - pthreads-macros: libpthread linked binary w/ macro definitions included > in debuginfo > - pthreads-static: Statically linked against libpthread > - pthreads-static-macros: Statically linked against libpthread w/ macro > definitions > > For each of these, the test also creates a corefile, then loads the > corefile and attempts to print errno again. > > Additionally, the test checks that a "masking" errno declared as a > local variable will print correctly. > > On Linux, if the machine is missing glibc debuginfo (or you have > debuginfod disabled), it's likely you'll see: > > (gdb) print errno > 'errno' has unknown type; cast it to its declared type > > But if you add a cast, the value of errno is often available: > > (gdb) print (int) errno > $1 = 42 > > The test detects this situation along with several others and does > 'setup_xfail' for tests that are likely to fail. Also, on Linux, > doing 'print (int) errno' for a statically linked binary (currently) > doesn't work. I've XFAILed these cases explicitly. > > On Fedora 39, without glibc debuginfo, there are no failures, but > I do see the following XFAILS and XPASSES: > > XFAIL: gdb.base/check-errno.exp: default: print errno > XFAIL: gdb.base/check-errno.exp: default: check errno value from corefile > XFAIL: gdb.base/check-errno.exp: macros: print errno > XFAIL: gdb.base/check-errno.exp: macros: print (int) errno > XFAIL: gdb.base/check-errno.exp: macros: check errno value from corefile > XFAIL: gdb.base/check-errno.exp: static: print errno > XFAIL: gdb.base/check-errno.exp: static: print (int) errno > XFAIL: gdb.base/check-errno.exp: static: check errno value from corefile > XFAIL: gdb.base/check-errno.exp: static-macros: print errno > XPASS: gdb.base/check-errno.exp: static-macros: print (int) errno > XFAIL: gdb.base/check-errno.exp: static-macros: check errno value from corefile > XFAIL: gdb.base/check-errno.exp: pthreads: print errno > XFAIL: gdb.base/check-errno.exp: pthreads: check errno value from corefile > XFAIL: gdb.base/check-errno.exp: pthreads-macros: print errno > XFAIL: gdb.base/check-errno.exp: pthreads-macros: print (int) errno > XFAIL: gdb.base/check-errno.exp: pthreads-macros: check errno value from corefile > XFAIL: gdb.base/check-errno.exp: pthreads-static: print errno > XFAIL: gdb.base/check-errno.exp: pthreads-static: print (int) errno > XFAIL: gdb.base/check-errno.exp: pthreads-static: check errno value from corefile > XFAIL: gdb.base/check-errno.exp: pthreads-static-macros: print errno > XPASS: gdb.base/check-errno.exp: pthreads-static-macros: print (int) errno > XFAIL: gdb.base/check-errno.exp: pthreads-static-macros: check errno value from corefile > > (It's likely that this also happens on other versions of Fedora, but I > haven't checked this.) > > On Fedora 39, with glibc debug info, but without libc.a (for static > linking), there are 2 XFAILs, 2 UNSUPPORTED tests, and 4 UNTESTED > tests. > > So, even when testing in less than ideal conditions, either due to lack > of glibc debuginfo or lack of a libc to link against to make a static > binary, there are no failures. > > With glibc debuginfo installed, on Fedora 38, Fedora 39, Fedora 40, > Fedora rawhide (41), and Ubuntu 22.04.1 LTS, I see these XFAILs and XPASSes > > XFAIL: gdb.base/check-errno.exp: macros: check errno value from corefile > XFAIL: gdb.base/check-errno.exp: static: print errno > XFAIL: gdb.base/check-errno.exp: static: print (int) errno > XFAIL: gdb.base/check-errno.exp: static: check errno value from corefile > XFAIL: gdb.base/check-errno.exp: static-macros: print errno > XPASS: gdb.base/check-errno.exp: static-macros: print (int) errno > XFAIL: gdb.base/check-errno.exp: static-macros: check errno value from corefile > XFAIL: gdb.base/check-errno.exp: pthreads-macros: check errno value from corefile > XFAIL: gdb.base/check-errno.exp: pthreads-static: print errno > XFAIL: gdb.base/check-errno.exp: pthreads-static: print (int) errno > XFAIL: gdb.base/check-errno.exp: pthreads-static: check errno value from corefile > XFAIL: gdb.base/check-errno.exp: pthreads-static-macros: print errno > XPASS: gdb.base/check-errno.exp: pthreads-static-macros: print (int) errno > XFAIL: gdb.base/check-errno.exp: pthreads-static-macros: check errno value from corefile > > On FreeBSD 13.1, I see the same XFAILs, but the XPASSes are simply PASSes. > > So, bottom line, this test does not introduce any new failures on the > platforms on which I've tested, but the XFAILs are certainly unfortunate. > Some aren't fixable (e.g. when attempting to make a function call while > debugging a core file), but I think that some of them are. I'm using > this new test case as a starting point for investigating problems with > printing errno. > > Co-Authored-By: Jan Kratochvil > --- > gdb/testsuite/gdb.base/check-errno.c | 37 ++++ > gdb/testsuite/gdb.base/check-errno.exp | 237 +++++++++++++++++++++++++ > 2 files changed, 274 insertions(+) > create mode 100644 gdb/testsuite/gdb.base/check-errno.c > create mode 100644 gdb/testsuite/gdb.base/check-errno.exp > > diff --git a/gdb/testsuite/gdb.base/check-errno.c b/gdb/testsuite/gdb.base/check-errno.c > new file mode 100644 > index 00000000000..c6835a866e8 > --- /dev/null > +++ b/gdb/testsuite/gdb.base/check-errno.c > @@ -0,0 +1,37 @@ > +/* This testcase is part of GDB, the GNU debugger. > + > + Copyright 2024 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 . */ > + > +#include > + > +static void shadow_errno (); > + > +int main () > +{ > + errno = 42; > + > + shadow_errno (); /* main-breakpoint */ > + return 0; > +} > + > +#undef errno > +static void > +shadow_errno () > +{ > + int errno = 36; > + > + return; /* shadow_errno-breakpoint */ > +} > diff --git a/gdb/testsuite/gdb.base/check-errno.exp b/gdb/testsuite/gdb.base/check-errno.exp > new file mode 100644 > index 00000000000..af7d204f56e > --- /dev/null > +++ b/gdb/testsuite/gdb.base/check-errno.exp > @@ -0,0 +1,237 @@ > +# Copyright 2024 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. > + > +# Check that errno can be accessed by GDB under a variety of > +# circumstances. > +# > +# The challenge with GDB accessing errno is that, on modern systems, > +# errno is a variable in thread-local storage. So, if GDB's access to > +# thread local storage is broken, some of these tests could fail. > +# > +# Another possibility (which is tested by the "macro" tests below) is > +# that errno is a macro and the debuginfo includes a macro expression > +# for errno. In the past, this often helped with being able to print > +# errno, but at the time that this test was written, it seems to not > +# always work correctly. > +# > +# When the binary is compiled statically, GDB's access to thread local > +# storage may be compromised, perhaps leading to failures with those > +# tests. > +# > +# To complicate things even more, access to errno might not work when > +# examining a core file. E.g. if it's necessary to call a function, > +# perhaps named '__errno_location', this won't be possible without > +# a running inferior. > +# > +# It's also possible for a program to declare errno in an inner scope > +# causing the thread-local errno to be shadowed. GDB should still > +# correctly print the masking errno for this case. > + > +standard_testfile > + > +proc do_tests {{do_xfail_cast 0} {do_xfail 0} {do_xfail_core_test 0}} { > + clean_restart $::binfile > + runto_main > + > + gdb_breakpoint [gdb_get_line_number "main-breakpoint"] > + gdb_continue_to_breakpoint "main-breakpoint" > + > + # Whether or not "print errno" will work often depends on the > + # debuginfo available. We can make some inferences about whether > + # some of the tests should have xfail set-up by looking at the > + # output of "ptype errno". We pass these ptype tests, even for > + # less than ideal outputs, because the point is to set up the > + # xfail. A failure can still occur for output which doesn't match > + # any of those listed. > + set test "ptype errno" > + gdb_test_multiple $test $test { > + -re "type = int\r\n$::gdb_prompt $" { > + pass $test > + } > + -re "type = .*no debug info.*$::gdb_prompt $" { > + pass $test > + set do_xfail 1 > + set do_xfail_core_test 1 > + } > + -re ".*Cannot find thread-local variables on this target.*$::gdb_prompt $" { > + pass $test > + set do_xfail 1 > + set do_xfail_core_test 1 > + } > + -re ".*has unknown return type; cast the call to its declared return type.*$::gdb_prompt $" { > + pass $test > + set do_xfail 1 > + set do_xfail_core_test 1 > + > + # On Linux, using -g3, which causes macro information to > + # be included in the debuginfo, errno might be defined as > + # follows: > + # > + # #define errno (*__errno_location ()) > + # > + # So, when we do "ptype errno", due to macro expansion, > + # this ends up being "ptype (*__errno_location ())". So > + # the call to __errno_location (or something similar on > + # other OSes) is the call mentioned in the error message. > + # > + # For the test "print (int) errno", we're casting the > + # result of the expression, which includes both the call > + # along with a dereferencing operation. > + # > + # This will sometimes produce the right answer, but it's > + # also just as likely to fail. E.g. on x86_64, if the > + # address being returned as a 32-bit int is the same as > + # that which would have been returned as a 64-bit pointer, > + # then the test might pass. Otherwise, it will almost > + # certainly fail, which is why we XFAIL it here. But do > + # expect to see the occasional XPASS for this case. > + set do_xfail_cast 1 > + } > + } > + > + # If errno is defined as a macro that contains an obvious function > + # call, it's likely that it won't work when debugging a core file. > + set test "info macro errno" > + gdb_test_multiple $test $test { > + -re "Defined at.*\[\r\n\]#define.*\\\(\\\).*$::gdb_prompt $" { > + set do_xfail_core_test 1 > + pass $test > + } > + -re "Defined at.*\[\r\n\]#define.*$::gdb_prompt $" { > + pass $test > + } > + -re "The symbol .errno. has no definition.*$::gdb_prompt $" { > + pass $test > + } > + } > + > + if $do_xfail { > + setup_xfail *-*-* > + } > + gdb_test "print errno" ".* = 42" > + > + if $do_xfail_cast { > + setup_xfail *-*-* > + } > + gdb_test "print (int) errno" ".* = 42" > + > + set corefile ${::binfile}.core > + set core_supported [gdb_gcore_cmd $corefile "save corefile"] > + # Normally, we'd check core_supported here and return if it's > + # not, but we'll defer that until after the shadow test. > + > + gdb_breakpoint [gdb_get_line_number "shadow_errno-breakpoint"] > + gdb_continue_to_breakpoint "shadow_errno-breakpoint" > + > + # This test demonstrates why a simple hack to GDB for printing > + # errno is a bad idea. (The hack was to intercept the string > + # "errno" in process_print_command_args() and replace it with > + # "*(*(int *(*)(void)) __errno_location) ()".) > + gdb_test "print errno" ".* = 36" "print masking errno" > + > + # Finish test early if no core file was made. > + if !$core_supported { > + return > + } > + > + clean_restart $::binfile > + > + set core_loaded [gdb_core_cmd $corefile "load corefile"] > + if { $core_loaded == -1 } { > + return > + } > + if $do_xfail_core_test { > + setup_xfail *-*-* > + } > + gdb_test "print errno" ".* = 42" "check errno value from corefile" > +} > + > +set binprefix $binfile > + > +with_test_prefix "default" { > + set binfile $binprefix-default > + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { > + untested "failed to compile" > + } else { > + do_tests > + } > +} > + > +with_test_prefix "macros" { > + set binfile $binprefix-macros > + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug macros}] != "" } { > + untested "failed to compile" > + } else { > + do_tests > + } > +} > + > +with_test_prefix "static" { > + set binfile $binprefix-static > + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug "additional_flags=-static"}] != "" } { > + untested "failed to compile" > + } else { > + set xfail_cast_test 0 > + if {[istarget *-linux*]} { > + set xfail_cast_test 1 > + } > + do_tests $xfail_cast_test > + } > +} > + > +with_test_prefix "static-macros" { > + set binfile $binprefix-static-macros > + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug macros "additional_flags=-static"}] != "" } { > + untested "failed to compile" > + } else { > + do_tests > + } > +} > + > +with_test_prefix "pthreads" { > + set binfile $binprefix-pthreads > + if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { > + untested "failed to compile" > + } else { > + do_tests > + } > +} > + > +with_test_prefix "pthreads-macros" { > + set binfile $binprefix-pthreads-macros > + if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug macros}] != "" } { > + untested "failed to compile" > + } else { > + do_tests > + } > +} > + > +with_test_prefix "pthreads-static" { > + set binfile $binprefix-pthreads-static > + if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug "additional_flags=-static"}] != "" } { > + untested "failed to compile" > + } else { > + set xfail_cast_test 0 > + if {[istarget *-linux*]} { > + set xfail_cast_test 1 > + } > + do_tests $xfail_cast_test > + } > +} > + > +with_test_prefix "pthreads-static-macros" { > + set binfile $binprefix-pthreads-static-macros > + if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug macros "additional_flags=-static"}] != "" } { > + untested "failed to compile" > + } else { > + do_tests > + } > +} > -- > 2.44.0 >