Files
binutils-gdb/gdb/testsuite/gdb.base/condbreak-multi-context.cc
Andrew Burgess 402f31a34d gdb/testsuite: avoid incorrect symbols in gdb.base/condbreak-multi-context.cc
In a different series I tweak how disabled_by_cond is handled in
update_breakpoint_locations for code_breakpoint objects, see:

  https://inbox.sourceware.org/gdb-patches/cover.1734366277.git.aburgess@redhat.com

But when I did this I ran into a regression in the test script
gdb.base/condbreak-multi-context.cc which I think is actually an issue
with this test.

The test relies on creating a multi-location breakpoint with a
condition and having GDB disable some of the locations as the
condition is only valid in some of the locations.

Here's an example of the test creating one such breakpoint:

  Reading symbols from /tmp/build/gdb/testsuite/outputs/gdb.base/condbreak-multi-context/condbreak-multi-context...
  (gdb) break func if a == 10
  warning: failed to validate condition at location 1, disabling:
    No symbol "a" in current context.
  warning: failed to validate condition at location 3, disabling:
    No symbol "a" in current context.
  Breakpoint 1 at 0x401142: func. (3 locations)
  (gdb) info breakpoints
  Num     Type           Disp Enb Address            What
  1       breakpoint     keep y   <MULTIPLE>
  	stop only if a == 10
  1.1                         N*  0x0000000000401142 in Base::func() at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/condbreak-multi-context.cc:23
  1.2                         y   0x000000000040114e in A::func() at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/condbreak-multi-context.cc:31
  1.3                         N*  0x000000000040115a in C::func() at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/condbreak-multi-context.cc:39
  (*): Breakpoint condition is invalid at this location.
  (gdb)

Notice that only location 1.2 is actually enabled, 1.1 and 1.3 are
disabled due to the condition 'a == 10' not being valid.

However, notice that this b/p is created before GDB has started the
inferior.  What I noticed is that if I first start the inferior then I
get a different behaviour:

  Reading symbols from /tmp/build/gdb/testsuite/outputs/gdb.base/condbreak-multi-context/condbreak-multi-context...
  (gdb) start
  Temporary breakpoint 1 at 0x40110e: file /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/condbreak-multi-context.cc, line 49.
  Starting program: /tmp/build/gdb/testsuite/outputs/gdb.base/condbreak-multi-context/condbreak-multi-context

  Temporary breakpoint 1, main () at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/condbreak-multi-context.cc:49
  49	  aobj.func ();
  (gdb) break func if a == 10
  Breakpoint 2 at 0x401142: func. (3 locations)
  (gdb) info breakpoints
  Num     Type           Disp Enb Address            What
  2       breakpoint     keep y   <MULTIPLE>
  	stop only if a == 10
  2.1                         y   0x0000000000401142 in Base::func() at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/condbreak-multi-context.cc:23
  2.2                         y   0x000000000040114e in A::func() at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/condbreak-multi-context.cc:31
  2.3                         y   0x000000000040115a in C::func() at /tmp/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/condbreak-multi-context.cc:39
  (gdb)

Notice that now all three locations are valid.

What's actually happening is that, on my machine libm.so contains a
global symbol 'a' which for 2.1 and 2.3 is being used to satisfy the
condition.

I don't believe this is actually the intention of the test, this is
just an unfortunate consequence of name collision.

The test actually relies on the local variables 'a' and 'c', and my
libm.so contains a global version of both.

So I propose that we just update the test, I've gone for the super
inventive 'aaa' and 'ccc'.  With this change, after starting the
inferior I now see the expected behaviour where only one of the three
locations is enabled.

However, while I'm fixing this I figure that it would be nice if the
test checked both cases, creating the breakpoints before starting the
inferior, and after starting the inferior.

So I've updated the test to check both cases.  This has meant
converting the mostly linear test script into a set of parameterised
functions which I then call with a flag to indicate if the inferior
should be started before of after creating the breakpoints.

Approved-By: Tom Tromey <tom@tromey.com>
Tested-By: Hannes Domani <ssbssa@yahoo.de>
2025-02-09 22:47:57 +00:00

55 lines
1.1 KiB
C++

/* This testcase is part of GDB, the GNU debugger.
Copyright 2020-2024 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/>. */
class Base
{
public:
static const int bbb = 20;
void func () {}
};
class A : public Base
{
public:
static const int aaa = 10;
void func () {}
};
class C : public Base
{
public:
static const int ccc = 30;
void func () {}
};
int
main ()
{
Base bobj;
A aobj;
C cobj;
aobj.func ();
bobj.func ();
cobj.func ();
return 0;
}