From patchwork Fri Sep 18 12:43:03 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 8777 Received: (qmail 14645 invoked by alias); 18 Sep 2015 12:43:36 -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 14164 invoked by uid 89); 18 Sep 2015 12:43:35 -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, FREEMAIL_FROM, KAM_STOCKGEN, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=no version=3.3.2 X-HELO: mail-wi0-f171.google.com Received: from mail-wi0-f171.google.com (HELO mail-wi0-f171.google.com) (209.85.212.171) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 18 Sep 2015 12:43:18 +0000 Received: by wiclk2 with SMTP id lk2so62883838wic.0 for ; Fri, 18 Sep 2015 05:43:14 -0700 (PDT) X-Received: by 10.180.87.162 with SMTP id az2mr38196403wib.62.1442580194604; Fri, 18 Sep 2015 05:43:14 -0700 (PDT) Received: from E107787-LIN.cambridge.arm.com ([195.154.84.196]) by smtp.gmail.com with ESMTPSA id uq5sm8742676wjc.3.2015.09.18.05.43.13 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 18 Sep 2015 05:43:13 -0700 (PDT) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH 7/8] Add a test case for fast tracepoints' locking mechanism Date: Fri, 18 Sep 2015 13:43:03 +0100 Message-Id: <1442580184-22562-8-git-send-email-yao.qi@linaro.org> In-Reply-To: <1442580184-22562-1-git-send-email-yao.qi@linaro.org> References: <1442230282-20751-1-git-send-email-pierre.langlois@arm.com> <1442580184-22562-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes From: Pierre Langlois When installing a fast tracepoint, we create a jump pad with a spin-lock. This way, only one thread can collect a given tracepoint at any time. This test case checks that this lock actually works as expected. This test works by creating a function which overrides the in-process agent library's gdb_collect function. On start up, GDBserver will ask GDB with the 'qSymbol' packet about symbols present in the inferior. GDB will reply with the gdb_agent_gdb_collect function from the test case instead of the one from the agent. gdb/testsuite/ChangeLog: * gdb.trace/ftrace-lock.c: New file. * gdb.trace/ftrace-lock.exp: New file. --- gdb/testsuite/gdb.trace/ftrace-lock.c | 106 ++++++++++++++++++++++++++++++++ gdb/testsuite/gdb.trace/ftrace-lock.exp | 88 ++++++++++++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 gdb/testsuite/gdb.trace/ftrace-lock.c create mode 100644 gdb/testsuite/gdb.trace/ftrace-lock.exp diff --git a/gdb/testsuite/gdb.trace/ftrace-lock.c b/gdb/testsuite/gdb.trace/ftrace-lock.c new file mode 100644 index 0000000..8ed45f4 --- /dev/null +++ b/gdb/testsuite/gdb.trace/ftrace-lock.c @@ -0,0 +1,106 @@ +/* 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 . */ + +#include + +#ifdef SYMBOL_PREFIX +#define SYMBOL(str) SYMBOL_PREFIX #str +#else +#define SYMBOL(str) #str +#endif + +/* Called if the testcase failed. */ +static void +fail (void) +{ +} + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +/* This function overrides gdb_collect in the in-process agent library. + See gdbserver/tracepoint.c (gdb_collect). We want this function to + be ran instead of the one from the library to easily check that only + one thread is tracing at a time. + + This works as expected because GDBserver will ask GDB about symbols + present in the inferior with the 'qSymbol' packet. And GDB will + reply with the address of this function instead of the one from the + in-process agent library. */ + +void +gdb_agent_gdb_collect (void *tpoint, unsigned char *regs) +{ + /* If we cannot acquire a lock, then this means another thread is + tracing and the lock implemented by the jump pad is not working! */ + if (pthread_mutex_trylock (&mutex) != 0) + { + fail (); + return; + } + + sleep (1); + + if (pthread_mutex_unlock (&mutex) != 0) + { + fail (); + return; + } +} + +/* Called from asm. */ +static void __attribute__((used)) +func (void) +{ +} + +static void * +thread_function (void *arg) +{ + /* `set_point' is the label at which to set a fast tracepoint. The + insn at the label must be large enough to fit a fast tracepoint + jump. */ + asm (" .global " SYMBOL (set_point) "\n" + SYMBOL (set_point) ":\n" +#if (defined __x86_64__ || defined __i386__) + " call " SYMBOL (func) "\n" +#elif (defined __aarch64__) + " nop\n" +#endif + ); +} + +static void +end (void) +{ +} + +int +main (int argc, char *argv[], char *envp[]) +{ + pthread_t threads[NUM_THREADS]; + int i; + + for (i = 0; i < NUM_THREADS; i++) + pthread_create (&threads[i], NULL, thread_function, NULL); + + for (i = 0; i < NUM_THREADS; i++) + pthread_join (threads[i], NULL); + + end (); + + return 0; +} diff --git a/gdb/testsuite/gdb.trace/ftrace-lock.exp b/gdb/testsuite/gdb.trace/ftrace-lock.exp new file mode 100644 index 0000000..c67739d --- /dev/null +++ b/gdb/testsuite/gdb.trace/ftrace-lock.exp @@ -0,0 +1,88 @@ +# 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 . + +load_lib "trace-support.exp" + +standard_testfile +set executable $testfile +set expfile $testfile.exp + +# make check RUNTESTFLAGS='gdb.trace/ftrace-lock.exp NUM_THREADS=2' +if ![info exists NUM_THREADS] { + set NUM_THREADS 2 +} + +# Some targets have leading underscores on assembly symbols. +set additional_flags [gdb_target_symbol_prefix_flags] +set options [list debug [gdb_target_symbol_prefix_flags] \ + additional_flags=-DNUM_THREADS=$NUM_THREADS] + +# Check that the target supports trace. +if { [gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile executable $options] != "" } { + untested "Couldn't compile test program" + return -1 +} + +clean_restart ${testfile} + +if ![runto_main] { + fail "Can't run to main to check for trace support" + return -1 +} + +if ![gdb_target_supports_trace] { + unsupported "target does not support trace" + return -1 +} + +# Compile the test case with the in-process agent library. +set libipa [get_in_proc_agent] +gdb_load_shlibs $libipa + +lappend options shlib=$libipa + +if { [gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile executable $options] != "" } { + untested "Couldn't compile test program with in-process agent library" + return -1 +} + +clean_restart ${executable} + +if ![runto_main] { + fail "Can't run to main to check for trace support" + return -1 +} + +if { [gdb_test "info sharedlibrary" ".*${libipa}.*" "IPA loaded"] != 0 } { + untested "Could not find IPA lib loaded" + return 1 +} + +gdb_test "break end" "" +gdb_test "break fail" "" + +gdb_test "ftrace set_point" "Fast tracepoint .*" \ + "fast tracepoint at a long insn" + +gdb_test "tstart" "" + +# If NUM_THREADS is high then this test case may timeout. Increase the +# timeout temporarily. +with_timeout_factor $NUM_THREADS { + # If the fail function is hit, then the testcase will fail. + gdb_test "continue" ".*Breakpoint \[0-9\]+, end \(\).*" \ + "do not hit the fail function" +} + +gdb_test "tstop" ""