Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: "Metzger, Markus T" <markus.t.metzger@intel.com>
To: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
Cc: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>,
	"Aktemur, Tankut Baris" <tankut.baris.aktemur@intel.com>
Subject: RE: [PATCH v2 10/47] gdb, gdbserver, ze: in-memory libraries
Date: Thu, 31 Jul 2025 06:09:39 +0000	[thread overview]
Message-ID: <DM8PR11MB5749E604DDD0073421BB8018DE27A@DM8PR11MB5749.namprd11.prod.outlook.com> (raw)
In-Reply-To: <878qkr1ou0.fsf@linaro.org>

Hello Thiago,

Thanks for your review.

>>  <!-- library-list: Root element with versioning -->
>> -<!ELEMENT library-list  (library)*>
>> -<!ATTLIST library-list  version CDATA   #FIXED  "1.0">
>> +<!ELEMENT library-list  (library | in-memory-library)*>
>> +<!ATTLIST library-list  version CDATA   #FIXED  "1.1">
>
>Theoretically, this would cause the parser to reject an XML unless it
>has version="1.1", despite the fact that GDB is still able to parse 1.0
>documents.  Therefore, this should just be changed to CDATA #REQUIRED,
>and we can rely on library_list_start_list to check if the version is
>acceptable.
>
>I said "theoretically" and "would" above because I experimented with it
>(actually, with <library-list-svr4> which is what I can test on Linux)
>and GDB didn't reject an XML reply with a tag that's not present in the
>DTD, and also it didn't care about the value of the version
>attribute. The DTD is simply ignored.
>
>Looking around a bit, I found a comment¹ by an Expat maintainer
>saying:
>
>> The thing is: Expat is a non-validating XML parser.
>
>So I'm not sure what purpose the DTDs have in GDB. Perhaps they're just
>part of the documentation?
>
>If the DTD was enforced, it would be ok to keep version at 1.0 since an
>old GDB would reject a library-list document with in-memory-library
>elements because it wouldn't conform to the expected DTD. As it is
>though, it looks like the version bump is indeed necessary.

IIUC you want this to remain as it is.

>There's another version bump elsewhere in this series though, which I
>think isn't really needed in practice — will there ever be a version of
>GDB in the field which supports version 1.1 but not 1.2?

I don't expect that.  I'll remove the other bump and stay at 1.1.

