From patchwork Thu Nov 26 15:59:59 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 9832 Received: (qmail 91926 invoked by alias); 26 Nov 2015 16:00:19 -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 85380 invoked by uid 89); 26 Nov 2015 16:00:05 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, SPF_PASS autolearn=ham version=3.3.2 X-HELO: usplmg21.ericsson.net Received: from usplmg21.ericsson.net (HELO usplmg21.ericsson.net) (198.24.6.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Thu, 26 Nov 2015 16:00:02 +0000 Received: from EUSAAHC007.ericsson.se (Unknown_Domain [147.117.188.93]) by usplmg21.ericsson.net (Symantec Mail Security) with SMTP id 8E.9E.32102.E7C27565; Thu, 26 Nov 2015 16:59:59 +0100 (CET) Received: from [142.133.110.144] (147.117.188.8) by smtp-am.internal.ericsson.com (147.117.188.95) with Microsoft SMTP Server id 14.3.248.2; Thu, 26 Nov 2015 10:59:59 -0500 Subject: Re: [PATCH v2 3/3] Add test for thread names To: Pedro Alves , References: <1448488138-2360-1-git-send-email-simon.marchi@ericsson.com> <1448488138-2360-4-git-send-email-simon.marchi@ericsson.com> <5656F0C2.4070203@redhat.com> From: Simon Marchi Message-ID: <56572C7F.3030101@ericsson.com> Date: Thu, 26 Nov 2015 10:59:59 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <5656F0C2.4070203@redhat.com> X-IsSubscribed: yes On 15-11-26 06:45 AM, Pedro Alves wrote: > On 11/25/2015 09:48 PM, Simon Marchi wrote: > >> +int >> +main (int argc, char **argv) >> +{ >> + pthread_t threads[NUM_THREADS]; >> + struct thread_data args[NUM_THREADS]; >> + pthread_barrier_t barrier; >> + int i; >> + const char *names[] = { "carrot", "potato", "celery" }; > > Add an alarm call so the process doesn't run forever if something > goes wrong and it gets detached / reparented to init. Since the main function doesn't wait forever, I don't know if it's necessary. If gdb crashes and leaves the process running, the process should end by itself (unless something is really wrong with the threads and the barrier). I'll add it anyway, it doesn't hurt and it's a good practice. >> + >> + /* Make sure that NAMES contains NUM_THREADS elements. */ >> + assert (sizeof (names) == sizeof(names[0]) * NUM_THREADS); >> + >> + assert (0 == pthread_barrier_init (&barrier, NULL, NUM_THREADS + 1)); > > There should be no side-effects in assert calls: > > res = pthread_barrier_init (&barrier, NULL, NUM_THREADS + 1)); > assert (res == 0); Right, if asserts are disabled, that code is left out. All fixed. >> + >> + pthread_setname_np (pthread_self (), "main"); >> + >> + for (i = 0; i < NUM_THREADS; i++) >> + { >> + struct thread_data *arg = &args[i]; >> + >> + arg->name = names[i]; >> + arg->barrier = &barrier; >> + >> + assert (0 == pthread_create (&threads[i], NULL, thread_func, arg)); > > Ditto. > >> + } >> + >> + pthread_barrier_wait (&barrier); >> + >> + all_threads_ready (); >> + >> + return 0; >> +} > > OK with above fixed. > >> +set expected_thread_list "\\* 1 .*\"main\" all_threads_ready.*\n" >> +append expected_thread_list " 2 .*\"carrot\".*\n" >> +append expected_thread_list " 3 .*\"potato\".*\n" >> +append expected_thread_list " 4 .*\"celery\".*" >> + >> +gdb_test "info threads" "$expected_thread_list" "list threads" > > Note you can do this with multi_line. E.g.: > > gdb_test "info threads" \ > [multi_line \ > "\\* 1 .*\"main\" all_threads_ready.*" \ > " 2 .*\"carrot\".*" \ > " 3 .*\"potato\".*" \ > " 4 .*\"celery\".*"] \ > "list threads" Ok. I modified names.c significantly, so could you give it another quick look? Changes: - Added alarm call. - Added some assert calls - I was seeing some sigsegv and sigill in __run_exit_handlers when running the binary, I think it was because I was not joining the threads. I added a second barrier call and am now joining the threads properly. - Define _GNU_SOURCE to remove warning about pthread_setname_np. From 41b75663742b06550911bdf2b6aee704fca66645 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Thu, 26 Nov 2015 09:49:04 -0500 Subject: [PATCH] Add test for thread names I couldn't find a test that verified the thread name functionality, so I created a new one. A target board can define gdb,no_thread_names if it doesn't support thread names and wants to skip the tests that uses them. This test has been made with Linux in mind. Not all platforms use pthread_setname_np to set the thread name, but some #ifdefs can be added later in order to support other platforms. Tested on x86-64 Ubuntu 14.04, native and remote. gdb/testsuite/ChangeLog: * gdb.threads/names.exp: New file. * gdb.threads/names.c: New file. * README: Mention gdb,no_thread_names. --- gdb/testsuite/ChangeLog | 6 +++ gdb/testsuite/README | 3 ++ gdb/testsuite/gdb.threads/names.c | 97 +++++++++++++++++++++++++++++++++++++ gdb/testsuite/gdb.threads/names.exp | 38 +++++++++++++++ 4 files changed, 144 insertions(+) create mode 100644 gdb/testsuite/gdb.threads/names.c create mode 100644 gdb/testsuite/gdb.threads/names.exp diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 9f6d7e6..461565f 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-11-26 Simon Marchi + + * gdb.threads/names.exp: New file. + * gdb.threads/names.c: New file. + * README: Mention gdb,no_thread_names. + 2015-11-26 Markus Metzger PR 19297 diff --git a/gdb/testsuite/README b/gdb/testsuite/README index 70f65cd..77ac74e 100644 --- a/gdb/testsuite/README +++ b/gdb/testsuite/README @@ -369,6 +369,9 @@ gdb,predefined_tsv The predefined trace state variables the board has. +gdb,no_thread_names + + The target doesn't support thread names. Testsuite Organization ********************** diff --git a/gdb/testsuite/gdb.threads/names.c b/gdb/testsuite/gdb.threads/names.c new file mode 100644 index 0000000..130ddc1 --- /dev/null +++ b/gdb/testsuite/gdb.threads/names.c @@ -0,0 +1,97 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2015 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 . */ + +#define _GNU_SOURCE +#include +#include +#include +#include + +#define NUM_THREADS 3 + +struct thread_data +{ + const char *name; + pthread_barrier_t *barrier; +}; + +static void * +thread_func (void *varg) +{ + struct thread_data *arg = (struct thread_data *) varg; + int res; + + res = pthread_setname_np (pthread_self (), arg->name); + assert (res == 0); + + pthread_barrier_wait (arg->barrier); + + pthread_barrier_wait (arg->barrier); + + return NULL; +} + +static void +all_threads_ready (void) +{ +} + +int +main (int argc, char **argv) +{ + pthread_t threads[NUM_THREADS]; + struct thread_data args[NUM_THREADS]; + pthread_barrier_t barrier; + int i, res; + const char *names[] = { "carrot", "potato", "celery" }; + + alarm (20); + + /* Make sure that NAMES contains NUM_THREADS elements. */ + assert (sizeof (names) == sizeof (names[0]) * NUM_THREADS); + + res = pthread_barrier_init (&barrier, NULL, NUM_THREADS + 1); + assert (res == 0);; + + res = pthread_setname_np (pthread_self (), "main"); + assert (res == 0); + + for (i = 0; i < NUM_THREADS; i++) + { + struct thread_data *arg = &args[i]; + + arg->name = names[i]; + arg->barrier = &barrier; + + res = pthread_create (&threads[i], NULL, thread_func, arg); + assert (res == 0); + } + + pthread_barrier_wait (&barrier); + + all_threads_ready (); + + pthread_barrier_wait (&barrier); + + for (i = 0; i < NUM_THREADS; i++) + { + res = pthread_join (threads[i], NULL); + assert (res == 0); + } + + return 0; +} diff --git a/gdb/testsuite/gdb.threads/names.exp b/gdb/testsuite/gdb.threads/names.exp new file mode 100644 index 0000000..f6bbdb4 --- /dev/null +++ b/gdb/testsuite/gdb.threads/names.exp @@ -0,0 +1,38 @@ +# Copyright (C) 2015 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 . + +# Verify that thread name features work properly (e.g. they show up in info +# threads). + +if [target_info exists gdb,no_thread_names] { + continue +} + +standard_testfile + +if [prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads}] { + return -1 +} + +if ![runto "all_threads_ready"] { + continue +} + +gdb_test "info threads" \ + [multi_line "\\* 1 .*\"main\" all_threads_ready.*" \ + " 2 .*\"carrot\".*" \ + " 3 .*\"potato\".*" \ + " 4 .*\"celery\".*" ] \ + "list threads"