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

