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 2FF4B3858015 for ; Wed, 2 Nov 2022 08:19:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2FF4B3858015 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1667377151; 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=q2qhoPGg8p1D23rokPhwEi1o+CSTa6wcbo8ROy1Sfk4=; b=TmpkYaavvdNBi0xSSaMNEfVDX+WFIgVdLhns1zkMTHb1EgNItfmpyovhHqnrq9MivO/c1V VsMAXhtot9TTjZezB5sVbVa1ovbBD4GO4B7cmy3mmFZ8Cp/x1SUH4Qbw5L5GiRlJQSNpsg SKnmHc3+zCsyUvwHyXb5yuzWZXCLsQU= Received: from mail-qt1-f200.google.com (mail-qt1-f200.google.com [209.85.160.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-556-DSrnhcDuOICex53ygZppkQ-1; Wed, 02 Nov 2022 04:19:11 -0400 X-MC-Unique: DSrnhcDuOICex53ygZppkQ-1 Received: by mail-qt1-f200.google.com with SMTP id gc12-20020a05622a59cc00b003a5444280e1so1122955qtb.13 for ; Wed, 02 Nov 2022 01:19:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=q2qhoPGg8p1D23rokPhwEi1o+CSTa6wcbo8ROy1Sfk4=; b=mNVIAjYmQKSVVx1LKKwo36RdFREx8sOe5UqsxQgfMJeN//S+F8GjSzAkSvG6mOHdzV 113O7RsJ8eMMeHEo9zWCx3JJcmf0dKYE2XDNFp/Ym1rgMgjSTwBv7w/OTAIaDbNx4mDT 4cJg/B6BWg870J1WhXY2jJYErKTt6ZVeAiWTPpkwahFzQ08T5EwA2Xig2CsBHREpIO2k 1znItx+8FqyPlp5fgT6DGBroOg5ga+KiDkmmTnzUPEyfU2AuKvjKMOzLL4e208md1m9y oBi97P4BUCr5akf5JMEDl45QAcyAbKvbwPyHg8Gp5tJ8FdD0SXxmNPWtKURx80tiC5Jz JQpA== X-Gm-Message-State: ACrzQf3HqsfbMuNbzWeE3vzR0pfyDRV5y2USE2Qqbh32C4VrG/zUTckK IbZO2+n/hQLBfy0EK5rtbXHtHH6lwkz4e8xjFVx5TujwJwkuRvTOh/W/LyNCqacXV5sYkv0/0Fk z7wx9liUf696aqojuWtbhYUQ1XoEuK4I+osK7eGcJRE/Hmr1j3cP1NuyDnzcJsvA06v2aXjG8 X-Received: by 2002:ad4:5e85:0:b0:4bb:fa4d:bb65 with SMTP id jl5-20020ad45e85000000b004bbfa4dbb65mr11879102qvb.9.1667377149702; Wed, 02 Nov 2022 01:19:09 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5TdtnX3B9vGll++6XSPalAiBdHql5wQ1kWQwBHXT58K5lhyymoKcAoOVfgJbnYtYw8ZyfT1w== X-Received: by 2002:ad4:5e85:0:b0:4bb:fa4d:bb65 with SMTP id jl5-20020ad45e85000000b004bbfa4dbb65mr11879072qvb.9.1667377149170; Wed, 02 Nov 2022 01:19:09 -0700 (PDT) Received: from [192.168.0.45] (ip-62-245-66-121.bb.vodafone.cz. [62.245.66.121]) by smtp.gmail.com with ESMTPSA id q25-20020a37f719000000b006fa16fe93bbsm7831752qkj.15.2022.11.02.01.19.07 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 02 Nov 2022 01:19:08 -0700 (PDT) Message-ID: <8240e463-4800-7a48-33fa-79351bc8f7eb@redhat.com> Date: Wed, 2 Nov 2022 09:19:05 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.4.0 Subject: [PING][PATCH v3] gdb: Fix issue with Clang CLI macros To: gdb-patches@sourceware.org, Bruno Larsen Cc: simark@simark.ca References: <20221018132215.2593111-1-blarsen@redhat.com> From: Bruno Larsen In-Reply-To: <20221018132215.2593111-1-blarsen@redhat.com> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-10.7 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_BARRACUDACENTRAL,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,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 List-Id: Ping Cheers, Bruno On 18/10/2022 15:22, Bruno Larsen wrote: > Clang up to version 15 (current) adds macros that were defined in the > command line or by "other means", according to the Dwarf specification, > after the last DW_MACRO_end_file, instead of before the first > DW_MACRO_start_file, as the specification dictates. When GDB reads the > macros after the last file is closed, the macros never end up "in scope" > and so we can't print them. This has been submitted as a bug to Clang > developers (https://github.com/llvm/llvm-project/issues/54506), and PR > macros/29034 was opened for GDB to keep track of this. > > Seeing as there is no expected date for it to be fixed, add a workaround > for all current versions of Clang. The workaround detects when > the main file would be closed and if the producer is Clang, and turns > that operation into a noop, so we keep a reference to the current_file > as those macros are read. > > A test case was added to confirm the functionality, and the KFAIL for > running gdb.base/macro-source-path when using clang. > > Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29034 > --- > gdb/dwarf2/cu.h | 1 + > gdb/dwarf2/macro.c | 19 +++- > gdb/dwarf2/macro.h | 2 +- > gdb/dwarf2/read.c | 13 ++- > gdb/dwarf2/read.h | 2 + > gdb/producer.c | 24 +++++ > gdb/producer.h | 4 + > gdb/testsuite/gdb.base/macro-source-path.exp | 5 - > gdb/testsuite/gdb.dwarf2/clang-cli-macro.c | 20 ++++ > gdb/testsuite/gdb.dwarf2/clang-cli-macro.exp | 98 ++++++++++++++++++++ > 10 files changed, 177 insertions(+), 11 deletions(-) > create mode 100644 gdb/testsuite/gdb.dwarf2/clang-cli-macro.c > create mode 100644 gdb/testsuite/gdb.dwarf2/clang-cli-macro.exp > > diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h > index 23cb3d21b2e..51638e71b19 100644 > --- a/gdb/dwarf2/cu.h > +++ b/gdb/dwarf2/cu.h > @@ -264,6 +264,7 @@ struct dwarf2_cu > bool producer_is_icc : 1; > bool producer_is_icc_lt_14 : 1; > bool producer_is_codewarrior : 1; > + bool producer_is_clang : 1; > > /* When true, the file that we're processing is known to have > debugging info for C++ namespaces. GCC 3.3.x did not produce > diff --git a/gdb/dwarf2/macro.c b/gdb/dwarf2/macro.c > index 38c0fdfec73..7224c45682a 100644 > --- a/gdb/dwarf2/macro.c > +++ b/gdb/dwarf2/macro.c > @@ -445,7 +445,7 @@ dwarf_decode_macro_bytes (dwarf2_per_objfile *per_objfile, > struct dwarf2_section_info *str_section, > struct dwarf2_section_info *str_offsets_section, > gdb::optional str_offsets_base, > - htab_t include_hash) > + htab_t include_hash, struct dwarf2_cu *cu) > { > struct objfile *objfile = per_objfile->objfile; > enum dwarf_macro_record_type macinfo_type; > @@ -672,6 +672,17 @@ dwarf_decode_macro_bytes (dwarf2_per_objfile *per_objfile, > if (! current_file) > complaint (_("macro debug info has an unmatched " > "`close_file' directive")); > + else if (current_file->included_by == nullptr > + && producer_is_clang (cu)) > + { > + /* Clang, until the current version, misplaces some macro > + definitions - such as ones defined in the command line, > + putting them after the last DW_MACRO_end_file instead of > + before the first DW_MACRO_start_file. Since at the time > + of writing there is no clang version with this bug fixed, > + we check for any clang producer. This should be changed > + to producer_is_clang_lt_XX when possible. */ > + } > else > { > current_file = current_file->included_by; > @@ -751,7 +762,7 @@ dwarf_decode_macro_bytes (dwarf2_per_objfile *per_objfile, > current_file, lh, section, > section_is_gnu, is_dwz, offset_size, > str_section, str_offsets_section, > - str_offsets_base, include_hash); > + str_offsets_base, include_hash, cu); > > htab_remove_elt (include_hash, (void *) new_mac_ptr); > } > @@ -795,7 +806,7 @@ dwarf_decode_macros (dwarf2_per_objfile *per_objfile, > unsigned int offset, struct dwarf2_section_info *str_section, > struct dwarf2_section_info *str_offsets_section, > gdb::optional str_offsets_base, > - int section_is_gnu) > + int section_is_gnu, struct dwarf2_cu *cu) > { > bfd *abfd; > const gdb_byte *mac_ptr, *mac_end; > @@ -956,5 +967,5 @@ dwarf_decode_macros (dwarf2_per_objfile *per_objfile, > dwarf_decode_macro_bytes (per_objfile, builder, abfd, mac_ptr, mac_end, > current_file, lh, section, section_is_gnu, 0, > offset_size, str_section, str_offsets_section, > - str_offsets_base, include_hash.get ()); > + str_offsets_base, include_hash.get (), cu); > } > diff --git a/gdb/dwarf2/macro.h b/gdb/dwarf2/macro.h > index e8c33a34a8d..02753ef377a 100644 > --- a/gdb/dwarf2/macro.h > +++ b/gdb/dwarf2/macro.h > @@ -31,6 +31,6 @@ extern void dwarf_decode_macros (dwarf2_per_objfile *per_objfile, > dwarf2_section_info *str_section, > dwarf2_section_info *str_offsets_section, > gdb::optional str_offsets_base, > - int section_is_gnu); > + int section_is_gnu, struct dwarf2_cu *cu); > > #endif /* GDB_DWARF2_MACRO_H */ > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c > index 78f4cc1f60d..b3b2c70b1c3 100644 > --- a/gdb/dwarf2/read.c > +++ b/gdb/dwarf2/read.c > @@ -9484,6 +9484,15 @@ producer_is_gcc_lt_4_3 (struct dwarf2_cu *cu) > return cu->producer_is_gcc_lt_4_3; > } > > +bool > +producer_is_clang (struct dwarf2_cu *cu) > +{ > + if (!cu->checked_producer) > + check_producer (cu); > + > + return cu->producer_is_clang; > +} > + > static file_and_directory & > find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu) > { > @@ -13343,6 +13352,8 @@ check_producer (struct dwarf2_cu *cu) > } > else if (startswith (cu->producer, "CodeWarrior S12/L-ISA")) > cu->producer_is_codewarrior = true; > + else if (producer_is_clang (cu->producer, &major, &minor)) > + cu->producer_is_clang = true; > else > { > /* For other non-GCC compilers, expect their behavior is DWARF version > @@ -23363,7 +23374,7 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset, > > dwarf_decode_macros (per_objfile, builder, section, lh, > offset_size, offset, str_section, str_offsets_section, > - str_offsets_base, section_is_gnu); > + str_offsets_base, section_is_gnu, cu); > } > > /* Return the .debug_loc section to use for CU. > diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h > index 5f01fbc1025..a47e6bf5144 100644 > --- a/gdb/dwarf2/read.h > +++ b/gdb/dwarf2/read.h > @@ -761,4 +761,6 @@ extern void dwarf2_get_section_info (struct objfile *, > asection **, const gdb_byte **, > bfd_size_type *); > > +extern bool producer_is_clang (struct dwarf2_cu *cu); > + > #endif /* DWARF2READ_H */ > diff --git a/gdb/producer.c b/gdb/producer.c > index ef1dd93afbc..f65823426d1 100644 > --- a/gdb/producer.c > +++ b/gdb/producer.c > @@ -127,6 +127,30 @@ producer_is_llvm (const char *producer) > || startswith (producer, " F90 Flang "))); > } > > +/* See producer.h. */ > + > +bool > +producer_is_clang (const char *producer, int *major, int *minor) > +{ > + if (producer != nullptr && startswith (producer, "clang version ")) > + { > + int maj, min; > + if (major == nullptr) > + major = &maj; > + if (minor == nullptr) > + minor = &min; > + > + /* The full producer string will look something like > + "clang version XX.X.X ..." > + So we can safely ignore all characters before the first digit. */ > + const char *cs = producer + strlen ("clang version "); > + > + if (sscanf (cs, "%d.%d", major, minor) == 2) > + return true; > + } > + return false; > +} > + > #if defined GDB_SELF_TEST > namespace selftests { > namespace producer { > diff --git a/gdb/producer.h b/gdb/producer.h > index f7c19368bc6..b75cfae6569 100644 > --- a/gdb/producer.h > +++ b/gdb/producer.h > @@ -41,4 +41,8 @@ extern bool producer_is_icc (const char *producer, int *major, int *minor); > false otherwise.*/ > extern bool producer_is_llvm (const char *producer); > > +/* Returns true if the given PRODUCER string is clang, false otherwise. > + Sets MAJOR and MINOR accordingly, if not NULL. */ > +extern bool producer_is_clang (const char *producer, int *major, int *minor); > + > #endif > diff --git a/gdb/testsuite/gdb.base/macro-source-path.exp b/gdb/testsuite/gdb.base/macro-source-path.exp > index edbb4aee8e9..b553d088d09 100644 > --- a/gdb/testsuite/gdb.base/macro-source-path.exp > +++ b/gdb/testsuite/gdb.base/macro-source-path.exp > @@ -62,11 +62,6 @@ proc test { src name } { > } > > # Print the macro that is defined on the command-line. > - if { [test_compiler_info "clang-*"] } { > - # This is really a clang bug, it puts the macros defined on the command > - # line after the main source file, in the macro table. > - setup_kfail "gdb/29034" "*-*-*" > - } > gdb_test "print ONE" " = 1" > > # Print the macro that is defined in the main file. > diff --git a/gdb/testsuite/gdb.dwarf2/clang-cli-macro.c b/gdb/testsuite/gdb.dwarf2/clang-cli-macro.c > new file mode 100644 > index 00000000000..749bcc1580e > --- /dev/null > +++ b/gdb/testsuite/gdb.dwarf2/clang-cli-macro.c > @@ -0,0 +1,20 @@ > +/* Copyright 2022 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 . */ > + > +int > +main (void) > +{ > + asm ("main_label: .globl main_label"); > +} > diff --git a/gdb/testsuite/gdb.dwarf2/clang-cli-macro.exp b/gdb/testsuite/gdb.dwarf2/clang-cli-macro.exp > new file mode 100644 > index 00000000000..ea701468cdb > --- /dev/null > +++ b/gdb/testsuite/gdb.dwarf2/clang-cli-macro.exp > @@ -0,0 +1,98 @@ > +# This testcase is part of GDB, the GNU debugger. > + > +# Copyright 2022 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 . > + > +# Clang has this bug where it puts the macros defined on the command-line > +# after the main file portion (see PR 29034) and: > +# https://github.com/llvm/llvm-project/issues/54506 > +# Test that GDB is still able to print macros in clang versions that > +# have this bug. > + > +load_lib dwarf.exp > + > +if {![dwarf2_support]} { > + return 0 > +} > +if {![test_compiler_info gcc-*-*]} { > + untested "dwarf assembler needs GCC" > +} > + > +standard_testfile .c .S > + > +lassign [function_range main $srcdir/$subdir/$srcfile] \ > + main_start main_len > + > +set asm_file [standard_output_file $srcfile2] > + > +Dwarf::assemble $asm_file { > + declare_labels L cu_macros > + > + cu {} { > + DW_TAG_compile_unit { > + {DW_AT_producer "clang version 15.0.0"} > + {DW_AT_language @DW_LANG_C11} > + {DW_AT_name $::srcfile} > + {DW_AT_macros $cu_macros DW_FORM_sec_offset} > + {DW_AT_stmt_list $L DW_FORM_sec_offset} > + } { > + declare_labels int_type > + > + int_type: DW_TAG_base_type { > + {DW_AT_byte_size 4 DW_FORM_sdata} > + {DW_AT_encoding @DW_ATE_signed} > + {DW_AT_name int} > + } > + DW_TAG_subprogram { > + {MACRO_AT_func {main}} > + {type :$int_type} > + } > + } > + } > + lines {version 2} L { > + file_name $::srcfile 1 > + program { > + DW_LNE_set_address $::main_start > + line 10 > + DW_LNS_copy > + DW_LNE_set_address "$::main_start + $::main_len" > + DW_LNE_end_sequence > + } > + } > + > + # Define the .debug_macro section. > + macro { > + cu_macros: unit { > + "debug-line-offset-label" $L > + } { > + start_file 0 1 > + # A macro defined at line 1 of the main file. > + define 1 "TWO 2" > + end_file > + define 0 "ONE 1" > + } > + } > +} > + > +if {[prepare_for_testing "failed to prepare" $testfile [list $srcfile $asm_file] {nodebug}]} { > + return > +} > + > +if {![runto_main]} { > + return > +} > + > +gdb_test "print TWO" "= 2" "print simple macro" > +gdb_test "print ONE" "= 1" "print defined from CLI"