Fix breakpoint thread condition missing with mi and a pending breakpoint.

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): New function.
	(int main): Add threading support required.
	* gdb.mi/mi-pending.exp: Add tests for this issue.
	* gdb.mi/mi-pendshr.c (pendfunc1): Remove stdio dependency.
	(pendfunc2): Remove stdio dependency.
	* gdb.mi/mi-pendshr2.c: New file.
This commit is contained in:
Antoine Tremblay 2015-02-19 15:23:34 -05:00
parent 5421cc6e55
commit 1563054901
8 changed files with 144 additions and 25 deletions

View file

@ -1,3 +1,8 @@
2015-03-24 Antoine Tremblay <antoine.tremblay@ericsson.com>
PR breakpoints/16466
* breakpoint.c (create_breakpoint): Set thread on breakpoint struct.
2015-03-23 Joel Brobecker <brobecker@adacore.com>
* ser-mingw.c (ser_windows_setparity): Fix indentation.

View file

@ -9784,6 +9784,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;

View file

@ -1,3 +1,14 @@
2015-03-24 Antoine Tremblay <antoine.tremblay@ericsson.com>
PR breakpoints/16466
* gdb.mi/Makefile.in: Add mi-pendshr2.sl to cleanup.
* gdb.mi/mi-pending.c (thread_func): New function.
(int main): Add threading support required.
* gdb.mi/mi-pending.exp: Add tests for this issue.
* gdb.mi/mi-pendshr.c (pendfunc1): Remove stdio dependency.
(pendfunc2): Remove stdio dependency.
* gdb.mi/mi-pendshr2.c: New file.
2015-03-23 Keith Seitz <keiths@redhat.com>
* gdb.linespec/keywords.c: New file.

View file

@ -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 $@..."

View file

@ -15,17 +15,51 @@
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;
}

View file

@ -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
}
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 than 1 thread to be created.
mi_gdb_test "-break-delete 3" "\\^done" "Delete breakpoint 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
}
}

View file

@ -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);

View file

@ -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)
{
}