From patchwork Thu Nov 3 14:42:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 59841 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id F0942385841C for ; Thu, 3 Nov 2022 14:43:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F0942385841C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1667486594; bh=uVyna/tEYSq45Xa50Q/Q5NwYp6KxTbWMQf9vJSDBqpU=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=lFJSXUf6LkpcXKBGylRjUTvfZY73u0buzjT0OSaL6DEQvWPW4EsNGKiQMncFog8A/ AZ5AfvRx/ATQ5uOfN13YPXt2YDkytpXFbc62+VNrZRnVwUuTX0H+PIO9DYOvGUsE2t nuoPRandxMNyhp4bzw5dbtoeTptDjrznAu48MlBw= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org 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 8895F3858D35 for ; Thu, 3 Nov 2022 14:42:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8895F3858D35 Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-462-7H2h0DcPMK6gMstEnk30Mw-1; Thu, 03 Nov 2022 10:42:45 -0400 X-MC-Unique: 7H2h0DcPMK6gMstEnk30Mw-1 Received: by mail-wm1-f72.google.com with SMTP id 187-20020a1c02c4000000b003cf8e70c1ecso15637wmc.4 for ; Thu, 03 Nov 2022 07:42:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uVyna/tEYSq45Xa50Q/Q5NwYp6KxTbWMQf9vJSDBqpU=; b=okHn7LFUlhTurRFvJLGIcFnYvtd+QRai1D5VH3gS6vFP9sDZX4S7puUOw9JJ5wUqFi 8XwOzqt0HinfYjgt8Sp0SdFRFtoTqQB3dOEGn2fTvxY3YebOFDgzhXW7/KXtAMIpKBHO Dy8p+rBZFGlgzV2gAE7b+gXH9egRgD6EBWQcjWuy033RY9r6YHMwzysB3NVrtE53vSmM MplrLCrhgXdEVYpv5izpPJVXUr2jqyOYC7GmoOA7wgRc7wHPgrnjxfRI84YvTs1IPvF0 kPDw2JxfaXcN6hVw3KVea5XCjVMBzoo4OZSzXKZHji8/6Ec2Hb5IZpuTbYJsVX8AcgVa ktkQ== X-Gm-Message-State: ACrzQf0yi16ZmPA7NqZlLlHuBnp5r48zx3kG8Quqp/F2zhtV8n9AkRQ2 ic4ksSpvxr46B0y0QXxkwQrb3uz+4QnZ6uMYZLjALC5uiQ53mQ1fwsGuFd9w6E7AyhkQ5qF3fDC +qIMIJ2HSJWZIUFIJIcOOfGIxOctU16KMJI1++T6+dN9ywmuY87ZdVeOoNyee4no+7zu67xn0Yg == X-Received: by 2002:a05:600c:4448:b0:3c6:fb65:2462 with SMTP id v8-20020a05600c444800b003c6fb652462mr20084660wmn.39.1667486563551; Thu, 03 Nov 2022 07:42:43 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4jLCWJDjQ9uYHDFv4rhzqS0xEJMVUv64kZegnFUCStrFk7vKNp6I1prZ94urSUV8XoOngEcw== X-Received: by 2002:a05:600c:4448:b0:3c6:fb65:2462 with SMTP id v8-20020a05600c444800b003c6fb652462mr20084639wmn.39.1667486563177; Thu, 03 Nov 2022 07:42:43 -0700 (PDT) Received: from localhost ([31.111.84.238]) by smtp.gmail.com with ESMTPSA id j7-20020a05600c190700b003b477532e66sm8228113wmq.2.2022.11.03.07.42.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Nov 2022 07:42:42 -0700 (PDT) To: gdb-patches@sourceware.org Subject: [PATCHv2] gdb: new $_inferior_thread_count convenience variable Date: Thu, 3 Nov 2022 14:42:39 +0000 Message-Id: <20221103144239.98993-1-aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20221102143416.3307157-1-aburgess@redhat.com> References: <20221102143416.3307157-1-aburgess@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, 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 X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Andrew Burgess via Gdb-patches From: Andrew Burgess Reply-To: Andrew Burgess Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Simon, Luis, thanks for your feedback. Changes since v1: 1. Rename variable to $_inferior_thread_count. 2. Use "live" in the docs and NEWS file to describe the threads being counted. I do still use "non-exited" within the commit message and comments, as this is how "live" is actually implemented within GDB. 3. Updated the docs to mention that in non-stop mode the value of $_inferior_thread_count will not be stable. Thanks, Andrew --- Add a new convenience variable $_inferior_thread_count that contains the number of live (non-exited) threads in the current inferior. This can be used in command scripts, or breakpoint conditions, etc to adjust the behaviour for multi-threaded inferiors. This value is only stable in all-stop mode. In non-stop mode, where new threads can be started, and existing threads exit, at any time, this convenience variable can give a different value each time it is evaluated. --- gdb/NEWS | 3 +++ gdb/doc/gdb.texinfo | 14 ++++++++++++-- gdb/testsuite/gdb.base/default.exp | 1 + gdb/testsuite/gdb.multi/tids.exp | 20 ++++++++++++++++++++ gdb/thread.c | 26 ++++++++++++++++++++++++++ gdbsupport/iterator-range.h | 4 ++++ 6 files changed, 66 insertions(+), 2 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index 8b519a648f7..8857dedb8b8 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -71,6 +71,9 @@ For both /r and /b GDB is now better at using whitespace in order to align the disassembled instruction text. +* New convenience variable $_inferior_thread_count contains the number + of live threads in the current inferior. + * New commands maintenance set ignore-prologue-end-flag on|off diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index ea66f4ee42d..82f7fd66bf0 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -3642,8 +3642,15 @@ @samp{$_gthread} contain, respectively, the per-inferior thread number and the global thread number of the current thread. You may find this useful in writing breakpoint conditional expressions, command scripts, -and so forth. @xref{Convenience Vars,, Convenience Variables}, for -general information on convenience variables. +and so forth. The convenience variable @samp{$_inferior_thread_count} +contains the number of live threads in the current inferior. +@xref{Convenience Vars,, Convenience Variables}, for general +information on convenience variables. + +When running in non-stop mode (@pxref{Non-Stop Mode}), where new +threads can be created, and existing threads exit, at any time, +@samp{$_inferior_thread_count} could return a different value each +time it is evaluated. If @value{GDBN} detects the program is multi-threaded, it augments the usual message about stopping at a breakpoint with the ID and name of @@ -12655,6 +12662,9 @@ @item $_gthread The global number of the current thread. @xref{global thread numbers}. +@item $_inferior_thread_count +The number of live threads in the current inferior. @xref{Threads}. + @item $_gdb_major @itemx $_gdb_minor @vindex $_gdb_major@r{, convenience variable} diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp index 29e76642830..f3e4b2867ef 100644 --- a/gdb/testsuite/gdb.base/default.exp +++ b/gdb/testsuite/gdb.base/default.exp @@ -584,6 +584,7 @@ set show_conv_list \ {$_thread = 0} \ {$_gthread = 0} \ {$_inferior = 1} \ + {$_inferior_thread_count = 0} \ {$_exception = } \ {$_probe_argc = } \ {$_probe_arg0 = } \ diff --git a/gdb/testsuite/gdb.multi/tids.exp b/gdb/testsuite/gdb.multi/tids.exp index fb7c2a29a71..23668caf18f 100644 --- a/gdb/testsuite/gdb.multi/tids.exp +++ b/gdb/testsuite/gdb.multi/tids.exp @@ -123,6 +123,8 @@ with_test_prefix "single inferior" { info_threads "" "1" gdb_test "thread" "Current thread is 1 .*" + + gdb_test "print \$_inferior_thread_count" " = 1" } # "info threads" while there are multiple inferiors should show @@ -140,8 +142,14 @@ with_test_prefix "two inferiors" { gdb_test "inferior 2" "Switching to inferior 2 .*" "switch to inferior 2" gdb_test "file ${binfile}" ".*" "load file in inferior 2" + gdb_test "print \$_inferior_thread_count" " = 0" \ + "no threads before we start the second inferior" + runto_main + gdb_test "print \$_inferior_thread_count" " = 1" \ + "no other threads started yet" + # Now that we've added another inferior, thread IDs now show the # inferior number. info_threads "" "1.1 2.1" \ @@ -153,8 +161,14 @@ with_test_prefix "two inferiors" { gdb_breakpoint "thread_function1" gdb_continue_to_breakpoint "once" + gdb_test "print \$_inferior_thread_count" " = 2" \ + "second thread started in inferior 2" gdb_test "inferior 1" "Switching to inferior 1 .*" + gdb_test "print \$_inferior_thread_count" " = 1" \ + "still only one thread in inferior 1" gdb_continue_to_breakpoint "twice" + gdb_test "print \$_inferior_thread_count" " = 2" \ + "second thread started in inferior 1" info_threads "" "1.1 1.2 2.1 2.2" \ "info threads again" @@ -187,9 +201,15 @@ with_test_prefix "two inferiors" { gdb_test "inferior 2" "Switching to inferior 2 .*" gdb_continue_to_breakpoint "once" + gdb_test "print \$_inferior_thread_count" " = 3" \ + "third thread started in inferior 2" gdb_test "inferior 1" "Switching to inferior 1 .*" + gdb_test "print \$_inferior_thread_count" " = 2" \ + "still only two threads in inferior 1" gdb_continue_to_breakpoint "twice" + gdb_test "print \$_inferior_thread_count" " = 3" \ + "third thread started in inferior 1" } thr_apply_info_thr "1" \ diff --git a/gdb/thread.c b/gdb/thread.c index 349fc01dd48..d176d1d9895 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -2123,6 +2123,22 @@ global_thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var, return thread_num_make_value_helper (gdbarch, 1); } +/* Return a new value for the number of non-exited threads in the current + inferior. If there are no threads in the current inferior return a + value of 0. */ + +static struct value * +inferior_thread_count_make_value (struct gdbarch *gdbarch, + struct internalvar *var, void *ignore) +{ + int int_val = 0; + + if (inferior_ptid != null_ptid) + int_val = current_inferior ()->non_exited_threads ().size (); + + return value_from_longest (builtin_type (gdbarch)->builtin_int, int_val); +} + /* Commands with a prefix of `thread'. */ struct cmd_list_element *thread_cmd_list = NULL; @@ -2142,6 +2158,14 @@ static const struct internalvar_funcs gthread_funcs = NULL, }; +/* Implementation of `_inferior_thread_count` convenience variable. */ + +static const struct internalvar_funcs inferior_thread_count_funcs = +{ + inferior_thread_count_make_value, + NULL, +}; + void _initialize_thread (); void _initialize_thread () @@ -2258,4 +2282,6 @@ When on messages about thread creation and deletion are printed."), create_internalvar_type_lazy ("_thread", &thread_funcs, NULL); create_internalvar_type_lazy ("_gthread", >hread_funcs, NULL); + create_internalvar_type_lazy ("_inferior_thread_count", + &inferior_thread_count_funcs, NULL); } diff --git a/gdbsupport/iterator-range.h b/gdbsupport/iterator-range.h index d35b03a3392..c99bdc8de07 100644 --- a/gdbsupport/iterator-range.h +++ b/gdbsupport/iterator-range.h @@ -53,6 +53,10 @@ struct iterator_range IteratorType end () const { return m_end; } + /* The number of items in this iterator_range. */ + std::size_t size () const + { return std::distance (m_begin, m_end); } + private: IteratorType m_begin, m_end; };