Re: gdb.objc/objcdecode.exp test error..

Matt Rice
2009-09-11T11:43:27Z

[-- Attachment #1: Type: text/plain, Size: 6168 bytes --]

On Sun, Mar 8, 2009 at 7:10 PM, Matt Rice <ratmice@gmail.com> wrote:
>
> well hmm these only partially fix the issue, still trying to figure
> out how to compile a shared library
> in the testsuite,

Alright so, i've finally gotten around to figuring that out.
Apologies for my lack of brevity.
Attached are testsuite patches which test this, and an additional way
to provoke the issue
I've currently decided to just focus on the assertion failure which is
evident in the current testsuite
and further explored in my tests, and also asked about by Pierre Muller in [1].

The assert was added at [2], this changed the handling in
breakpoint_re_set_one of the return value of decode_line_1 from being
iterated over to asserting that there is only a single value returned.

to quote the gdb manual at [3]:
It is also possible to specify just a method name:

break create

end quote.

basically the effect of this is that it is possible to create an
ambiguous expression[5]
which is extrapolated into more ambiguous expressions,

e.g. 'create' becomes 'create'
and also '-[Foo create]'
and both 'create' and '-[Foo create]' can also become '-[Foo(bar) create]'
and it is possible for all 3 to exist at the same time.

As Vladimir mentioned on irc this is somewhat non-conventional, e.g.

The c++ language support doesn't do anything like it, e.g.
break create will not expand to Foo::create(void)
and it seems that we have similar behaviour to this already available in rbreak,
but none the less, the behaviour is documented and works _until_ it
hits ambiguity.
e.g. if 'break create' were to match only '-[Bar create]' and '-[Baz
create]', the 2 resulting breakpoints would not be ambiguous nor
trigger the assertion.

Regardless of the above there is a language feature of Objective-C
with which it is possible to also trigger this assertion, The feature
is called categories, and they are a way in which to add
methods, or override methods, This situation seems much more akin to
the situation in which breakpoint_re_set_one was intended to handle.

These are tested via the -bar methods in the added .m files.

after loading the Category in libobjcdecode3.so via dlopen, [obj bar];
will call a new implementation, but the symbol was not overridden via
normal c-style linkage, the symbols are unique, so both method
implementations exist, only the objects dispatch table has been
updated, therefore decode_line_1 returns 2 symbols matching the 'bar'
method. With the criteria that whichever implementation was loaded
last is the one which is used.

because it is rather common for people to cache function pointers to
methods in order to avoid the overhead involved with the dispatch
table lookups, it is a uncommon but possible source of problems to
have a stale cached implementation, so its a good thing we can set a
breakpoint on all implementations of a specific method..

the patch for [5] at [6], will sort of kinda of fix part of these
issues, i've attached a rehashing of it
it will avoid the assertion failures, but it will also fail to
recognize when a category has been loaded and thus fail the "bar
category implementation" tests, so i suppose its better than the
current behaviour.

While the bug listed, mentions going another way about solving said
bug report, it is my opinion that the current assertion failures
cannot be fixed in such a way, only by either removing the assertion,
or avoiding the ambiguity, though we could always keep the assertion
and split it into 2 stages or something, an ambiguous stage and a
non-ambiguous stage with the assertion.

but there is some weirdness about re-enabling the iteration, for
instance it seems it would cause them to share conditions, i'm not
sure this is wanted in the method/function case, but it probably is in
the method/category method case.

[1]: http://sourceware.org/ml/gdb-patches/2008-03/msg00473.html
[2]: http://sourceware.org/ml/gdb-patches/2007-09/msg00306.html
[3]: info -f gdb --node='Method Names in Commands'
[4]: info -f gdb --node='Ambiguous Expressions'
[5]: http://sourceware.org/bugzilla/show_bug.cgi?id=8343
[6]: http://sourceware.org/bugzilla/show_bug.cgi?id=8535

P.S. the new tests are somewhat duplicated by the original tests I had
done, and the ones from Adam Fedor. I'm guessing that the requirements
of the new ones will probably work on a more limited set of platforms
i suppose, due to the dlopen requirements. Let me know if you want me
to roll these all into a single test, or if i should keep the old ones
around.

