From patchwork Thu Jun 6 17:10:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amos Bird X-Patchwork-Id: 33040 Received: (qmail 125291 invoked by alias); 6 Jun 2019 17:11:09 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 125283 invoked by uid 89); 6 Jun 2019 17:11:09 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-14.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=43, 6, 6085, 3, 6 X-HELO: mail-pf1-f195.google.com Received: from mail-pf1-f195.google.com (HELO mail-pf1-f195.google.com) (209.85.210.195) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 06 Jun 2019 17:11:06 +0000 Received: by mail-pf1-f195.google.com with SMTP id a23so1902320pff.4 for ; Thu, 06 Jun 2019 10:11:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=references:user-agent:from:to:cc:subject:in-reply-to:date :message-id:mime-version; bh=LoOQ9all+QzgcFZyqe9qoaMg1hWN8Y47Nv6jvRb88K8=; b=cLIf0HdDUga5GgunVQW04wZEDroN2D8MvXO30dChL/oaei0C1UY484P4Dgvr0zcN5a hNgXm/KvgWYNqkTkgfMomiMVWiA+kYeA3S/dY2um8t401GPMl72vcy5Z+pJMGMf5s/Pq pVWKK3oksMvebjhOGi7NnvaXLMoAxdVqZjOyDICunBYdZRKSvpVX9IMjq7uJ9WVZwQuh N95/wZ36L/qg8cMPWw77xAsm5GA0jyqOwiawG3ehFQOqOwtuiSALX8oEwf3TCoFJpNo1 wxRxTQQXFa9UloSn1N5uQgsH/N2xpY8zIe+UDcEYEDid2CnKi7Q+l9nq0MciWsTSYWfF QK4g== Return-Path: Received: from localhost ([40.83.99.220]) by smtp.gmail.com with ESMTPSA id e127sm2562544pfe.98.2019.06.06.10.11.03 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Thu, 06 Jun 2019 10:11:04 -0700 (PDT) References: <87d0l8pzdz.fsf@gmail.com> <87ef5j33au.fsf@tromey.com> <87ftpzo1wa.fsf@gmail.com> <20190516131419.GA29999@blade.nx> <87ftpepk1l.fsf@gmail.com> <83d0kicvs6.fsf@gnu.org> <87ef4ypif5.fsf@gmail.com> <441e0b74-a391-2d68-e5d3-f43f1b8da188@simark.ca> <87r28xciz3.fsf@gmail.com> <87pnohcc5t.fsf@gmail.com> <070c42f3-78bd-e605-3f9d-e708f3f0a65c@redhat.com> <87mujlc8bn.fsf@gmail.com> User-agent: mu4e 1.3.2; emacs 27.0.50 From: Amos Bird To: Pedro Alves Cc: Simon Marchi , Eli Zaretskii , gbenson@redhat.com, gdb-patches@sourceware.org, tom@tromey.com Subject: Re: [PATCH] Add "thread-exited" annotation In-reply-to: Date: Fri, 07 Jun 2019 01:10:59 +0800 Message-ID: <87tvd2zljw.fsf@gmail.com> MIME-Version: 1.0 Updated. Thanks! Pedro Alves writes: > On 5/17/19 6:14 PM, Amos Bird wrote: >> } else { >> gdb_test_multiple "signal SIGTRAP" "signal sent" { >> - -re ".*\032\032post-prompt\r\nContinuing with signal >> SIGTRAP.\r\n\r\n\032\032starting\(\r\n\r\n\032\032frames-invalid\)+\r\n\r\n\032\032signalled\r\n\r\nProgram >> terminated with signal >> \r\n\032\032signal-name\r\nSIGTRAP\r\n\032\032signal-name-end\r\n, >> \r\n\032\032signal-string\r\nTrace.breakpoint >> trap\r\n\032\032signal-string-end\r\n.\r\nThe program no longer >> exists.\r\n\r\n\032\032stopped\r\n$gdb_prompt$" { >> +-re ".*\032\032post-prompt\r\nContinuing with signal >> SIGTRAP.\r\n\r\n\032\032starting\(\r\n\r\n\032\032frames-invalid\)+\r\n\r\n\032\032signalled\r\n\r\nProgram >> terminated with signal >> \r\n\032\032signal-name\r\nSIGTRAP\r\n\032\032signal-name-end\r\n, >> \r\n\032\032signal-string\r\nTrace.breakpoint >> trap\r\n\032\032signal-string-end\r\n.\r\nThe program no longer >> exists.\r\n\r\n\032\032thread-exited,id=\"${decimal}\",group-id=\"i${decimal}\"\r\n\r\n\032\032stopped\r\n$gdb_prompt$" >> { >> pass "signal sent" > > That lost the tab before "-re" -- was that on purpose? > > >> } >> } >> @@ -450,6 +450,7 @@ if { [remote_file host exists core] } { >> proc thread_test {} { >> global subdir srcdir testfile srcfile binfile >> global gdb_prompt old_gdb_prompt >> + global decimal >> set srcfile watch_thread_num.c >> set binfile [standard_output_file >> ${testfile}-watch_thread_num] >> set gdb_prompt $old_gdb_prompt >> @@ -468,6 +469,9 @@ proc thread_test {} { >> set linenum [gdb_get_line_number "all threads started"] >> gdb_breakpoint "$linenum" >> >> + set linenum [gdb_get_line_number "first child thread >> exited"] >> + gdb_breakpoint "$linenum" >> + >> set gdb_prompt \ >> "\r\n\032\032pre-prompt\r\n$gdb_prompt >> \r\n\032\032prompt\r\n" >> >> @@ -481,6 +485,12 @@ proc thread_test {} { >> pass "new thread" >> } >> } >> + >> + gdb_test_multiple "continue" "thread exit" { >> + -re >> "\032\032thread-exited,id=\"${decimal}\",group-id=\"i${decimal}\"" >> { >> + pass "thread exit" >> + } >> + } > > This should use the same indentation levels as the similar code > above. > > Also, this isn't expecting the prompt. Is there a reason for > that? > Not matching/expecting the prompt is usually not desired, > because it > leaves the prompt in the expect buffer, which can confuse > following > tests. > > Also, this causes some regressions: > > Running src/gdb/testsuite/gdb.cp/annota2.exp ... > FAIL: gdb.cp/annota2.exp: continue until exit (timeout) > FAIL: gdb.cp/annota2.exp: delete bps > FAIL: gdb.cp/annota2.exp: break at main (got interactive > prompt) > > Please take a look at those and make sure to run the whole > testsuite (I only ran the "gdb.*/annota*.exp" tests). > > Thanks, > Pedro Alves --- Amos Bird amosbird@gmail.com From 68d708fb2f25d3c635be0429b54792970313ac9d Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Fri, 7 Jun 2019 01:10:14 +0800 Subject: [PATCH] Add thread-exit annotation. --- gdb/ChangeLog | 5 +++++ gdb/NEWS | 2 ++ gdb/annotate.c | 14 +++++++++++++ gdb/doc/ChangeLog | 5 +++++ gdb/doc/annotate.texinfo | 7 +++++++ gdb/testsuite/ChangeLog | 5 +++++ gdb/testsuite/gdb.base/annota1.exp | 12 ++++++++++- gdb/testsuite/gdb.base/watch_thread_num.c | 25 +++++++++++++++++------ gdb/testsuite/gdb.cp/annota2.exp | 2 ++ 9 files changed, 70 insertions(+), 7 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e0120e7743..849ed30731 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2019-04-26 Amos Bird + + * annotate.c (annotate_thread_exited): Add "thread-exited" + annotation. + 2019-04-25 Keith Seitz PR c++/24367 diff --git a/gdb/NEWS b/gdb/NEWS index 5309a8f923..735d915ec6 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -3,6 +3,8 @@ *** Changes since GDB 8.3 +* 'thread-exited' event is now available in the annotations interface. + * New built-in convenience variables $_gdb_major and $_gdb_minor provide the GDB version. They are handy for conditionally using features available only in or since specific GDB versions, in diff --git a/gdb/annotate.c b/gdb/annotate.c index 97cb4c8855..af804ddd1f 100644 --- a/gdb/annotate.c +++ b/gdb/annotate.c @@ -241,6 +241,19 @@ annotate_thread_changed (void) } } +/* Emit notification on thread exit. */ + +static void +annotate_thread_exited (struct thread_info *t, int silent) +{ + if (annotation_level > 1) + { + printf_filtered(("\n\032\032thread-exited," + "id=\"%d\",group-id=\"i%d\"\n"), + t->global_num, t->inf->num); + } +} + void annotate_field_begin (struct type *type) { @@ -595,4 +608,5 @@ _initialize_annotate (void) gdb::observers::breakpoint_created.attach (breakpoint_changed); gdb::observers::breakpoint_deleted.attach (breakpoint_changed); gdb::observers::breakpoint_modified.attach (breakpoint_changed); + gdb::observers::thread_exit.attach (annotate_thread_exited); } diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index ba152329d7..79b837aac6 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2019-04-26 Amos Bird + + * annotate.texinfo (Multi-threaded Apps): Add entry for thread-exited + annotation. + 2019-04-22 Pedro Alves * gdb.texinfo (Reverse Execution): Mention and xref process record diff --git a/gdb/doc/annotate.texinfo b/gdb/doc/annotate.texinfo index b85b759f9a..ee8147f52f 100644 --- a/gdb/doc/annotate.texinfo +++ b/gdb/doc/annotate.texinfo @@ -836,6 +836,13 @@ The selected thread has changed. This may occur at the request of the user with the @code{thread} command, or as a result of execution, e.g., another thread hits a breakpoint. +@findex thread-exited@r{, annotation} +@item ^Z^Zthread-exited,id="@var{id}",group-id="@var{gid}" + +This annotation is issued once for each thread that exits. The @var{id} +field contains the global @value{GDBN} identifier of the thread. The +@var{gid} field identifies the thread group this thread belongs to. + @end table @node GNU Free Documentation License diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 9b0725a033..d7a9b5611d 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-04-26 Amos Bird + + * gdb.base/annota1.exp (thread_switch): Add test for + thread-exited annotation. + 2019-04-25 Keith Seitz PR c++/24367 diff --git a/gdb/testsuite/gdb.base/annota1.exp b/gdb/testsuite/gdb.base/annota1.exp index 5237bc9715..dfa30831e6 100644 --- a/gdb/testsuite/gdb.base/annota1.exp +++ b/gdb/testsuite/gdb.base/annota1.exp @@ -428,7 +428,7 @@ if [target_info exists gdb,nosignals] { unsupported "signal sent" } else { gdb_test_multiple "signal SIGTRAP" "signal sent" { - -re ".*\032\032post-prompt\r\nContinuing with signal SIGTRAP.\r\n\r\n\032\032starting\(\r\n\r\n\032\032frames-invalid\)+\r\n\r\n\032\032signalled\r\n\r\nProgram terminated with signal \r\n\032\032signal-name\r\nSIGTRAP\r\n\032\032signal-name-end\r\n, \r\n\032\032signal-string\r\nTrace.breakpoint trap\r\n\032\032signal-string-end\r\n.\r\nThe program no longer exists.\r\n\r\n\032\032stopped\r\n$gdb_prompt$" { + -re ".*\032\032post-prompt\r\nContinuing with signal SIGTRAP.\r\n\r\n\032\032starting\(\r\n\r\n\032\032frames-invalid\)+\r\n\r\n\032\032signalled\r\n\r\nProgram terminated with signal \r\n\032\032signal-name\r\nSIGTRAP\r\n\032\032signal-name-end\r\n, \r\n\032\032signal-string\r\nTrace.breakpoint trap\r\n\032\032signal-string-end\r\n.\r\nThe program no longer exists.\r\n\r\n\032\032thread-exited,id=\"${decimal}\",group-id=\"i${decimal}\"\r\n\r\n\032\032stopped\r\n$gdb_prompt$" { pass "signal sent" } } @@ -450,6 +450,7 @@ if { [remote_file host exists core] } { proc thread_test {} { global subdir srcdir testfile srcfile binfile global gdb_prompt old_gdb_prompt + global decimal set srcfile watch_thread_num.c set binfile [standard_output_file ${testfile}-watch_thread_num] set gdb_prompt $old_gdb_prompt @@ -468,6 +469,9 @@ proc thread_test {} { set linenum [gdb_get_line_number "all threads started"] gdb_breakpoint "$linenum" + set linenum [gdb_get_line_number "first child thread exited"] + gdb_breakpoint "$linenum" + set gdb_prompt \ "\r\n\032\032pre-prompt\r\n$gdb_prompt \r\n\032\032prompt\r\n" @@ -481,6 +485,12 @@ proc thread_test {} { pass "new thread" } } + + gdb_test_multiple "continue" "thread exit" { + -re "\032\032thread-exited,id=\"${decimal}\",group-id=\"i${decimal}\".*\r\n$gdb_prompt$" { + pass "thread exit" + } + } } } diff --git a/gdb/testsuite/gdb.base/watch_thread_num.c b/gdb/testsuite/gdb.base/watch_thread_num.c index a5195c71f6..fe9d602476 100644 --- a/gdb/testsuite/gdb.base/watch_thread_num.c +++ b/gdb/testsuite/gdb.base/watch_thread_num.c @@ -29,6 +29,8 @@ void *thread_function (void *arg); /* Pointer to function executed by each threa static pthread_barrier_t threads_started_barrier; +static pthread_barrier_t threads_started_barrier2; + #define NUM 15 static int num_threads = NUM; @@ -43,6 +45,8 @@ int main () { pthread_barrier_init (&threads_started_barrier, NULL, NUM + 1); + pthread_barrier_init (&threads_started_barrier2, NULL, 2); + for (i = 0; i < NUM; i++) { res = pthread_create (&threads[i], @@ -53,7 +57,11 @@ int main () { pthread_barrier_wait (&threads_started_barrier); - sleep (180); /* all threads started */ + pthread_barrier_wait (&threads_started_barrier2); /* all threads started */ + + pthread_join (threads[0], NULL); + + sleep (180); /* first child thread exited */ exit (EXIT_SUCCESS); } @@ -68,13 +76,18 @@ void *thread_function (void *arg) { pthread_barrier_wait (&threads_started_barrier); - /* Don't run forever. Run just short of it :) */ - while (shared_var > 0) + if (my_number > 0) { - shared_var++; - usleep (1); /* Loop increment. */ - loop (); + /* Don't run forever. Run just short of it :) */ + while (shared_var > 0) + { + shared_var++; + usleep (1); /* Loop increment. */ + loop (); + } } + else + pthread_barrier_wait (&threads_started_barrier2); pthread_exit (NULL); } diff --git a/gdb/testsuite/gdb.cp/annota2.exp b/gdb/testsuite/gdb.cp/annota2.exp index 982020a11e..745f461716 100644 --- a/gdb/testsuite/gdb.cp/annota2.exp +++ b/gdb/testsuite/gdb.cp/annota2.exp @@ -138,6 +138,8 @@ set pat [multi_line "" \ "\032\032exited 0" \ "$inferior_exited_re normally." \ "" \ + "\032\032thread-exited,id=\"1\",group-id=\"i1\"" \ + "" \ "\032\032stopped" \ $gdb_prompt$] gdb_test_multiple "continue" "continue until exit" { -- 2.21.0