Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@palves.net>
To: Simon Marchi <simon.marchi@polymtl.ca>, gdb-patches@sourceware.org
Cc: Simon Marchi <simon.marchi@efficios.com>
Subject: Re: [PATCH 02/11] gdb: introduce intrusive_list, make thread_info use it
Date: Mon, 5 Jul 2021 16:44:48 +0100	[thread overview]
Message-ID: <2466c5e0-36f4-ce47-f05f-022cda04bb04@palves.net> (raw)
In-Reply-To: <20210622165704.2404007-3-simon.marchi@polymtl.ca>

Hi!

This looks mostly good to me, though I'm biased...

On 2021-06-22 5:56 p.m., Simon Marchi wrote:
> From: Pedro Alves <pedro@palves.net>
> 
> GDB currently has several objects that are put in a singly linked list,
> by having the object's type have a "next" pointer directly.  For
> example, struct thread_info and struct inferior.  Because these are
> simply-linked lists, and we don't keep track of a "tail" pointer, when
> we want to append a new element on the list, we need to walk the whole
> list to find the current tail.  It would be nice to get rid of that
> walk.  Removing elements from such lists also requires a walk, to find
> the "previous" position relative to the element being removed.  To
> eliminate the need for that walk, we could make those lists
> doubly-linked, by adding a "prev" pointer alongside "next".  It would be
> nice to avoid the boilerplace associated with maintaining such a list

boilerplace -> boilerplate

> manually, though.  That is what the new intrusive_list type addresses.

...

> 
> Unlike Boost's implementation, ours is not a circular list.  An earlier
> version of the patch was circular: the instrusive_list type included an

instrusive_list -> intrusive_list

> intrusive_list_node "head".  In this design, a node contained pointers
> to the previous and next nodes, not the previous and next elements.
> This wasn't great for when debugging GDB with GDB, as it was difficult
> to get from a pointer to the node to a pointer to the element.  With the
> design proposed in this patch, nodes contain pointers to the previous
> and next elements, making it easy to traverse the list by hand and
> inspect each element.
> 

...

> 
> Add a Python pretty-printer, to help inspecting intrusive lists when
> debugging GDB with GDB.  Here's an example of the output:
> 
>     (top-gdb) p current_inferior_.m_obj.thread_list
>     $1 = intrusive list of thread_info = {0x61700002c000, 0x617000069080, 0x617000069400, 0x61700006d680, 0x61700006eb80}
> 

Did you find this output helpful in practice?  Printing the whole object is
for sure too much, but I wonder whether printing the thread id, and ptid and
perhaps the thread state wouldn't be more helpful, like:

 $1 = intrusive list of thread_info = {
   {id = 1.1, ptid = 1000.1000.0, state = THREAD_RUNNING}, 
   {id = 1.3, ptid = 1000.1002.0, state = THREAD_STOPPED},
   {id = 1.5, ptid = 1000.3672.0, state = THREAD_STOPPED}
 }

> It's not possible with current master, but with this patch [1] that I
> hope will be merged eventually, it's possible to index the list and
> access the pretty-printed value's children:
> 
>     (top-gdb) p current_inferior_.m_obj.thread_list[1]
>     $2 = (thread_info *) 0x617000069080
>     (top-gdb) p current_inferior_.m_obj.thread_list[1].ptid
>     $3 = {
>       m_pid = 406499,
>       m_lwp = 406503,
>       m_tid = 0
>     }

I guess in practice I'd always want to print the list
with "set print array-indexes on".  Otherwise, how would you know
which index to pass to []?  And still, with just pointers/addresses
in the output, I'm not sure I'd easily know which index to pass:

 $1 = intrusive list of struct thread_info = {[0] = 0x5555564d0f60, [1] = 0x5555572ad640, [2] = 0x5555572ad9f0}

?

I mean, one can eyeball for the right entry based on thread_info
pointer/address, but if one already has the pointer/address handy, then
one wouldn't need to search for the entry in the thread list in the first
place, right?