And with regard to 8343, this seems as good a place as any to discuss it,
given that we have up to 2 layers of ambiguity, maybe we need in the
breakpoint structure to differentiate between breakpoints which were
set by the user, and breakpoints which were derived from breakpoints
which are set by the user.

Then we can only ask the user about symbols which can be derived from
user-specified breakpoints, i'm not sure if this would require a
different return value from decode_line_1 or if this should be handled
in the 'break_command_really'.
that way we could avoid asking about '-[Foo(bar) create]' twice when
re_setting both 'create' and '-[Foo create]'. (when using
multiple-symbols ask), also seems like something that could be used
for something akin to a 'pending rbreak'.

P.P.S: these aren't 7.0 regressions they've been around since at least
6.8 in 7.0 we can ignore the assertions specifying 'N', and go about
our debugging where before we would get stuck in a loop with PR #8343
before we got to the assertions.

2009-09-10 Matt Rice <ratmice@gmail.com>

* lib/gdb.exp (gdb_continue_to_breakpoint): Fail on internal-error
instead of falling back to timeout.
* gdb.objc/objcdecode.exp: Set the multiple symbols found behaviour
to ask for the original test. Add tests for the multiple symbols
found behaviour of all.
* gdb.objc/ambiguous.exp: New tests for ObjC ambiguous expressions
across shared libraries.
* gdb.objc/ambiguous.m: Ditto.
* gdb.objc/objcdecode2.m: Ditto.
* gdb.objc/objcdecode2.h: Ditto.
* gdb.objc/objcdecode3.m: Ditto.

