From: Simon Marchi <simon.marchi@polymtl.ca>
To: Kevin Buettner <kevinb@redhat.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH v3 4/7] Test case for Inferior.thread_from_thread_handle
Date: Sun, 23 Jul 2017 21:17:00 -0000 [thread overview]
Message-ID: <d7965059550cb0bce99354ecec158b55@polymtl.ca> (raw)
In-Reply-To: <20170718175515.252308db@pinnacle.lan>
Hi Kevin,
On 2017-07-19 02:55, Kevin Buettner wrote:
> As the title says, this is a test case for
> Inferior.thread_from_thread_handle, a python method which will,
> given a thread library dependent thread handle, find the GDB thread
> which corresponds to that thread handle (in the inferior under
> consideration).
>
> The C file for this test case causes the thread handles for the
> main thread and two child threads to be placed into an array. The
> test case runs to one of the functions (do_something()) at which point,
> it retrieves the thread handles from the array and attempts to find the
> correponding thread in GDB's internal thread list.
"correponding"
>
> I use barriers to make sure that both threads have actually started;
> execution will stop when one of the threads breaks at do_something.
>
> Thanks to Simon Marchi for suggestions for forcing the thread
> numbering to be stable.
>
> gdb/testsuite/ChangeLog:
>
> * gdb.python/py-thrhandle.c, gdb.python/py-thrhandle.exp: New
> files.
> ---
> gdb/testsuite/gdb.python/py-thrhandle.c | 97
> +++++++++++++++++++++++++++++++
> gdb/testsuite/gdb.python/py-thrhandle.exp | 72 +++++++++++++++++++++++
> 2 files changed, 169 insertions(+)
>
> diff --git a/gdb/testsuite/gdb.python/py-thrhandle.c
> b/gdb/testsuite/gdb.python/py-thrhandle.c
> new file mode 100644
> index 0000000..10e0222
> --- /dev/null
> +++ b/gdb/testsuite/gdb.python/py-thrhandle.c
> @@ -0,0 +1,97 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> + Copyright 2017 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
> <http://www.gnu.org/licenses/>. */
> +
> +#include <pthread.h>
> +#include <unistd.h>
> +#include <memory.h>
> +
> +#define NTHR 3
> +#define NBOGUSTHR 2
> +
> +int thr_data[NTHR];
> +
> +/* Thread handles for each thread plus some "bogus" threads. */
> +pthread_t thrs[NTHR + NBOGUSTHR];
> +
> +/* The thread children will meet at this barrier. */
> +pthread_barrier_t c_barrier;
> +
> +/* The main thread and child thread will meet at this barrier. */
> +pthread_barrier_t mc_barrier;
> +
> +void
> +do_something (int n)
> +{
> +}
> +
> +void *
> +do_work (void *data)
> +{
> + int num = * (int *) data;
> +
> + /* As the child threads are created, they'll meet the main thread
> + at this barrier. We do this to ensure that threads end up in
> + GDB's thread list in the order in which they were created.
> Having
> + this ordering makes it easier to write the test. */
> + pthread_barrier_wait (&mc_barrier);
> +
> + /* All of the child threads will meet at this barrier before
> proceeding.
> + This ensures that all threads will be active (not exited) and in
> + roughly the same state when the first one hits the breakpoint in
> + do_something(). */
> + pthread_barrier_wait (&c_barrier);
> +
> + do_something (num);
> +
> + pthread_exit (NULL);
> +}
> +
> +void
> +after_mc_barrier (void)
> +{
> +}
> +
> +int
> +main (int argc, char **argv)
> +{
> + int i;
> +
> + pthread_barrier_init (&c_barrier, NULL, NTHR - 1);
> +
> + thrs[0] = pthread_self ();
> + thr_data[0] = 1;
> +
> + /* Create two bogus thread handles. */
> + memset (&thrs[NTHR], 0, sizeof (pthread_t));
> + memset (&thrs[NTHR + 1], 0xaa, sizeof (pthread_t));
> +
> + for (i = 1; i < NTHR; i++)
> + {
> + thr_data[i] = i + 1;
> +
> + pthread_barrier_init (&mc_barrier, NULL, 2);
I don't think it's wrong to init/destroy the barrier repeatedly, but
it's not necessary. After the barrier has "opened", it is reset with
the count it was initialized with. So you can just call _wait again on
it.
> +
> + pthread_create (&thrs[i], NULL, do_work, &thr_data[i]);
> +
> + pthread_barrier_wait (&mc_barrier);
> + pthread_barrier_destroy (&mc_barrier);
> + after_mc_barrier ();
> + }
> +
> + for (i = 1; i < NTHR; i++)
> + pthread_join (thrs[i], NULL);
> +}
> diff --git a/gdb/testsuite/gdb.python/py-thrhandle.exp
> b/gdb/testsuite/gdb.python/py-thrhandle.exp
> new file mode 100644
> index 0000000..033737d
> --- /dev/null
> +++ b/gdb/testsuite/gdb.python/py-thrhandle.exp
> @@ -0,0 +1,72 @@
> +# Copyright (C) 2017 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
> <http://www.gnu.org/licenses/>.
> +
> +# Please email any bugs, comments, and/or additions to this file to:
> +# bug-gdb@gnu.org
> +
> +# This file verifies that gdb.thread_from_thread_handle works as
> expected.
This is now gdb.Inferior.thread_from_thread_handle.
> +
> +standard_testfile
> +
> +
> +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}"
> "${binfile}" executable debug] != "" } {
> + return -1
> +}
> +
> +clean_restart ${binfile}
> +runto_main
> +
> +gdb_test "break after_mc_barrier" \
> + "Breakpoint 2 at .*: file .*${srcfile}, line .*" \
> + "breakpoint on after_mc_barrier"
> +
> +gdb_test "break do_something" \
> + "Breakpoint 3 at .*: file .*${srcfile}, line .*" \
> + "breakpoint on do_something"
> +
> +gdb_test "continue" \
> + "Breakpoint 2, after_mc_barrier .*" \
> + "run to after_mc_barrier (1)"
Do not use parentheses at the end of the test name:
https://sourceware.org/gdb/wiki/GDBTestcaseCookbook#Do_not_use_.22tail_parentheses.22_on_test_messages
Alternatively, you can use gdb_continue_to_breakpoint or gdb_continue
(not sure why we have both).
> +
> +gdb_test_no_output "del 2" "delete after_mc_barrier breakpoint"
> +
> +gdb_test "continue" \
> + "Breakpoint 3, do_something .*" \
> + "run to do_something"
> +
> +# The current thread, indicated by '*' in the "info threads" output
> +# should be stopped in do_something() with a value of n which is the
> +# same as the number reported in the "Id" column. If it's not, then
> +# something went wrong with the start up sequence which should cause
> +# the main thread to be thread 1, the first child thread to be thread
> +# 2, and the second child thread to be thread 3.
> +
> +gdb_test "info threads" \
> + {.*[\r\n]+\* +([0-9]+) +Thread[^\r\n]* do_something \(n=\1\) at.*}
I didn't understand the comment when reading it at first, then wondered
for way too long how we could end up with n=1 :).
> +gdb_test "python print
> gdb.selected_inferior().thread_from_thread_handle(gdb.parse_and_eval('thrs\[0\]')).num"
> \
> + "1"
> +
> +gdb_test "python print
> gdb.selected_inferior().thread_from_thread_handle(gdb.parse_and_eval('thrs\[1\]')).num"
> \
> + "2"
> +
> +gdb_test "python print
> gdb.selected_inferior().thread_from_thread_handle(gdb.parse_and_eval('thrs\[2\]')).num"
> \
> + "3"
> +
> +gdb_test "python print
> gdb.selected_inferior().thread_from_thread_handle(gdb.parse_and_eval('thrs\[3\]'))"
> \
> + "None"
> +
> +gdb_test "python print
> gdb.selected_inferior().thread_from_thread_handle(gdb.parse_and_eval('thrs\[4\]'))"
> \
> + "None"
Please use parentheses with print, so it works with Python 3. But then,
your test name will have tail parentheses, so it might be a good idea to
give them explicit names.
Thanks,
Simon
next prev parent reply other threads:[~2017-07-23 21:17 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-19 0:42 [PATCH v3 0/7] Thread handle to thread info mapping Kevin Buettner
2017-07-19 0:54 ` [PATCH v3 1/7] Add target method for converting thread handle to thread_info struct pointer Kevin Buettner
2017-07-23 20:39 ` Simon Marchi
2017-07-19 0:54 ` [PATCH v3 2/7] Add `thread_from_thread_handle' method to (Python) gdb.Inferior Kevin Buettner
2017-07-23 20:53 ` Simon Marchi
2017-07-19 0:55 ` [PATCH v3 5/7] Add thread_db_notice_clone to gdbserver Kevin Buettner
2017-07-23 21:27 ` Simon Marchi
2017-07-19 0:55 ` [PATCH v3 3/7] Documentation for Inferior.thread_from_thread_handle Kevin Buettner
2017-07-19 2:33 ` Eli Zaretskii
2017-07-19 0:55 ` [PATCH v3 4/7] Test case " Kevin Buettner
2017-07-23 21:17 ` Simon Marchi [this message]
2017-07-19 0:56 ` [PATCH v3 6/7] Add thread_handle_to_thread_info support for remote targets Kevin Buettner
2017-07-23 21:47 ` Simon Marchi
2017-07-19 0:56 ` [PATCH v3 7/7] Documentation for qXfer:threads:read handle attribute Kevin Buettner
2017-07-19 2:34 ` Eli Zaretskii
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=d7965059550cb0bce99354ecec158b55@polymtl.ca \
--to=simon.marchi@polymtl.ca \
--cc=gdb-patches@sourceware.org \
--cc=kevinb@redhat.com \
/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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).