[PATCH] Fix breakpoint thread condition missing with mi and a pending breakpoint.

Antoine Tremblay antoine.tremblay@ericsson.com
Thu Mar 5 13:10:00 GMT 2015


ping...

On 02/20/2015 02:06 PM, Antoine Tremblay wrote:
> When setting a pending breakpoint with a thread condition while using
> the mi interface, the thread condition would be lost by gdb when the breakpoint
> was resolved.
>
> This patch fixes this behavior by setting the thread condition properly in the
> mi case.
>
> Also, this patch modifies the mi-pending test case to test for this issue and
> removes some unneeded code in the testcase and dependency on stdio.
>
> gdb/Changelog:
> 	PR breakpoints/16466
> 	* breakpoint.c (create_breakpoint): Set thread on breakpoint struct.
>
> gdb/testsuite/ChangeLog:
> 	PR breakpoints/16466
> 	* gdb.mi/Makefile.in: Add mi-pendshr2.sl to cleanup.
> 	* gdb.mi/mi-pending.c (thread_func): Add simple
> 	thread function.
> 	(int main): Added threading support required.
> 	* gdb.mi/mi-pending.exp: Added tests for this issue.
> 	* gdb.mi/mi-pendshr.c (pendfunc1): Removed stdio dependency.
> 	(pendfunc2): Removed stdio dependency.
> 	* gdb.mi/mi-pendshr2.c: New file.
> ---
>   gdb/breakpoint.c                    |    1 +
>   gdb/testsuite/gdb.mi/Makefile.in    |    2 +-
>   gdb/testsuite/gdb.mi/mi-pending.c   |   42 +++++++++++++++++---
>   gdb/testsuite/gdb.mi/mi-pending.exp |   72 +++++++++++++++++++++++++++++------
>   gdb/testsuite/gdb.mi/mi-pendshr.c   |   13 +++----
>   gdb/testsuite/gdb.mi/mi-pendshr2.c  |   21 ++++++++++
>   6 files changed, 126 insertions(+), 25 deletions(-)
>   create mode 100644 gdb/testsuite/gdb.mi/mi-pendshr2.c
>
> diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
> index acf1ecf..778a01e 100644
> --- a/gdb/breakpoint.c
> +++ b/gdb/breakpoint.c
> @@ -10159,6 +10159,7 @@ create_breakpoint (struct gdbarch *gdbarch,
>   	      make_cleanup (xfree, cond_string);
>   	    }
>   	  b->cond_string = cond_string;
> +	  b->thread = thread;
>   	}
>         b->extra_string = NULL;
>         b->ignore_count = ignore_count;
> diff --git a/gdb/testsuite/gdb.mi/Makefile.in b/gdb/testsuite/gdb.mi/Makefile.in
> index 661add2..2ea819d 100644
> --- a/gdb/testsuite/gdb.mi/Makefile.in
> +++ b/gdb/testsuite/gdb.mi/Makefile.in
> @@ -16,7 +16,7 @@ PROGS = basics c_variable cpp_variable var-cmd dw2-ref-missing-frame	\
>   	mi2-var-block mi2-var-child mi2-var-cmd mi2-var-display		\
>   	mi2-watch until
>
> -MISCELLANEOUS = mi-pendshr.sl
> +MISCELLANEOUS = mi-pendshr.sl mi-pendshr2.sl
>
>   all info install-info dvi install uninstall installcheck check:
>   	@echo "Nothing to be done for $@..."
> diff --git a/gdb/testsuite/gdb.mi/mi-pending.c b/gdb/testsuite/gdb.mi/mi-pending.c
> index 21a2165..7d1b7ae 100644
> --- a/gdb/testsuite/gdb.mi/mi-pending.c
> +++ b/gdb/testsuite/gdb.mi/mi-pending.c
> @@ -15,17 +15,49 @@
>      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 <stdio.h>
> +#include <dlfcn.h>
> +#include <pthread.h>
>
> -int k = 0;
> +#define NUM 2
>
>   extern void pendfunc (int x);
>
> +void*
> +thread_func (void* arg)
> +{
> +  const char *libname = "mi-pendshr2.sl";
> +  void *h;
> +  int (*p_func) ();
> +
> +  h = dlopen (libname, RTLD_LAZY);  /* set breakpoint here */
> +  if (h == NULL) return;
> +
> +  p_func = dlsym (h, "pendfunc3");
> +  if (p_func == NULL) return;
> +
> +  (*p_func) ();
> +}
> +
>   int main()
>   {
> -  pendfunc (3); /* break main here */
> -  pendfunc (4);
> -  k = 1;
> +  int res;
> +  pthread_t threads[NUM];
> +  int i;
> +
>     pendfunc (3);
> +  pendfunc (4);
> +
> +  for (i = 0; i < NUM; i++)
> +    {
> +      res = pthread_create(&threads[i],
> +			     NULL,
> +			     &thread_func,
> +			     NULL);
> +    }
> +
> +  for (i = 0; i < NUM; i++) {
> +    res = pthread_join(threads[i], NULL);
> +  }
> +
>     return 0;
>   }
> diff --git a/gdb/testsuite/gdb.mi/mi-pending.exp b/gdb/testsuite/gdb.mi/mi-pending.exp
> index a5d1c5b..3621f47 100644
> --- a/gdb/testsuite/gdb.mi/mi-pending.exp
> +++ b/gdb/testsuite/gdb.mi/mi-pending.exp
> @@ -24,29 +24,39 @@ if {[skip_shlib_tests]} {
>       return 0
>   }
>
> -standard_testfile mi-pending.c mi-pendshr.c
> -set lib_sl [standard_output_file mi-pendshr.sl]
> +standard_testfile mi-pending.c
>
> -set lib_opts  debug
> -set exec_opts [list debug shlib=$lib_sl]
> +set libfile1 "mi-pendshr"
> +set libfile2 "mi-pendshr2"
> +set libsrc1  $srcdir/$subdir/$libfile1.c
> +set libsrc2  $srcdir/$subdir/$libfile2.c
> +set lib_sl1  [standard_output_file $libfile1.sl]
> +set lib_sl2  [standard_output_file $libfile2.sl]
> +set lib_opts debug
> +set exec_opts [list debug shlib=$lib_sl1 shlib_load]
>
>   if [get_compiler_info] {
>       return -1
>   }
>
> -if { [gdb_compile_shlib $srcdir/$subdir/$srcfile2 $lib_sl $lib_opts] != ""
> -     || [gdb_compile $srcdir/$subdir/$srcfile $binfile executable $exec_opts] != ""} {
> -    untested "Could not compile either $libsrc or $srcdir/$subdir/$srcfile."
> +if { [gdb_compile_shlib $libsrc1 $lib_sl1 $lib_opts] != ""
> +     || [gdb_compile_shlib $libsrc2 $lib_sl2 $lib_opts] != ""} {
> +    untested "Could not compile either $libsrc1 or $libsrc2"
>       return -1
>   }
>
> -# Start with a fresh gdb.
> +if { [gdb_compile_pthreads $srcdir/$subdir/$srcfile $binfile executable $exec_opts] != ""} {
> +    untested "Could not compile  $srcdir/$subdir/$srcfile."
> +    return -1
> +}
>
> +# Start with a fresh gdb.
>   gdb_exit
>   mi_gdb_start
>   mi_gdb_reinitialize_dir $srcdir/$subdir
>   mi_gdb_load ${binfile}
> -mi_load_shlibs $lib_sl
> +mi_load_shlibs $lib_sl1
> +mi_load_shlibs $lib_sl2
>
>   # Set pending breakpoint via MI.
>   mi_gdb_test "-break-insert -f pendfunc1" \
> @@ -54,23 +64,61 @@ mi_gdb_test "-break-insert -f pendfunc1" \
>       "MI pending breakpoint on pendfunc1"
>
>   # Set pending breakpoint with a condition via MI.
> -mi_gdb_test "-break-insert -f -c x==4 ${srcfile2}:pendfunc2" \
> -    ".*\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"<PENDING>\",pending=\"${srcfile2}:pendfunc2\",cond=\"x==4\",times=\"0\",original-location=\"${srcfile2}:pendfunc2\"\}"\
> -    "MI pending breakpoint on ${srcfile2}:pendfunc2 if x==4"
> +mi_gdb_test "-break-insert -f -c x==4 ${libsrc1}:pendfunc2" \
> +    ".*\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"<PENDING>\",pending=\"${libsrc1}:pendfunc2\",cond=\"x==4\",times=\"0\",original-location=\"${libsrc1}:pendfunc2\"\}"\
> +    "MI pending breakpoint on ${libsrc1}:pendfunc2 if x==4"
> +
> +# Set breakpoint so that we can stop when the thread is created
> +mi_gdb_test "-break-insert -f thread_func" \
> +    ".*\\^done,bkpt=\{number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"${hex}\",func=\"thread_func\".*\}"\
> +    "MI pending breakpoint on thread_func"
>
>   mi_run_cmd
> +
>   mi_expect_stop "breakpoint-hit" "pendfunc1" ".*" ".*" ".*" \
>       { "" "disp=\"keep\"" } \
>       "Run till MI pending breakpoint on pendfunc1"
>
>   mi_send_resuming_command "exec-continue" "continuing execution to skip conditional bp"
> +
>   # We should not stop on the conditional breakpoint yet, but we stop on the original bp.
>   mi_expect_stop "breakpoint-hit" "pendfunc1" ".*" ".*" ".*" \
>       { "" "disp=\"keep\"" } \
>       "Run till MI pending breakpoint on pendfunc1 a second time"
>
>   mi_send_resuming_command "exec-continue" "continuing execution to conditional bp"
> +
>   # Now we should stop on the conditional breakpoint.
>   mi_expect_stop "breakpoint-hit" "pendfunc2" "\{name=\"x\",value=\"4\"\}" ".*" ".*" \
>       { "" "disp=\"keep\"" } \
>       "Run till MI pending breakpoint on pendfunc2 with x==4"
> +
> +mi_send_resuming_command "exec-continue" "continuing execution to thread creation"
> +
> +# Stop on thread creation so we can set a pending breakpoint with a thread cond.
> +mi_expect_stop "breakpoint-hit" "thread_func" ".*" ".*" ".*" \
> +    { "" "disp=\"keep\"" } \
> +    "Run till MI pending breakpoint on thread_func"
> +
> +# Delete thread creation breakpoint to enable more then 1 thread to be created.
> +mi_gdb_test "-break-delete 3" ".*" ""
> +
> +# Set pending breakpoint with a thread via MI.
> +mi_gdb_test "-break-insert -p 2 -f pendfunc3" \
> +    ".*\\^done,bkpt=\{number=\"4\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"<PENDING>\",pending=\"pendfunc3\",thread=\"2\",thread=\"2\",times=\"0\",original-location=\"pendfunc3\"\}"\
> +    "MI pending breakpoint on pendfunc3"
> +
> +mi_send_resuming_command "exec-continue" "continuing execution to thread condition"
> +
> +# Check if we stopped in thread 2 like we should.
> +set testname "Run till MI pending breakpoint on pendfunc3 on thread 2"
> +gdb_expect 5 {
> +    -re "\\*stopped,reason=\"breakpoint-hit\",disp=\"keep\",bkptno=\"4\",frame=\{addr=\"$hex\",func=\"pendfunc3\".*thread-id=\"2\".*" {
> +	pass $testname
> +	return 0
> +    }
> +    timeout {
> +	fail "$testname (timeout)"
> +	return -1
> +    }
> +}
> diff --git a/gdb/testsuite/gdb.mi/mi-pendshr.c b/gdb/testsuite/gdb.mi/mi-pendshr.c
> index 05c88af..2dce1fe 100644
> --- a/gdb/testsuite/gdb.mi/mi-pendshr.c
> +++ b/gdb/testsuite/gdb.mi/mi-pendshr.c
> @@ -15,20 +15,19 @@
>      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 <stdio.h>
> -
> -void pendfunc1 (int x)
> +void
> +pendfunc1 (int x)
>   {
>     int y = x + 4;
> -  printf ("in pendfunc1, x is %d\n", x);
>   }
>
> -void pendfunc2 (int x)
> +void
> +pendfunc2 (int x)
>   {
> -  printf ("in pendfunc2, x is %d\n", x);
>   }
>
> -void pendfunc (int x)
> +void
> +pendfunc (int x)
>   {
>     pendfunc1 (x);
>     pendfunc2 (x);
> diff --git a/gdb/testsuite/gdb.mi/mi-pendshr2.c b/gdb/testsuite/gdb.mi/mi-pendshr2.c
> new file mode 100644
> index 0000000..915d647
> --- /dev/null
> +++ b/gdb/testsuite/gdb.mi/mi-pendshr2.c
> @@ -0,0 +1,21 @@
> +/* 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 <http://www.gnu.org/licenses/>.  */
> +
> +void
> +pendfunc3 (void)
> +{
> +}
>



More information about the Gdb-patches mailing list