[-- Attachment #2: 0001--lib-gdb.exp-gdb_continue_to_breakpoint.patch --]
[-- Type: application/octet-stream, Size: 11242 bytes --]

From 62edd95e58fdd240c6fa85a12a4d3fbc7b1acb00 Mon Sep 17 00:00:00 2001
From: Matt Rice <ratmice@gmail.com>
Date: Fri, 11 Sep 2009 01:34:47 -0700
Subject: [PATCH 1/2] * lib/gdb.exp (gdb_continue_to_breakpoint): Fail on internal-error
instead of falling back to timeout.
* gdb.objc/objcdecode.exp: Set the multiple symbols found behaviour
to ask for the original test. Add tests for the multiple symbols
found behaviour of all.
* gdb.objc/ambiguous.exp: New tests for ObjC ambiguous expressions
across shared libraries.
* gdb.objc/ambiguous.m: Ditto.
* gdb.objc/objcdecode2.m: Ditto.
* gdb.objc/objcdecode2.h: Ditto.
* gdb.objc/objcdecode3.m: Ditto.

---
gdb/testsuite/gdb.objc/ambiguous.exp | 149 +++++++++++++++++++++++++++++++++
gdb/testsuite/gdb.objc/ambiguous.m | 35 ++++++++
gdb/testsuite/gdb.objc/objcdecode.exp | 55 ++++++++++++-
gdb/testsuite/gdb.objc/objcdecode2.h | 9 ++
gdb/testsuite/gdb.objc/objcdecode2.m | 20 +++++
gdb/testsuite/gdb.objc/objcdecode3.m | 19 ++++
gdb/testsuite/lib/gdb.exp | 5 +
7 files changed, 290 insertions(+), 2 deletions(-)
create mode 100644 gdb/testsuite/gdb.objc/ambiguous.exp
create mode 100644 gdb/testsuite/gdb.objc/ambiguous.m
create mode 100644 gdb/testsuite/gdb.objc/objcdecode2.h
create mode 100644 gdb/testsuite/gdb.objc/objcdecode2.m
create mode 100644 gdb/testsuite/gdb.objc/objcdecode3.m

diff --git a/gdb/testsuite/gdb.objc/ambiguous.exp b/gdb/testsuite/gdb.objc/ambiguous.exp
new file mode 100644
index 0000000..8c1c0d2
--- /dev/null
+++ b/gdb/testsuite/gdb.objc/ambiguous.exp
@@ -0,0 +1,149 @@
+# Copyright 2009 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/>.
+
+# This file tests breakpoints on ambiguous expressions in C and Obj-C symbols
+# And their affects across shared libraries.
+
+# This file was written by Matt Rice (ratmice@gmail.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+proc do_objc_tests {} {
+ global prms_id
+ global bug_id
+ global subdir
+ global objdir
+ global srcdir
+ global binfile
+ global gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+
+}
+
+set testfile "objcdecode2"
+set srcfile ${testfile}.m
+set binfile ${objdir}/${subdir}/lib${testfile}.so
+set lib_flags [list debug additional_flags=[list -g -fPIC -I${srcdir}/${subdir}] ]
+
+if {[gdb_compile_shlib "${srcdir}/${subdir}/${srcfile}" "${binfile}" $lib_flags] != "" } {
+ return -1
+}
+
+set testfile "objcdecode3"
+set srcfile ${testfile}.m
+set binfile ${objdir}/${subdir}/lib${testfile}.so
+set decode3_binfile $binfile
+
+if {[gdb_compile_shlib "${srcdir}/${subdir}/${srcfile}" "${binfile}" $lib_flags] != "" } {
+ return -1
+}
+
+
+set testfile "ambiguous"
+set srcfile ${testfile}.m
+set binfile ${objdir}/${subdir}/${testfile}
+set ambig_opts [list debug additional_flags=[list -g
+ -DSHLIB_NAME=\"$decode3_binfile\"
+ -L${objdir}/${subdir}
+ -Wl,-rpath,${objdir}/${subdir}
+ -ldl -lobjcdecode2
+ -I${srcdir}/${subdir}] ]
+
+if {[gdb_compile_objc "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $ambig_opts] != "" } {
+ return -1
+}
+
+do_objc_tests
+
+set name "ambiguous expression after shlib load"
+gdb_test_multiple "break foo" $name \
+{
+ -re "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*\r\n$gdb_prompt $" { pass $name }
+ -re ".*$gdb_prompt $" { fail $name }
+}
+
+gdb_run_cmd
+gdb_test_multiple "" $name \
+{
+ -re "Breakpoint \[0-9\]+, foo \\\(\\\) at .*\r\n$gdb_prompt $" {
+ pass $name
+ }
+ -re "\\\[0\\\] cancel\r\n\\\[1\\\] all\r\n\\\[2\\\] -.Decode foo. at .*\r\n\\\[3\\\] foo at .*\r\n> $" {
+ send_gdb "0\n"
+ kfail "gdb/1238" $name
+ # gdb is in a bad state here.
+ # It would be difficult to do any more tests after this.
+ }
+}
+
+gdb_test_multiple "break foo" $name \
+{
+ -re "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*\r\nBreakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*\r\n$gdb_prompt $" { pass $name }
+ -re ".*$gdb_prompt $" { kfail $name }
+}
+gdb_continue_to_breakpoint "foo class implementation"
+gdb_exit
+
+do_objc_tests
+
+send_gdb "set breakpoint pending on\n"
+
+set name "setting pending breakpoint"
+gdb_test_multiple "break -\[DecodeShlib bar\]" $name {
+ -re ".*$gdb_prompt $" { pass $name }
+}
+
+set name "multiply defined method via category implementation"
+gdb_test_multiple "run" $name \
+{
+ -re "Breakpoint \[0-9\]+, -\\\[DecodeShlib bar\\\] \\\(.*\\\) at .*\r\n$gdb_prompt $" {
+ pass $name
+ }
+ -re ".*$gdb_prompt $" { fail $name }
+}
+gdb_continue_to_breakpoint "bar category implementation"
+
+gdb_exit
+
+# i'm not sure why this reacts differently than the above tests
+# using pending breakpoints but it does: therefore i've added it, even though they appear quite similar.
+do_objc_tests
+
+if ![runto_main] {
+ fail "unable to run to main"
+}
+
+gdb_test_multiple "break bar" $name {
+ -re "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*\r\n$gdb_prompt $" {
+ pass $name
+ }
+ -re ".*$gdb_prompt $" { fail $name }
+}
+
+gdb_continue_to_breakpoint "bar class implementation"
+gdb_continue_to_breakpoint "bar category implementation"
+
+return 0
diff --git a/gdb/testsuite/gdb.objc/ambiguous.m b/gdb/testsuite/gdb.objc/ambiguous.m
new file mode 100644
index 0000000..fb59919
--- /dev/null
+++ b/gdb/testsuite/gdb.objc/ambiguous.m
@@ -0,0 +1,35 @@
+#include <objcdecode2.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef __WIN32__
+#include <windows.h>
+#define dlopen(name, mode) LoadLibrary (name)
+#define dlerror() "an error occurred"
+#else
+#include <dlfcn.h>
+#endif
+
+void foo()
+{
+ printf("function implementation\n");
+}
+
+int main()
+{
+ void *handle;
+ id obj = [DecodeShlib new];
+
+ foo();
+ [obj foo];
+
+ [obj bar]; /* class implementation */
+
+ handle = dlopen(SHLIB_NAME, RTLD_LAZY);
+ if (!handle)
+ fprintf(stderr, "error calling dlopen: %s\n", dlerror());
+
+ [obj foo]; /* category implementation */
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.objc/objcdecode.exp b/gdb/testsuite/gdb.objc/objcdecode.exp
index b751fb9..556aacc 100644
--- a/gdb/testsuite/gdb.objc/objcdecode.exp
+++ b/gdb/testsuite/gdb.objc/objcdecode.exp
@@ -59,7 +59,8 @@ do_objc_tests
#
# Break on multiply defined method (PR objc/1236)
#
-set name "break on multiply defined method"
+set name "break on multiply defined method using multiple-symbols ask"
+gdb_test "set multiple-symbols ask" ""
gdb_test_multiple "break multipleDef" $name \
{
-re "\\\[0\\\] cancel\r\n\\\[1\\\] all\r\n\\\[2\\\] -.Decode multipleDef. at .*\r\n\\\[3\\\] multipleDef at .*\r\n> $" {
@@ -70,7 +71,7 @@ gdb_test_multiple "break multipleDef" $name \
-re ".*$gdb_prompt $" { kfail "gdb/1236" $name }
}

-set name "continue after break on multiply defined symbol"
+set name "run after setting breakpoints on multiply defined symbol"
gdb_run_cmd
gdb_test_multiple "" $name \
{
@@ -84,3 +85,53 @@ gdb_test_multiple "" $name \
# It would be difficult to do any more tests after this.
}
}
+
+do_objc_tests
+if ![runto_main] { fail "Can't run to main" }
+
+set name "break on multiply defined symbol with multiple-symbols all after main"
+gdb_test "set multiple-symbols all after main" ""
+gdb_test_multiple "break multipleDef" $name \
+{
+ -re "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*\r\nBreakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*\r\n$gdb_prompt $" { pass $name }
+ -re ".*$gdb_prompt $" { fail $name }
+}
+
+set name "can hit multiply defined breakpoint on function after main"
+gdb_continue_to_breakpoint "function multipleDef"
+
+set name "can hit multiply defined breakpoint on objc method after main"
+gdb_continue_to_breakpoint "method multipleDef"
+gdb_exit
+
+do_objc_tests
+
+set name "break on multiply defined symbol with multiple-symbols all before main"
+gdb_test_multiple "break multipleDef" $name \
+{
+ -re "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*\r\nBreakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*\r\n$gdb_prompt $" { pass $name }
+ -re ".*$gdb_prompt $" { kfail $name }
+}
+
+set name "can hit multiply defined breakpoint on function before main"
+gdb_run_cmd
+gdb_test_multiple "" $name \
+{
+ -re "Breakpoint \[0-9\]+, multipleDef \\\(\\\) at .*\r\n$gdb_prompt $" {
+ pass $name
+ }
+ -re ".*$gdb_prompt $" { fail $name }
+}
+
+set name "can hit multiply defined breakpoint on method before main"
+gdb_test_multiple "continue" $name \
+{
+ -re "Breakpoint \[0-9\]+, -\\\[Decode multipleDef\\\] \\\(.*\\\) at .*\r\n$gdb_prompt $" {
+ pass $name
+ }
+ -re ".*$gdb_prompt $" { fail $name }
+}
+
+gdb_exit
+return 0
+
diff --git a/gdb/testsuite/gdb.objc/objcdecode2.h b/gdb/testsuite/gdb.objc/objcdecode2.h
new file mode 100644
index 0000000..d9c3bb8
--- /dev/null
+++ b/gdb/testsuite/gdb.objc/objcdecode2.h
@@ -0,0 +1,9 @@
+#include <objc/Object.h>
+
+@interface DecodeShlib: Object
+{
+}
+- foo;
+- bar;
+- (const char *) myDescription;
+@end
diff --git a/gdb/testsuite/gdb.objc/objcdecode2.m b/gdb/testsuite/gdb.objc/objcdecode2.m
new file mode 100644
index 0000000..4860c54
--- /dev/null
+++ b/gdb/testsuite/gdb.objc/objcdecode2.m
@@ -0,0 +1,20 @@
+#include <objcdecode2.h>
+#include <stdio.h>
+
+@implementation DecodeShlib
+
+- foo
+{
+ printf("foo class implementation\n");
+}
+
+- bar
+{
+ printf("bar class implementation\n");
+}
+
+- (const char *) myDescription
+{
+ return "DecodeShlib gdb test object";
+}
+@end
diff --git a/gdb/testsuite/gdb.objc/objcdecode3.m b/gdb/testsuite/gdb.objc/objcdecode3.m
new file mode 100644
index 0000000..97f6e4f
--- /dev/null
+++ b/gdb/testsuite/gdb.objc/objcdecode3.m
@@ -0,0 +1,19 @@
+#include <objcdecode2.h>
+#include <stdio.h>
+
+@interface DecodeShlib(CategoryInShlib)
+@end
+
+@implementation DecodeShlib(CategoryInShlib)
+
+- foo
+{
+ printf("foo category implementation\n");
+}
+
+- bar
+{
+ printf("bar category implementation\n");
+}
+
+@end
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 0c93a73..4f33486 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -474,6 +474,11 @@ proc gdb_continue_to_breakpoint {name {location_pattern .*}} {
-re ".*$gdb_prompt $" {
fail $full_name
}
+ -re ".*A problem internal to GDB has been detected" {
+ fail "$full_name (GDB internal error)"
+ gdb_internal_error_resync
+ }
+
timeout {
fail "$full_name (timeout)"
}
--
1.6.2.5

[-- Attachment #3: 0002-Add-enable_ambiguous-argument-to-decode_line_1.patch --]
[-- Type: application/octet-stream, Size: 6088 bytes --]

From 5a8bbadf3dc9bf701545c3592911351932810ece Mon Sep 17 00:00:00 2001
From: Matt Rice <ratmice@gmail.com>
Date: Fri, 11 Sep 2009 01:54:50 -0700
Subject: [PATCH 2/2] Add enable_ambiguous argument to decode_line_1.

---
gdb/breakpoint.c | 14 +++++++-------
gdb/cli/cli-cmds.c | 8 ++++----
gdb/linespec.c | 17 +++++++++--------
gdb/linespec.h | 3 ++-
gdb/symtab.c | 2 +-
gdb/tracepoint.c | 2 +-
6 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 9f50872..d242d43 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -5793,10 +5793,10 @@ parse_breakpoint_sals (char **address,
&& ((*address)[1] != '['))))
*sals = decode_line_1 (address, 1, default_breakpoint_symtab,
default_breakpoint_line, addr_string,
- not_found_ptr);
+ not_found_ptr, 1);
else
*sals = decode_line_1 (address, 1, (struct symtab *) NULL, 0,
- addr_string, not_found_ptr);
+ addr_string, not_found_ptr, 1);
}
/* For any SAL that didn't have a canonical string, fill one in. */
if (sals->nelts > 0 && *addr_string == NULL)
@@ -6697,10 +6697,10 @@ until_break_command (char *arg, int from_tty, int anywhere)