>> @@ -246,10 +295,35 @@ solib_target_current_sos (void)
>>    for (lm_info_target_up &info : library_list)
>>      {
>>        auto &new_solib = sos.emplace_back ();
>> +      switch (info->location)
>> +	{
>> +	case lm_on_disk:
>> +	  /* We don't need a copy of the name in INFO anymore.  */
>> +	  new_solib.so_name = std::move (info->name);
>> +	  new_solib.so_original_name = new_solib.so_name;
>> +	  break;
>> +
>> +	case lm_in_memory:
>> +	  {
>> +	    if (info->end <= info->begin)
>> +	      error (_("bad in-memory-library location: begin=%s, end=%s"),
>> +		     core_addr_to_string_nz (info->begin),
>> +		     core_addr_to_string_nz (info->end));
>
>Is erroring out better than printing a warning and skipping the bad
>library entry?

Makes sense.  The rest would still work.

>> +	    /* Give it a name although this isn't really needed.  */
>> +	    std::string orig_name
>> +	      = std::string ("in-memory-")
>> +	      + core_addr_to_string_nz (info->begin)
>> +	      + "-"
>> +	      + core_addr_to_string_nz (info->end);
>> +
>> +	    new_solib.so_original_name = orig_name;
>
>I know less about C++ than I would like: would it be better to use
>std::move (orig_name) here, or can we rely on the compiler being smart
>enough to notice that it doesn't need orig_name after this line and
>avoid a copy? If you don't know either, I'd add an std::move just to be
>sure.

We don't really need that local variable.

>> @@ -40,6 +40,17 @@ loaded_dll (process_info *proc, const char *name,
>CORE_ADDR base_addr)
>>    proc->dlls_changed = true;
>>  }
>>
>> +/* Record a newly loaded in-memory DLL at BASE_ADDR for PROC.  */
>
>You should also document the BEGIN and END arguments. In particular, I'm
>interested in learning the difference between BEGIN and BASE_ADDR.

I documented the corresponding fields in struct dll_info.

The arguments of all those functions directly correspond to those fields.
If it is OK, I would not repeat the documentation.

>> +void
>> +loaded_dll (process_info *proc, CORE_ADDR begin, CORE_ADDR end,
>> +	    CORE_ADDR base_addr)
>> +{
>> +  gdb_assert (proc != nullptr);
>> +  proc->all_dlls.emplace_back (begin, end, base_addr);
>> +  proc->dlls_changed = true;
>> +}
>
>Even though both versions of loaded_dll are small, it's a bit
>unfortunate that they're almost identical. This is because of the choice
>to have two constructors for dll_info and the location member being
>initialized depending on which one is called. I understand that design
>choice, but given that it leads to this duplication of code I think it's
>better to have location explicit in the constructor (or a new
>constructor with location explicitly passed in it) and then one version
>of loaded_dll can simply call the other one (or both can call a third,
>internal loaded_dll version) with an explicit location argument.

It's not just the location.  They would also need to provide all the
arguments that are only relevant for the other location.

And if we ever added a third location type (a section in a fat binary,
maybe), we'd need to touch all that code again to add arguments
for that new type.

I could add a check_ack() function to contain

  if (need_ack && !get_client_state ().vack_library_supported)
    throw_error (NOT_SUPPORTED_ERROR,
		 _("library acknowledgement not supported."));

if that helps.

>> +void
>> +unloaded_dll (process_info *proc, CORE_ADDR begin, CORE_ADDR end,
>> +	      CORE_ADDR base_addr)
>> +{
>> +  gdb_assert (proc != nullptr);
>> +  auto pred = [&] (const dll_info &dll)
>> +    {
>> +      if (dll.location != dll_info::in_memory)
>> +	return false;
>> +
>> +      if (base_addr != UNSPECIFIED_CORE_ADDR
>> +	  && base_addr == dll.base_addr)
>> +	return true;
>> +
>> +      /* We do not require the end address to be specified - we don't
>> +	 support partially unloaded libraries, anyway.  */
>> +      if (begin != UNSPECIFIED_CORE_ADDR
>> +	  && begin == dll.begin
>> +	  && (end == UNSPECIFIED_CORE_ADDR
>> +	      || end == dll.end))
>> +	return true;
>> +
>> +      return false;
>> +    };
>> +
>> +  auto iter = std::find_if (proc->all_dlls.begin (), proc->all_dlls.end (),
>> +			    pred);
>> +
>> +  if (iter == proc->all_dlls.end ())
>> +    /* For some inferiors we might get unloaded_dll events without having
>> +       a corresponding loaded_dll.  In that case, the dll cannot be found
>> +       in ALL_DLL, and there is nothing further for us to do.  */
>> +    return;
>> +  else
>> +    {
>> +      /* DLL has been found so remove the entry and free associated
>> +	 resources.  */
>> +      proc->all_dlls.erase (iter);
>> +      proc->dlls_changed = 1;
>> +    }
>> +}
>
>Here the duplication problem between the two versions of unloaded_dll is
>worse. It's possible do define an unloaded_dll_1 internal function with
>the code above and getting an dll_info::location_t as argument that is
>called by both versions of unloaded_dll.

The predicate is different for the two versions.  I added a function that
takes the predicate as input.

>> +  location_t location;
>>    std::string name;
>> +  CORE_ADDR begin;
>
>Here too it would be nice to have a comment explaining the difference
>between begin and base_addr.

That's where I added the comments describing the fields.

>> +{
>> +  if (dll.end <= dll.begin)
>> +    error (_("bad in-memory-library location: begin=%s, end=%s"),
>> +	   core_addr_to_string_nz (dll.begin),
>> +	   core_addr_to_string_nz (dll.end));
>> +
>> +  gdb::byte_vector buffer (dll.end - dll.begin);
>> +  int errcode = gdb_read_memory (dll.begin, buffer.data (), buffer.size ());
>> +  if (errcode != 0)
>> +    error (_("failed to read in-memory library at %s..%s"),
>> +	   core_addr_to_string_nz (dll.begin),
>> +	   core_addr_to_string_nz (dll.end));
>> +
>> +  std::string name
>> +    = std::string ("gdb-in-memory-solib-")
>> +    + core_addr_to_string_nz (dll.begin)
>> +    + "-"
>> +    + core_addr_to_string_nz (dll.end);
>> +
>> +  gdb_file_up file = gdb_create_tmpfile (name);
>
>This is the only use of gdb_create_tmpfile. I think that instead of
>having files that will be deleted when gdbserver exits, it would be
>better if the files were deleted when they aren't necessary anymore.
>
>gdb_create_tmpfile could return not only a gdb_file_up, but also a
>gdb::unlinker (in an std::pair, I suppose). Then dll_to_tmpfile could
>add it to new member of dll_info with type
>std::optional<gdb::unlinker>. Thus, when the dll_info object is
>destroyed, the tmp file will be deleted. WDYT?
>
>Also, this could be a dll_info::to_tmpfile method instead of a separate
>function.

That sounds good and would make patch 9 obsolete.

>> +static std::string
>> +library_list_version_needed (const std::list<dll_info> &dlls)
>> +{
>> +  const client_state &cs = get_client_state ();
>> +  int major = 1, minor = 0;
>> +
>> +  for (const dll_info &dll : dlls)
>> +    {
>> +      switch (dll.location)
>> +	{
>> +	case dll_info::on_disk:
>> +	  major = std::max (major, 1);
>> +	  minor = std::max (minor, 0);
>> +	  break;
>> +
>> +	case dll_info::in_memory:
>> +	  if (cs.in_memory_library_supported)
>> +	    {
>> +	      major = std::max (major, 1);
>> +	      minor = std::max (minor, 1);
>> +	    }
>> +	  break;
>> +	}
>> +    }
>> +
>> +  return std::to_string (major) + std::string (".") + std::to_string (minor);
>> +}
>
>This makes the version depend on what the currnet list of dll_infos
>needs, not just on the features supported by GDB or gdbserver. If
>there's no in-memory library loaded, then the XML will be version
>1.0. If later an in-memory library is loaded, then the next XML will be
>version 1.1
>
>I expected the version to depend just on the features advertised by GDB
>and gdbserver, so I was a bit surprised. I don't think this is a
>problem, but I just mention here in case someone has an opinion about
>it.

This may be overengineered.  It allows gdbserver with in-memory library
support to work with older GDBs that do not support it.  For our use-case,
such a GDB would not support our architecture, anyway.  From a general
feature perspective, though, it may make sense.

If maintainers agree that we do not want this flexibility, all this tempfile
stuff will go away, simplifying the series a bit.

>> diff --git a/gdb/remote.c b/gdb/remote.c
>> index
>f41129915683194237d1bba56d17df61ae89c063..7d074a5df322d68ded8f96c4
>832bc8c247435a4f 100644
>> --- a/gdb/remote.c
>> +++ b/gdb/remote.c
>> @@ -5956,6 +5956,9 @@ remote_target::remote_query_supported ()
>>  	  != AUTO_BOOLEAN_FALSE)
>>  	remote_query_supported_append (&q, "memory-tagging+");
>>
>> +      remote_query_supported_append
>> +	(&q, "qXfer:libraries:read:in-memory-library+");
>
>This is the only feature in this function that isn't guarded by a "set
>remote foo-packet" command state. Shouldn't it?

This is not a new packet.  This indicates support for a new element in the
qXfer::libraries::read response.

Regards,
Markus.
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928

  reply	other threads:[~2025-07-31  6:11 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-13 15:59 [PATCH v2 00/47] A new target to debug Intel GPUs Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 01/47] gdb, intelgt: add intelgt as a basic machine Tankut Baris Aktemur
2024-12-16  7:53   ` Jan Beulich
2024-12-17 18:48     ` Aktemur, Tankut Baris
2024-12-18  7:19       ` Jan Beulich
2024-12-20  9:55         ` Aktemur, Tankut Baris
2025-02-03 17:17           ` Aktemur, Tankut Baris
2025-02-04  7:06             ` Jan Beulich
2024-12-13 15:59 ` [PATCH v2 02/47] bfd: add intelgt target to BFD Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 03/47] ld: add intelgt as a target configuration Tankut Baris Aktemur
2024-12-16  7:43   ` Jan Beulich
2024-12-13 15:59 ` [PATCH v2 04/47] opcodes: add intelgt as a configuration Tankut Baris Aktemur
2024-12-16  7:44   ` Jan Beulich
2024-12-17 18:47     ` Aktemur, Tankut Baris
2024-12-18  7:22       ` Jan Beulich
2024-12-20  9:47         ` Aktemur, Tankut Baris
2025-01-03  4:46           ` Simon Marchi
2025-02-03 17:13             ` Aktemur, Tankut Baris
2025-02-04  7:07               ` Jan Beulich
2024-12-13 15:59 ` [PATCH v2 05/47] gdb, arch, intelgt: add intelgt arch definitions Tankut Baris Aktemur
2025-07-08  3:03   ` Thiago Jung Bauermann
2025-07-21 10:49     ` Aktemur, Tankut Baris
2024-12-13 15:59 ` [PATCH v2 06/47] gdb, intelgt: add the target-dependent definitions for the Intel GT architecture Tankut Baris Aktemur
2025-07-08  2:43   ` Thiago Jung Bauermann
2025-07-18 17:43     ` Aktemur, Tankut Baris
2024-12-13 15:59 ` [PATCH v2 07/47] gdb, gdbserver, gdbsupport: add 'device' tag to XML target description Tankut Baris Aktemur
2024-12-13 16:45   ` Eli Zaretskii
2025-07-08  4:04   ` Thiago Jung Bauermann
2025-07-21 10:49     ` Aktemur, Tankut Baris
2024-12-13 15:59 ` [PATCH v2 08/47] gdb, intelgt: add disassemble feature for the Intel GT architecture Tankut Baris Aktemur
2025-07-09  3:12   ` Thiago Jung Bauermann
2024-12-13 15:59 ` [PATCH v2 09/47] gdbsupport, filestuff, ze: temporary files Tankut Baris Aktemur
2025-07-14  1:26   ` Thiago Jung Bauermann
2024-12-13 15:59 ` [PATCH v2 10/47] gdb, gdbserver, ze: in-memory libraries Tankut Baris Aktemur
2025-07-14  2:35   ` Thiago Jung Bauermann
2025-07-31  6:09     ` Metzger, Markus T [this message]
2025-07-16  4:08   ` Thiago Jung Bauermann
2024-12-13 15:59 ` [PATCH v2 11/47] gdb, gdbserver, rsp, ze: acknowledge libraries Tankut Baris Aktemur
2024-12-13 16:43   ` Eli Zaretskii
2025-07-16  4:20   ` Thiago Jung Bauermann
2025-07-31  6:09     ` Metzger, Markus T
2024-12-13 15:59 ` [PATCH v2 12/47] gdb, solib, ze: solib_bfd_open_from_target_memory Tankut Baris Aktemur
2025-07-18  0:42   ` Thiago Jung Bauermann
2024-12-13 15:59 ` [PATCH v2 13/47] gdb, remote, ze: fix "$Hc-1#09...Packet received: E01" during startup Tankut Baris Aktemur
2025-07-18  0:41   ` Thiago Jung Bauermann
2025-08-01  7:55     ` Metzger, Markus T
2024-12-13 15:59 ` [PATCH v2 14/47] gdb, infrun, ze: allow saving process events Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 15/47] gdb, ze: add TARGET_WAITKIND_UNAVAILABLE Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 16/47] gdb, infrun, ze: handle stopping unavailable threads Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 17/47] gdb, infrun, ze: allow resuming " Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 18/47] gdb, gdbserver, ze: add U stop reply Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 19/47] gdb, gdbserver, ze: add library notification to " Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 20/47] gdbserver, ze: report TARGET_WAITKIND_UNAVAILABLE events Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 21/47] gdb, ze: handle TARGET_WAITKIND_UNAVAILABLE in stop_all_threads Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 22/47] gdb, remote: handle thread unavailability in print_one_stopped_thread Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 23/47] gdb, remote: do 'remote_add_inferior' in 'remote_notice_new_inferior' earlier Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 24/47] gdb, remote: handle a generic process PID in remote_notice_new_inferior Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 25/47] gdb, remote: handle a generic process PID in process_stop_reply Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 26/47] gdb: use the pid from inferior in setup_inferior Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 27/47] gdb: revise the pid_to_exec_file target op Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 28/47] gdb: load solibs if the target does not have the notion of an exec file Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 29/47] gdbserver: import AC_LIB_HAVE_LINKFLAGS macro into the autoconf script Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 30/47] gdbserver: add a pointer to the owner thread in regcache Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 31/47] gdbserver: dump 'xx...x' in collect_register_as_string for unavailable register Tankut Baris Aktemur
2024-12-23 11:38   ` Aktemur, Tankut Baris
2024-12-23 13:47     ` Luis Machado
2024-12-13 15:59 ` [PATCH v2 32/47] gdbserver: wait for stopped threads in queue_stop_reply_callback Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 33/47] gdbserver: adjust pid after the target attaches Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 34/47] gdb: do not create a thread after a process event Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 35/47] gdb, ze: on a whole process stop, mark all threads as not_resumed Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 36/47] gdb, dwarf, ze: add DW_OP_INTEL_regval_bits Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 37/47] gdbserver: allow configuring for a heterogeneous target Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 38/47] gdbserver, ze, intelgt: introduce ze-low and intel-ze-low targets Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 39/47] testsuite, sycl: add SYCL support Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 40/47] testsuite, sycl: add test for backtracing inside a kernel Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 41/47] testsuite, sycl: add test for 'info locals' and 'info args' Tankut Baris Aktemur
2024-12-13 15:59 ` [PATCH v2 42/47] testsuite, sycl: add tests for stepping and accessing data elements Tankut Baris Aktemur
2024-12-13 16:00 ` [PATCH v2 43/47] testsuite, sycl: add test for 1-D and 2-D parallel_for kernels Tankut Baris Aktemur
2024-12-13 16:00 ` [PATCH v2 44/47] testsuite, sycl: add test for scheduler-locking Tankut Baris Aktemur
2024-12-13 16:00 ` [PATCH v2 45/47] testsuite, arch, intelgt: add a disassembly test Tankut Baris Aktemur
2024-12-13 16:00 ` [PATCH v2 46/47] testsuite, arch, intelgt: add intelgt-program-bp.exp Tankut Baris Aktemur
2024-12-13 16:00 ` [PATCH v2 47/47] testsuite, sycl: test canceling a stepping flow Tankut Baris Aktemur
2025-02-07 10:18 ` [PATCH v2 00/47] A new target to debug Intel GPUs Aktemur, Tankut Baris
2025-05-08  7:40   ` Aktemur, Tankut Baris
2025-05-26  8:03     ` Aktemur, Tankut Baris
2025-06-17 12:22       ` Aktemur, Tankut Baris
2025-07-03 12:55   ` Aktemur, Tankut Baris

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=DM8PR11MB5749E604DDD0073421BB8018DE27A@DM8PR11MB5749.namprd11.prod.outlook.com \
    --to=markus.t.metzger@intel.com \
    --cc=gdb-patches@sourceware.org \
    --cc=tankut.baris.aktemur@intel.com \
    --cc=thiago.bauermann@linaro.org \
    /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