It does seem to make it a bit easier to iterate over the whole list
printing each element, easier than following the next->next->next
pointers.  Was that the use case you had in mind?

With the alternative output suggested above, we'd have:

 $1 = intrusive list of thread_info = {
   [0] = {id = 1.1, ptid = 1000.1000.0, state = THREAD_RUNNING}, 
   [1] = {id = 1.3, ptid = 1000.1002.0, state = THREAD_STOPPED},
   [2] = {id = 1.5, ptid = 1000.3672.0, state = THREAD_STOPPED}
 }

Off hand, I think I'd find this more useful.  I'm assuming that
using [] with Andrew's patch would still work the same way.

I guess this would be implemented by passing some customization
object or function to the pretty printer, that it would call to
print each element.  If no such customization is passed, then
it would just print what you have.  So I guess this could always
be done separately...

> +++ b/gdb/unittests/intrusive_list-selftests.c

Yay, unit tests!  Thanks a lot for writing them.

> @@ -0,0 +1,734 @@
> +/* Tests fpr intrusive double linked list for GDB, the GNU debugger.
> +   Copyright (C) 2021 Free Software Foundation, Inc.
> +
> +   This file is part of GDB.
> +
> +   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/>.  */
> +
> +#include "defs.h"
> +
> +#include "gdbsupport/intrusive_list.h"
> +#include "gdbsupport/selftest.h"
> +#include <unordered_set>
> +
> +/* An item type using intrusive_list_node by inheriting from it and its
> +   corresponding list type.  Put another base before intrusive_list_node
> +   so that a pointer to the node != a pointer to the item.  */
> +
> +struct other_base
> +{
> +  int n = 1;
> +};
> +
> +struct item_with_base : public other_base,
> +			public intrusive_list_node<item_with_base>
> +{
> +  item_with_base (const char *name)

explicit

> +    : name (name)
> +  {}
> +
> +  const char *const name;
> +};
> +
> +using item_with_base_list = intrusive_list<item_with_base>;
> +
> +/* An item type using intrusive_list_node as a field and its corresponding
> +   list type.  Put the other field before the node, so that a pointer to the
> +   node != a pointer to the item.  */
> +
> +struct item_with_member
> +{
> +  item_with_member (const char *name)

explicit

> diff --git a/gdbsupport/intrusive_list.h b/gdbsupport/intrusive_list.h
> new file mode 100644
> index 000000000000..8e98e5b2c1a5
> --- /dev/null
> +++ b/gdbsupport/intrusive_list.h
> @@ -0,0 +1,559 @@
> +/* Intrusive double linked list for GDB, the GNU debugger.
> +   Copyright (C) 2021 Free Software Foundation, Inc.
> +
> +   This file is part of GDB.
> +
> +   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/>.  */
> +
> +#ifndef GDBSUPPORT_INTRUSIVE_LIST_H
> +#define GDBSUPPORT_INTRUSIVE_LIST_H
> +
> +#define UNLINKED_VALUE ((T *) -1)

UNLINKED_VALUE seems like a too-generic name for a macro.
I think it'd be better to add some prefix to minimize
potential for conflict.  INTR_LIST_UNLINKED_VALUE
or some such.

  parent reply	other threads:[~2021-07-05 15:45 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-22 16:56 [PATCH 00/11] Various thread lists optimizations Simon Marchi via Gdb-patches
2021-06-22 16:56 ` [PATCH 01/11] gdb: introduce iterator_range, remove next_adapter Simon Marchi via Gdb-patches
2021-07-05 15:41   ` Pedro Alves
2021-07-06 19:16     ` Simon Marchi via Gdb-patches
2021-06-22 16:56 ` [PATCH 02/11] gdb: introduce intrusive_list, make thread_info use it Simon Marchi via Gdb-patches
2021-06-22 23:13   ` Lancelot SIX via Gdb-patches
2021-06-23  0:48     ` Simon Marchi via Gdb-patches
2021-07-05 15:44   ` Pedro Alves [this message]
2021-07-06 19:38     ` Simon Marchi via Gdb-patches
2021-07-06 20:45       ` Simon Marchi via Gdb-patches
2021-07-06 21:04         ` Pedro Alves
2021-07-06 21:38           ` Simon Marchi via Gdb-patches
2021-07-06 21:02       ` Pedro Alves
2021-07-06 21:45         ` Simon Marchi via Gdb-patches
2021-07-07 11:46           ` Pedro Alves
2021-07-07 13:52             ` Simon Marchi via Gdb-patches
2021-06-22 16:56 ` [PATCH 03/11] gdb: make inferior_list use intrusive_list Simon Marchi via Gdb-patches
2021-07-05 15:44   ` Pedro Alves
2021-07-14  6:34     ` Tom de Vries
2021-07-14 16:11       ` Simon Marchi via Gdb-patches
2021-07-14 20:15         ` [PATCH] gdb: make all_inferiors_safe actually work Simon Marchi via Gdb-patches
2021-07-15 10:15           ` Tom de Vries
2021-07-17 12:54             ` Simon Marchi via Gdb-patches
2021-06-22 16:56 ` [PATCH 04/11] gdb: use intrusive list for step-over chain Simon Marchi via Gdb-patches
2021-07-05 15:45   ` Pedro Alves
2021-07-06 20:59     ` Simon Marchi via Gdb-patches
2021-06-22 16:56 ` [PATCH 05/11] gdb: add setter / getter for thread_info resumed state Simon Marchi via Gdb-patches
2021-07-05 15:45   ` Pedro Alves
2021-06-22 16:56 ` [PATCH 06/11] gdb: make thread_info::suspend private, add getters / setters Simon Marchi via Gdb-patches
2021-07-05 15:45   ` Pedro Alves
2021-06-22 16:57 ` [PATCH 07/11] gdb: maintain per-process-target list of resumed threads with pending wait status Simon Marchi via Gdb-patches
2021-07-05 15:51   ` Pedro Alves
2021-07-06 21:25     ` Simon Marchi via Gdb-patches
2021-07-07 12:01       ` Pedro Alves
2021-07-12 22:28         ` Simon Marchi via Gdb-patches
2021-07-12 22:34           ` Simon Marchi via Gdb-patches
2021-07-13 12:21           ` Pedro Alves
2021-06-22 16:57 ` [PATCH 08/11] gdb: optimize check for resumed threads with pending wait status in maybe_set_commit_resumed_all_targets Simon Marchi via Gdb-patches
2021-07-05 15:51   ` Pedro Alves
2021-06-22 16:57 ` [PATCH 09/11] gdb: optimize selection of resumed thread with pending event Simon Marchi via Gdb-patches
2021-07-05 15:51   ` Pedro Alves
2021-06-22 16:57 ` [PATCH 10/11] gdb: maintain ptid -> thread map, optimize find_thread_ptid Simon Marchi via Gdb-patches
2021-07-05 15:52   ` Pedro Alves
2021-07-06 21:31     ` Simon Marchi via Gdb-patches
2021-07-07 12:13       ` Pedro Alves
2021-06-22 16:57 ` [PATCH 11/11] gdb: optimize all_matching_threads_iterator Simon Marchi via Gdb-patches
2021-07-05 15:52   ` Pedro Alves
2021-07-14  9:40     ` Tom de Vries
2021-07-13  0:47 ` [PATCH 00/11] Various thread lists optimizations Simon Marchi via Gdb-patches

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=2466c5e0-36f4-ce47-f05f-022cda04bb04@palves.net \
    --to=pedro@palves.net \
    --cc=gdb-patches@sourceware.org \
    --cc=simon.marchi@efficios.com \
    --cc=simon.marchi@polymtl.ca \
    /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