if (default_breakpoint_valid)
sals = decode_line_1 (&arg, 1, default_breakpoint_symtab,
- default_breakpoint_line, (char ***) NULL, NULL);
+ default_breakpoint_line, (char ***) NULL, NULL, 1);
else
sals = decode_line_1 (&arg, 1, (struct symtab *) NULL,
- 0, (char ***) NULL, NULL);
+ 0, (char ***) NULL, NULL, 1);

if (sals.nelts != 1)
error (_("Couldn't get information on specified line."));
@@ -7903,7 +7903,7 @@ breakpoint_re_set_one (void *bint)
TRY_CATCH (e, RETURN_MASK_ERROR)
{
sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL,
- not_found_ptr);
+ not_found_ptr, 0);
}
if (e.reason < 0)
{
@@ -8427,10 +8427,10 @@ decode_line_spec_1 (char *string, int funfirstline)
sals = decode_line_1 (&string, funfirstline,
default_breakpoint_symtab,
default_breakpoint_line,
- (char ***) NULL, NULL);
+ (char ***) NULL, NULL, 1);
else
sals = decode_line_1 (&string, funfirstline,
- (struct symtab *) NULL, 0, (char ***) NULL, NULL);
+ (struct symtab *) NULL, 0, (char ***) NULL, NULL, 1);
if (*string)
error (_("Junk at end of line specification: %s"), string);
return sals;
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index ce7c2a6..1f03305 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -650,7 +650,7 @@ edit_command (char *arg, int from_tty)
/* Now should only be one argument -- decode it in SAL. */

