From: Bruno Larsen <blarsen@redhat.com>
To: Tom de Vries <tdevries@suse.de>, gdb-patches@sourceware.org
Subject: Re: [PATCH 2/3] [RFC][gdb/symtab] Add maint set symbol-read-order
Date: Mon, 26 Sep 2022 12:43:42 +0200 [thread overview]
Message-ID: <fa3c35aa-55e4-fa0e-67da-88270f4681ab@redhat.com> (raw)
In-Reply-To: <20220922152042.21914-2-tdevries@suse.de>
Cheers,
Bruno
On 22/09/2022 17:20, Tom de Vries via Gdb-patches wrote:
> With the test-case included in this patch, we run into:
> ...
> (gdb) print var_dwarf^M
> $1 = 1^M
> (gdb) PASS: gdb.ctf/dwarf2-and-ctf.exp: print var_dwarf
> print var_ctf^M
> 'var_ctf' has unknown type; cast it to its declared type^M
> (gdb) FAIL: gdb.ctf/dwarf2-and-ctf.exp: print var_ctf
> ...
>
> The problem is that the executable contains both ctf and dwarf2, so the ctf
> info is ignored.
>
> GDB has support for handling multiple debug formats, but the common use case
> for ctf is to be used when dwarf2 is not present, and gdb reflects that,
> assuming that by reading ctf in addition there won't be any extra information,
> so it's not worth the additional cycles and memory.
>
> Add a new maintenance command "maint set symbol-read-order <string>", where
> the argument string "mdebug+stabs+dwarf2/ctf" represent the current default,
> in other words:
> - first mdebug is read
> - then stabs is read
> - then dwarf2 is read,
> - then ctf is read, but only if dwarf2 info was missing.
>
> A bit of background on the relevance of reading order: the formats that create
> partial symtabs (all but dwarf2) have a priority relationship between them,
> where reading earlier means lower priority. By reading the format with the
> most detail last, we ensure it has the highest priority, which makes sure that
> in case there is overlapping info, the most detailed info is found. This
> explains the ordering of mdebug, stabs and dwarf2 (because it used to have
> partial symtabs).
>
> By using "maint set symbol-read-order ctf+dwarf2 or dwarf2+ctf, we can make the
> test-case pass.
>
> This is an RFC at this point, so no documentation yet.
>
> Points I'd like to have feedback on:
> - I chose this to be a maintenance command, because I suspect the reading
> order implications are a bit hard to understand.
> - was it a good idea to use strtok ?
> - I went for genericity, but could haved used instead a simple
> "set read-ctf-symtab <no|no-dwarf2|yes>". If that is better, should
> it be a maintenance command or not?
> - I initially went for the priority first order in the argument string, so
> reflecting the current default would be "dwarf2/ctf+stabs+mdebug", thinking
> it would be easier to understand the priority scheme this way, but abandoned
> that approach midway. Which is easier to grasp?
A point against genericity, it isn't clear if we are supposed to read
mdebug+stabs+(dwarf2)/ctf or (mdebug+stabs+dwarf2)/ctf. The option to
change how ctf specifically is read would not create this.
About the ordering, I feel like priority order would be less confusing,
if you decide to go with the generic option.
>
> Tested on x86_64-linux.
> ---
> gdb/elfread.c | 243 ++++++++++++++++++++---
> gdb/testsuite/gdb.ctf/dwarf2-and-ctf-2.c | 24 +++
> gdb/testsuite/gdb.ctf/dwarf2-and-ctf.c | 26 +++
> gdb/testsuite/gdb.ctf/dwarf2-and-ctf.exp | 54 +++++
> 4 files changed, 317 insertions(+), 30 deletions(-)
> create mode 100644 gdb/testsuite/gdb.ctf/dwarf2-and-ctf-2.c
> create mode 100644 gdb/testsuite/gdb.ctf/dwarf2-and-ctf.c
> create mode 100644 gdb/testsuite/gdb.ctf/dwarf2-and-ctf.exp
>
> diff --git a/gdb/elfread.c b/gdb/elfread.c
> index ed11c67dc02..740b0a76513 100644
> --- a/gdb/elfread.c
> +++ b/gdb/elfread.c
> @@ -51,6 +51,7 @@
> #include "gdbsupport/scoped_fd.h"
> #include "debuginfod-support.h"
> #include "dwarf2/public.h"
> +#include "cli/cli-cmds.h"
>
> /* The struct elfinfo is available only during ELF symbol table and
> psymtab reading. It is destroyed at the completion of psymtab-reading.
> @@ -1166,6 +1167,152 @@ elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags,
> symtab_create_debug_printf ("done reading minimal symbols");
> }
>
> +/* Symbol types supported by elfread.c. */
> +
> +enum symbol_type
> + {
> + mdebug,
> + stabs,
> + dwarf2,
> + ctf,
> + sep,
> + };
> +
> +/* Strings corresponding to enum symbol_type. */
> +
> +const char *symbol_type_to_string [] =
> + {
> + "mdebug",
> + "stabs",
> + "dwarf2",
> + "ctf",
> + "sep"
> + };
> +
> +/* Return symbol_type for string S in ST and return true, otherwise return
> + false. If ALLOW_SEP is true, we also allow the sep symbol_type. */
> +
> +static bool
> +string_to_symbol_type (const char *s, enum symbol_type &st,
> + bool allow_sep = false)
> +{
> + size_t symbol_type_to_string_elems
> + = sizeof (symbol_type_to_string) / sizeof (*symbol_type_to_string);
> +
> + for (unsigned int i = 0; i < symbol_type_to_string_elems; i++)
> + {
> + if (i == sep && !allow_sep)
> + continue;
> +
> + if (strcmp (symbol_type_to_string[i], s) != 0)
> + continue;
> +
> + st = (symbol_type)i;
> + return true;
> + }
> +
> + return false;
> +}
> +
> +/* The default "mdebug+stabs+dwarf2/ctf" means:
> + - read mdebug first
> + - then read stabs
> + - then read dwarf2
> + - then read ctf, but only if dwarf2 is not read. */
> +
> +static std::string symbol_read_order_default = "mdebug+stabs+dwarf2/ctf";
> +
> +/* Set by the "maint set symbol-read-order <string>" command. */
> +
> +static std::string symbol_read_order = symbol_read_order_default;
> +
> +/* Parsed representation of symbol_read_order.
> + For a symbol_read_order of "mdebug+stabs+dwarf2/ctf" we have
> + { mdebug, sep, stabs, sep, dwarf, ctf, sep }. */
> +
> +std::vector<enum symbol_type> parsed_symbol_read_order;
> +
> +/* Init parsed_symbol_read_order using symbol_read_order. Return true if
> + successful. */
> +
> +static bool
> +parse_symbol_read_order (void)
> +{
> + parsed_symbol_read_order.clear ();
> +
> + if (symbol_read_order.empty ())
> + return false;
> +
> + const char *s = symbol_read_order.c_str ();
> +
> + int prev_delim = -1;
> + for (int i = 0; i < symbol_read_order.size (); ++i)
> + {
> + char c = s[i];
> + if (c != '/' && c != '+')
> + continue;
> +
> + if (i == 0 || i == symbol_read_order.size () - 1)
> + /* Cannot begin or end with delimiter. */
> + return false;
> +
> + if (prev_delim != -1 && prev_delim == i - 1)
> + /* Cannot have two subsequent delimiters. */
> + return false;
> +
> + prev_delim = i;
> + }
> +
> + char s_dup[symbol_read_order.size ()];
> + strcpy (&s_dup[0], s);
> +
> + for (const char *p = s; *p != '\0'; ++p)
> + {
> + gdb_assert (*p != '/' && *p != '+');
> + char *token = strtok (p == s ? s_dup : nullptr, "/+");
> + gdb_assert (strlen (token) != 0);
> + enum symbol_type st;
> + if (!string_to_symbol_type (token, st))
> + {
> + parsed_symbol_read_order.clear ();
> + return false;
> + }
> + parsed_symbol_read_order.push_back (st);
> +
> + p += strlen (token);
> + if (*p == '\0')
> + {
> + parsed_symbol_read_order.push_back (sep);
> + break;
> + }
> +
> + if (*p == '+')
> + {
> + parsed_symbol_read_order.push_back (sep);
> + }
> + else if (*p == '/')
> + continue;
> + else
> + gdb_assert_not_reached ("");
> + }
> +
> + return true;
> +}
> +
> +static void
> +update_symbol_read_order (const char *args, int from_tty,
> + struct cmd_list_element *c)
> +{
> + if (!parse_symbol_read_order ())
> + {
> + warning ("invalid argument: '%s', reverting to default: '%s'",
> + symbol_read_order.c_str (), symbol_read_order_default.c_str ());
> + symbol_read_order = symbol_read_order_default;
> + bool res = parse_symbol_read_order ();
> + gdb_assert (res);
> + }
> +}
> +
> /* Dwarf-specific helper for elf_symfile_read. Return true if we managed to
> load dwarf debug info. */
>
> @@ -1270,6 +1417,12 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
> static void
> elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
> {
> + if (parsed_symbol_read_order.empty ())
> + {
> + bool res = parse_symbol_read_order ();
> + gdb_assert (res);
> + }
> +
> bfd *abfd = objfile->obfd.get ();
> struct elfinfo ei;
>
> @@ -1294,38 +1447,59 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
> we don't do this then the XCOFF info is found first - for code in
> an included file XCOFF info is useless. */
>
> - if (ei.mdebugsect)
> - {
> - const struct ecoff_debug_swap *swap;
> -
> - /* .mdebug section, presumably holding ECOFF debugging
> - information. */
> - swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
> - if (swap)
> - elfmdebug_build_psymtabs (objfile, swap, ei.mdebugsect);
> - }
> - if (ei.stabsect)
> + for (int i = 0; i < parsed_symbol_read_order.size (); ++i)
> {
> - asection *str_sect;
> -
> - /* Stab sections have an associated string table that looks like
> - a separate section. */
> - str_sect = bfd_get_section_by_name (abfd, ".stabstr");
> -
> - /* FIXME should probably warn about a stab section without a stabstr. */
> - if (str_sect)
> - elfstab_build_psymtabs (objfile,
> - ei.stabsect,
> - str_sect->filepos,
> - bfd_section_size (str_sect));
> - }
> -
> - bool has_dwarf2 = elf_symfile_read_dwarf2 (objfile, symfile_flags);
> + bool loaded_p = false;
> + switch (parsed_symbol_read_order[i])
> + {
> + case mdebug:
> + if (ei.mdebugsect)
> + {
> + const struct ecoff_debug_swap *swap;
> +
> + /* .mdebug section, presumably holding ECOFF debugging
> + information. */
> + swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
> + if (swap)
> + elfmdebug_build_psymtabs (objfile, swap, ei.mdebugsect);
> + loaded_p = true;
> + }
> + break;
> + case stabs:
> + if (ei.stabsect)
> + {
> + asection *str_sect;
> +
> + /* Stab sections have an associated string table that looks like
> + a separate section. */
> + str_sect = bfd_get_section_by_name (abfd, ".stabstr");
> +
> + /* FIXME should probably warn about a stab section without a stabstr. */
> + if (str_sect)
> + elfstab_build_psymtabs (objfile,
> + ei.stabsect,
> + str_sect->filepos,
> + bfd_section_size (str_sect));
> + loaded_p = true;
> + }
> + break;
> + case ctf:
> + if (ei.ctfsect)
> + {
> + elfctf_build_psymtabs (objfile);
> + loaded_p = true;
> + }
> + break;
> + case dwarf2:
> + loaded_p = elf_symfile_read_dwarf2 (objfile, symfile_flags);
> + }
>
> - /* Read the CTF section only if there is no DWARF info. */
> - if (!has_dwarf2 && ei.ctfsect)
> - {
> - elfctf_build_psymtabs (objfile);
> + if (loaded_p)
> + {
> + for (i++; i < parsed_symbol_read_order.size (); ++i)
> + if (parsed_symbol_read_order[i] == sep)
> + break;
> + }
> }
> }
>
> @@ -1420,4 +1594,13 @@ _initialize_elfread ()
> add_symtab_fns (bfd_target_elf_flavour, &elf_sym_fns);
>
> gnu_ifunc_fns_p = &elf_gnu_ifunc_fns;
> +
> + add_setshow_string_cmd ("symbol-read-order", class_maintenance,
> + &symbol_read_order, _("\
> +Set the symbol read order."), _(" \
> +Show the symbol read order."), nullptr,
> + update_symbol_read_order, nullptr,
> + &maintenance_set_cmdlist,
> + &maintenance_show_cmdlist);
> +
> }
> diff --git a/gdb/testsuite/gdb.ctf/dwarf2-and-ctf-2.c b/gdb/testsuite/gdb.ctf/dwarf2-and-ctf-2.c
> new file mode 100644
> index 00000000000..834c6d281ae
> --- /dev/null
> +++ b/gdb/testsuite/gdb.ctf/dwarf2-and-ctf-2.c
> @@ -0,0 +1,24 @@
> +/* 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 <http://www.gnu.org/licenses/>. */
> +
> +int var_ctf = 2;
> +
> +int
> +foo (void)
> +{
> + return var_ctf;
> +}
> diff --git a/gdb/testsuite/gdb.ctf/dwarf2-and-ctf.c b/gdb/testsuite/gdb.ctf/dwarf2-and-ctf.c
> new file mode 100644
> index 00000000000..d9bfc29dd6d
> --- /dev/null
> +++ b/gdb/testsuite/gdb.ctf/dwarf2-and-ctf.c
> @@ -0,0 +1,26 @@
> +/* 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 <http://www.gnu.org/licenses/>. */
> +
> +int var_dwarf = 1;
> +
> +extern int foo ();
> +
> +int
> +main (void)
> +{
> + return var_dwarf + foo ();
> +}
> diff --git a/gdb/testsuite/gdb.ctf/dwarf2-and-ctf.exp b/gdb/testsuite/gdb.ctf/dwarf2-and-ctf.exp
> new file mode 100644
> index 00000000000..2827babd00d
> --- /dev/null
> +++ b/gdb/testsuite/gdb.ctf/dwarf2-and-ctf.exp
> @@ -0,0 +1,54 @@
> +# 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 <http://www.gnu.org/licenses/>.
> +
> +standard_testfile .c -2.c
> +
> +set objfile [standard_output_file ${testfile}.o]
> +set objfile2 [standard_output_file ${testfile}-2.o]
> +
> +set s1 ${srcdir}/${subdir}/${srcfile}
> +set s2 ${srcdir}/${subdir}/${srcfile2}
> +
> +set opts {}
> +lappend opts debug
> +if { [gdb_compile $s1 ${objfile} object $opts] != "" } {
> + untested "failed to compile"
> + return -1
> +}
> +
> +set opts {}
> +lappend opts "additional_flags=-gctf"
> +if { [gdb_compile $s2 ${objfile2} object $opts] != "" } {
> + untested "failed to compile"
> + return -1
> +}
> +
> +set opts {}
> +lappend opts "additional_flags=-Wl,-ctf-variables"
> +if { [gdb_compile [list ${objfile} ${objfile2}] $binfile executable $opts] != "" } {
> + unsupported "failed to link"
> + return -1
> +}
> +
> +foreach_with_prefix order {dwarf2+ctf ctf+dwarf2} {
> + clean_restart
> +
> + gdb_test "maint set symbol-read-order $order"
> +
> + gdb_load $binfile
> +
> + gdb_test "print var_dwarf" " = 1"
> + gdb_test "print var_ctf" " = 2"
> +}
next prev parent reply other threads:[~2022-09-26 10:43 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-22 15:20 [PATCH 1/3] [gdb/symtab] Factor out elf_symfile_read_dwarf2 Tom de Vries
2022-09-22 15:20 ` [PATCH 2/3] [RFC][gdb/symtab] Add maint set symbol-read-order Tom de Vries
2022-09-26 10:43 ` Bruno Larsen [this message]
2023-02-24 12:42 ` Tom de Vries
2022-09-22 15:20 ` [PATCH 3/3] [gdb/testsuite] Fix ctf test-cases on openSUSE Tumbleweed Tom de Vries
2022-10-12 15:11 ` Tom de Vries
2022-10-12 15:08 ` [commited][PATCH 1/3] [gdb/symtab] Factor out elf_symfile_read_dwarf2 Tom de Vries
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=fa3c35aa-55e4-fa0e-67da-88270f4681ab@redhat.com \
--to=blarsen@redhat.com \
--cc=gdb-patches@sourceware.org \
--cc=tdevries@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).