arg1 = arg;
- sals = decode_line_1 (&arg1, 0, 0, 0, 0, 0);
+ sals = decode_line_1 (&arg1, 0, 0, 0, 0, 0, 1);

if (! sals.nelts)
{
@@ -777,7 +777,7 @@ list_command (char *arg, int from_tty)
dummy_beg = 1;
else
{
- sals = decode_line_1 (&arg1, 0, 0, 0, 0, 0);
+ sals = decode_line_1 (&arg1, 0, 0, 0, 0, 0, 1);

if (!sals.nelts)
return; /* C++ */
@@ -810,9 +810,9 @@ list_command (char *arg, int from_tty)
else
{
if (dummy_beg)
- sals_end = decode_line_1 (&arg1, 0, 0, 0, 0, 0);
+ sals_end = decode_line_1 (&arg1, 0, 0, 0, 0, 0, 1);
else
- sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line, 0, 0);
+ sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line, 0, 0, 1);
if (sals_end.nelts == 0)
return;
if (sals_end.nelts > 1)
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 3e943a1..7cb6858 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -679,7 +679,7 @@ See set/show multiple-symbol."));

struct symtabs_and_lines
decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
- int default_line, char ***canonical, int *not_found_ptr)
+ int default_line, char ***canonical, int *not_found_ptr, int enable_ambiguity)
{
char *p;
char *q;
@@ -738,13 +738,14 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,

/* Check if the symbol could be an Objective-C selector. */

- {
- struct symtabs_and_lines values;
- values = decode_objc (argptr, funfirstline, NULL,
- canonical, saved_arg);
- if (values.sals != NULL)
- return values;
- }
+ if (enable_ambiguity)
+ {
+ struct symtabs_and_lines values;
+ values = decode_objc (argptr, funfirstline, NULL,
+ canonical, saved_arg);
+ if (values.sals != NULL)
+ return values;
+ }

/* Does it look like there actually were two parts? */

diff --git a/gdb/linespec.h b/gdb/linespec.h
index 8ac6ea7..d80aee9 100644
--- a/gdb/linespec.h
+++ b/gdb/linespec.h
@@ -22,6 +22,7 @@ struct symtab;
extern struct symtabs_and_lines
decode_line_1 (char **argptr, int funfirstline,
struct symtab *default_symtab, int default_line,
- char ***canonical, int *not_found_ptr);
+ char ***canonical, int *not_found_ptr,
+ int enable_ambiguity);

#endif /* defined (LINESPEC_H) */
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 8d9d72c..dae40d5 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -4471,7 +4471,7 @@ decode_line_spec (char *string, int funfirstline)

sals = decode_line_1 (&string, funfirstline,
cursal.symtab, cursal.line,
- (char ***) NULL, NULL);
+ (char ***) NULL, NULL, 1);

if (*string)
error (_("Junk at end of line specification: %s"), string);
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 0d439ef..c7b1d2d 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -1852,7 +1852,7 @@ scope_info (char *args, int from_tty)
if (args == 0 || *args == 0)
error (_("requires an argument (function, line or *addr) to define a scope"));

- sals = decode_line_1 (&args, 1, NULL, 0, &canonical, NULL);
+ sals = decode_line_1 (&args, 1, NULL, 0, &canonical, NULL, 1);
if (sals.nelts == 0)
return; /* presumably decode_line_1 has already warned */

--
1.6.2.5