gdb/
authorJan Kratochvil <jan.kratochvil@redhat.com>
Thu, 22 Apr 2010 23:15:43 +0000 (23:15 +0000)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Thu, 22 Apr 2010 23:15:43 +0000 (23:15 +0000)
Fix crashes on dangling display expressions.
* ada-lang.c (ada_operator_check): New function.
(ada_exp_descriptor): Fill-in the field operator_check.
* c-lang.c (exp_descriptor_c): Fill-in the field operator_check.
* jv-lang.c (exp_descriptor_java): Likewise.
* m2-lang.c (exp_descriptor_modula2): Likewise.
* scm-lang.c (exp_descriptor_scm): Likewise.
* parse.c (exp_descriptor_standard): Likewise.
(operator_check_standard): New function.
(exp_iterate, exp_uses_objfile_iter, exp_uses_objfile): New functions.
* parser-defs.h (struct exp_descriptor): New field operator_check.
(operator_check_standard, exp_uses_objfile): New declarations.
* printcmd.c: Remove the inclusion of solib.h.
(display_uses_solib_p): Remove the function.
(clear_dangling_display_expressions): Call lookup_objfile_from_block
and exp_uses_objfile instead of display_uses_solib_p.
* solist.h (struct so_list) <objfile>: New comment.
* symtab.c (lookup_objfile_from_block): Remove the static qualifier.
* symtab.h (lookup_objfile_from_block): New declaration.
(struct general_symbol_info) <obj_section>: Extend the comment.

gdb/testsuite/
Fix crashes on dangling display expressions.
* gdb.base/solib-display.exp: Call gdb_gnu_strip_debug if LIBSEPDEBUG
is SEP.
(lib_flags): Remove the "debug" keyword.
(libsepdebug): New variable for iterating new loop.
(save_pf_prefix): New variable wrapping the loop.
(sep_lib_flags): New variable derived from LIB_FLAGS.  Use it.
* lib/gdb.exp (gdb_gnu_strip_debug): Document the return code.

15 files changed:
gdb/ChangeLog
gdb/ada-lang.c
gdb/c-lang.c
gdb/jv-lang.c
gdb/m2-lang.c
gdb/parse.c
gdb/parser-defs.h
gdb/printcmd.c
gdb/scm-lang.c
gdb/solist.h
gdb/symtab.c
gdb/symtab.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/solib-display.exp
gdb/testsuite/lib/gdb.exp

index 42571e67dda1a11f4eab5b66b1d31dacba54e109..e0e3353a7b6d60bd8f3d33dca0f404149f7b34e5 100644 (file)
@@ -1,3 +1,26 @@
+2010-04-22  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       Fix crashes on dangling display expressions.
+       * ada-lang.c (ada_operator_check): New function.
+       (ada_exp_descriptor): Fill-in the field operator_check.
+       * c-lang.c (exp_descriptor_c): Fill-in the field operator_check.
+       * jv-lang.c (exp_descriptor_java): Likewise.
+       * m2-lang.c (exp_descriptor_modula2): Likewise.
+       * scm-lang.c (exp_descriptor_scm): Likewise.
+       * parse.c (exp_descriptor_standard): Likewise.
+       (operator_check_standard): New function.
+       (exp_iterate, exp_uses_objfile_iter, exp_uses_objfile): New functions.
+       * parser-defs.h (struct exp_descriptor): New field operator_check.
+       (operator_check_standard, exp_uses_objfile): New declarations.
+       * printcmd.c: Remove the inclusion of solib.h.
+       (display_uses_solib_p): Remove the function.
+       (clear_dangling_display_expressions): Call lookup_objfile_from_block
+       and exp_uses_objfile instead of display_uses_solib_p.
+       * solist.h (struct so_list) <objfile>: New comment.
+       * symtab.c (lookup_objfile_from_block): Remove the static qualifier.
+       * symtab.h (lookup_objfile_from_block): New declaration.
+       (struct general_symbol_info) <obj_section>: Extend the comment.
+
 2010-04-22  Sergio Durigan Junior  <sergiodj@linux.vnet.ibm.com>
            Thiago Jung Bauermann  <bauerman@br.ibm.com>
 
index abc9c9fb8490658f201a3cc18e16ee691545588d..9da0609458eb08df4d5e7635e021abdc99e51673 100644 (file)
@@ -10887,6 +10887,36 @@ ada_operator_length (struct expression *exp, int pc, int *oplenp, int *argsp)
     }
 }
 
+/* Implementation of the exp_descriptor method operator_check.  */
+
+static int
+ada_operator_check (struct expression *exp, int pos,
+                   int (*objfile_func) (struct objfile *objfile, void *data),
+                   void *data)
+{
+  const union exp_element *const elts = exp->elts;
+  struct type *type = NULL;
+
+  switch (elts[pos].opcode)
+    {
+      case UNOP_IN_RANGE:
+      case UNOP_QUAL:
+       type = elts[pos + 1].type;
+       break;
+
+      default:
+       return operator_check_standard (exp, pos, objfile_func, data);
+    }
+
+  /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL.  */
+
+  if (type && TYPE_OBJFILE (type)
+      && (*objfile_func) (TYPE_OBJFILE (type), data))
+    return 1;
+
+  return 0;
+}
+
 static char *
 ada_op_name (enum exp_opcode opcode)
 {
@@ -11275,6 +11305,7 @@ parse (void)
 static const struct exp_descriptor ada_exp_descriptor = {
   ada_print_subexp,
   ada_operator_length,
+  ada_operator_check,
   ada_op_name,
   ada_dump_subexp_body,
   ada_evaluate_subexp
index fefd67556459156040fe5f3ed9dedaa9edbba0a5..805c57255d9c165f61e7551668f136c4567aa4db 100644 (file)
@@ -1139,6 +1139,7 @@ static const struct exp_descriptor exp_descriptor_c =
 {
   print_subexp_standard,
   operator_length_standard,
+  operator_check_standard,
   op_name_standard,
   dump_subexp_body_standard,
   evaluate_subexp_c
index 6c449ef40c360e0d866667f7908fdc056ebe1b03..b9117246bf1040ff13fb62a7596c63356d7b3ee3 100644 (file)
@@ -1162,6 +1162,7 @@ const struct exp_descriptor exp_descriptor_java =
 {
   print_subexp_standard,
   operator_length_standard,
+  operator_check_standard,
   op_name_standard,
   dump_subexp_body_standard,
   evaluate_subexp_java
index 80e9bf90d1fa3aab29ed009cc7e3c863cd92fe3f..30577744170a28e4498120ff58caa9d7006fa987 100644 (file)
@@ -356,6 +356,7 @@ const struct exp_descriptor exp_descriptor_modula2 =
 {
   print_subexp_standard,
   operator_length_standard,
+  operator_check_standard,
   op_name_standard,
   dump_subexp_body_standard,
   evaluate_subexp_modula2
index aabc4616c8432323e7b3d18fc2fe1eaed4673a25..51e15505a25238dc0c82dbecd8000cce2f4c279a 100644 (file)
@@ -62,6 +62,7 @@ const struct exp_descriptor exp_descriptor_standard =
   {
     print_subexp_standard,
     operator_length_standard,
+    operator_check_standard,
     op_name_standard,
     dump_subexp_body_standard,
     evaluate_subexp_standard
@@ -1373,6 +1374,150 @@ parser_fprintf (FILE *x, const char *y, ...)
   va_end (args);
 }
 
+/* Implementation of the exp_descriptor method operator_check.  */
+
+int
+operator_check_standard (struct expression *exp, int pos,
+                        int (*objfile_func) (struct objfile *objfile,
+                                             void *data),
+                        void *data)
+{
+  const union exp_element *const elts = exp->elts;
+  struct type *type = NULL;
+  struct objfile *objfile = NULL;
+
+  /* Extended operators should have been already handled by exp_descriptor
+     iterate method of its specific language.  */
+  gdb_assert (elts[pos].opcode < OP_EXTENDED0);
+
+  /* Track the callers of write_exp_elt_type for this table.  */
+
+  switch (elts[pos].opcode)
+    {
+    case BINOP_VAL:
+    case OP_COMPLEX:
+    case OP_DECFLOAT:
+    case OP_DOUBLE:
+    case OP_LONG:
+    case OP_SCOPE:
+    case OP_TYPE:
+    case UNOP_CAST:
+    case UNOP_DYNAMIC_CAST:
+    case UNOP_REINTERPRET_CAST:
+    case UNOP_MAX:
+    case UNOP_MEMVAL:
+    case UNOP_MIN:
+      type = elts[pos + 1].type;
+      break;
+
+    case TYPE_INSTANCE:
+      {
+       LONGEST arg, nargs = elts[pos + 1].longconst;
+
+       for (arg = 0; arg < nargs; arg++)
+         {
+           struct type *type = elts[pos + 2 + arg].type;
+           struct objfile *objfile = TYPE_OBJFILE (type);
+
+           if (objfile && (*objfile_func) (objfile, data))
+             return 1;
+         }
+      }
+      break;
+
+    case UNOP_MEMVAL_TLS:
+      objfile = elts[pos + 1].objfile;
+      type = elts[pos + 2].type;
+      break;
+
+    case OP_VAR_VALUE:
+      {
+       const struct block *const block = elts[pos + 1].block;
+       const struct symbol *const symbol = elts[pos + 2].symbol;
+
+       /* Check objfile where the variable itself is placed.
+          SYMBOL_OBJ_SECTION (symbol) may be NULL.  */
+       if ((*objfile_func) (SYMBOL_SYMTAB (symbol)->objfile, data))
+         return 1;
+
+       /* Check objfile where is placed the code touching the variable.  */
+       objfile = lookup_objfile_from_block (block);
+
+       type = SYMBOL_TYPE (symbol);
+      }
+      break;
+    }
+
+  /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL.  */
+
+  if (type && TYPE_OBJFILE (type)
+      && (*objfile_func) (TYPE_OBJFILE (type), data))
+    return 1;
+  if (objfile && (*objfile_func) (objfile, data))
+    return 1;
+
+  return 0;
+}
+
+/* Call OBJFILE_FUNC for any TYPE and OBJFILE found being referenced by EXP.
+   The functions are never called with NULL OBJFILE.  Functions get passed an
+   arbitrary caller supplied DATA pointer.  If any of the functions returns
+   non-zero value then (any other) non-zero value is immediately returned to
+   the caller.  Otherwise zero is returned after iterating through whole EXP.
+   */
+
+static int
+exp_iterate (struct expression *exp,
+            int (*objfile_func) (struct objfile *objfile, void *data),
+            void *data)
+{
+  int endpos;
+  const union exp_element *const elts = exp->elts;
+
+  for (endpos = exp->nelts; endpos > 0; )
+    {
+      int pos, args, oplen = 0;
+
+      exp->language_defn->la_exp_desc->operator_length (exp, endpos,
+                                                       &oplen, &args);
+      gdb_assert (oplen > 0);
+
+      pos = endpos - oplen;
+      if (exp->language_defn->la_exp_desc->operator_check (exp, pos,
+                                                          objfile_func, data))
+       return 1;
+
+      endpos = pos;
+    }
+
+  return 0;
+}
+
+/* Helper for exp_uses_objfile.  */
+
+static int
+exp_uses_objfile_iter (struct objfile *exp_objfile, void *objfile_voidp)
+{
+  struct objfile *objfile = objfile_voidp;
+
+  if (exp_objfile->separate_debug_objfile_backlink)
+    exp_objfile = exp_objfile->separate_debug_objfile_backlink;
+
+  return exp_objfile == objfile;
+}
+
+/* Return 1 if EXP uses OBJFILE (and will become dangling when OBJFILE
+   is unloaded), otherwise return 0.  OBJFILE must not be a separate debug info
+   file.  */
+
+int
+exp_uses_objfile (struct expression *exp, struct objfile *objfile)
+{
+  gdb_assert (objfile->separate_debug_objfile_backlink == NULL);
+
+  return exp_iterate (exp, exp_uses_objfile_iter, objfile);
+}
+
 void
 _initialize_parse (void)
 {
index c4eb1a042a814713e6788501e8d6b606211215b8..a37bbcaa2b6438493f5b449de1425c2665b42210 100644 (file)
@@ -192,6 +192,11 @@ extern void operator_length (struct expression *, int, int *, int *);
 
 extern void operator_length_standard (struct expression *, int, int *, int *);
 
+extern int operator_check_standard (struct expression *exp, int pos,
+                                   int (*objfile_func)
+                                     (struct objfile *objfile, void *data),
+                                   void *data);
+
 extern char *op_name_standard (enum exp_opcode);
 
 extern struct type *follow_types (struct type *);
@@ -270,6 +275,19 @@ struct exp_descriptor
        the number of subexpressions it takes.  */
     void (*operator_length) (struct expression*, int, int*, int *);
 
+    /* Call TYPE_FUNC and OBJFILE_FUNC for any TYPE and OBJFILE found being
+       referenced by the single operator of EXP at position POS.  Operator
+       parameters are located at positive (POS + number) offsets in EXP.
+       The functions should never be called with NULL TYPE or NULL OBJFILE.
+       Functions should get passed an arbitrary caller supplied DATA pointer.
+       If any of the functions returns non-zero value then (any other) non-zero
+       value should be immediately returned to the caller.  Otherwise zero
+       should be returned.  */
+    int (*operator_check) (struct expression *exp, int pos,
+                          int (*objfile_func) (struct objfile *objfile,
+                                               void *data),
+                          void *data);
+
     /* Name of this operator for dumping purposes.  */
     char *(*op_name) (enum exp_opcode);
 
@@ -302,4 +320,6 @@ extern void print_subexp_standard (struct expression *, int *,
 
 extern void parser_fprintf (FILE *, const char *, ...) ATTR_FORMAT (printf, 2 ,3);
 
+extern int exp_uses_objfile (struct expression *exp, struct objfile *objfile);
+
 #endif /* PARSER_DEFS_H */
index be6a8a5fa4b21bb5e2a70316c815bcf30a231b4a..735b043e76b4166e28b9c3e6525ee8077fc492e5 100644 (file)
@@ -46,7 +46,6 @@
 #include "exceptions.h"
 #include "observer.h"
 #include "solist.h"
-#include "solib.h"
 #include "parser-defs.h"
 #include "charset.h"
 #include "arch-utils.h"
@@ -1891,51 +1890,6 @@ disable_display_command (char *args, int from_tty)
       }
 }
 
-/* Return 1 if D uses SOLIB (and will become dangling when SOLIB
-   is unloaded), otherwise return 0.  */
-
-static int
-display_uses_solib_p (const struct display *d,
-                     const struct so_list *solib)
-{
-  int endpos;
-  struct expression *const exp = d->exp;
-  const union exp_element *const elts = exp->elts;
-
-  if (d->block != NULL
-      && d->pspace == solib->pspace
-      && solib_contains_address_p (solib, d->block->startaddr))
-    return 1;
-
-  for (endpos = exp->nelts; endpos > 0; )
-    {
-      int i, args, oplen = 0;
-
-      exp->language_defn->la_exp_desc->operator_length (exp, endpos,
-                                                       &oplen, &args);
-      gdb_assert (oplen > 0);
-
-      i = endpos - oplen;
-      if (elts[i].opcode == OP_VAR_VALUE)
-       {
-         const struct block *const block = elts[i + 1].block;
-         const struct symbol *const symbol = elts[i + 2].symbol;
-
-         if (block != NULL
-             && solib_contains_address_p (solib,
-                                          block->startaddr))
-           return 1;
-
-         /* SYMBOL_OBJ_SECTION (symbol) may be NULL.  */
-         if (SYMBOL_SYMTAB (symbol)->objfile == solib->objfile)
-           return 1;
-       }
-      endpos -= oplen;
-    }
-
-  return 0;
-}
-
 /* display_chain items point to blocks and expressions.  Some expressions in
    turn may point to symbols.
    Both symbols and blocks are obstack_alloc'd on objfile_stack, and are
@@ -1947,17 +1901,28 @@ display_uses_solib_p (const struct display *d,
 static void
 clear_dangling_display_expressions (struct so_list *solib)
 {
+  struct objfile *objfile = solib->objfile;
   struct display *d;
-  struct objfile *objfile = NULL;
 
-  for (d = display_chain; d; d = d->next)
+  /* With no symbol file we cannot have a block or expression from it.  */
+  if (objfile == NULL)
+    return;
+  if (objfile->separate_debug_objfile_backlink)
+    objfile = objfile->separate_debug_objfile_backlink;
+  gdb_assert (objfile->pspace == solib->pspace);
+
+  for (d = display_chain; d != NULL; d = d->next)
     {
-      if (d->exp && display_uses_solib_p (d, solib))
-       {
-         xfree (d->exp);
-         d->exp = NULL;
-         d->block = NULL;
-       }
+      if (d->pspace != solib->pspace)
+       continue;
+
+      if (lookup_objfile_from_block (d->block) == objfile
+         || (d->exp && exp_uses_objfile (d->exp, objfile)))
+      {
+       xfree (d->exp);
+       d->exp = NULL;
+       d->block = NULL;
+      }
     }
 }
 \f
index 5898aadad36f214f884a5488feec826666777143..23e5f22f365d9029d9879726ff9786ec1d8a3c0e 100644 (file)
@@ -231,6 +231,7 @@ const struct exp_descriptor exp_descriptor_scm =
 {
   print_subexp_standard,
   operator_length_standard,
+  operator_check_standard,
   op_name_standard,
   dump_subexp_body_standard,
   evaluate_exp
index 77eb2aeaa4823cea717a50ab047cfba85218a1ee..bcba0ad65b6871d224fe35923dec54e644aca4fd 100644 (file)
@@ -63,7 +63,12 @@ struct so_list
 
     bfd *abfd;
     char symbols_loaded;       /* flag: symbols read in yet? */
-    struct objfile *objfile;   /* objfile for loaded lib */
+
+    /* objfile with symbols for a loaded library.  Target memory is read from
+       ABFD.  OBJFILE may be NULL either before symbols have been loaded, if
+       the file cannot be found or after the command "nosharedlibrary".  */
+    struct objfile *objfile;
+
     struct target_section *sections;
     struct target_section *sections_end;
 
index 29142dab47f8077297d661f7f6c68f46bccb0c55..28084e766f6c57b20ceae740d4b996d9edbf8d2f 100644 (file)
@@ -1150,7 +1150,7 @@ lookup_symbol_aux_local (const char *name, const struct block *block,
 
 /* Look up OBJFILE to BLOCK.  */
 
-static struct objfile *
+struct objfile *
 lookup_objfile_from_block (const struct block *block)
 {
   struct objfile *obj;
index a0da0db9bcf12ab88ec38b41d7857b532570046d..115c8ba15ec7a0b2791bedf0ea2d379f743166d4 100644 (file)
@@ -148,7 +148,7 @@ struct general_symbol_info
 
   short section;
 
-  /* The section associated with this symbol. */
+  /* The section associated with this symbol.  It can be NULL.  */
 
   struct obj_section *obj_section;
 };
@@ -1207,4 +1207,6 @@ int producer_is_realview (const char *producer);
 void fixup_section (struct general_symbol_info *ginfo,
                    CORE_ADDR addr, struct objfile *objfile);
 
+struct objfile *lookup_objfile_from_block (const struct block *block);
+
 #endif /* !defined(SYMTAB_H) */
index 6bbacf029d6ec4a5cfb643df1716e2e196d39d54..025e50d784445b532d36a2aea00bf0954c482618 100644 (file)
@@ -1,3 +1,14 @@
+2010-04-22  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       Fix crashes on dangling display expressions.
+       * gdb.base/solib-display.exp: Call gdb_gnu_strip_debug if LIBSEPDEBUG
+       is SEP.
+       (lib_flags): Remove the "debug" keyword.
+       (libsepdebug): New variable for iterating new loop.
+       (save_pf_prefix): New variable wrapping the loop.
+       (sep_lib_flags): New variable derived from LIB_FLAGS.  Use it.
+       * lib/gdb.exp (gdb_gnu_strip_debug): Document the return code.
+
 2010-04-22  Pierre Muller  <muller@ics.u-strasbg.fr>
 
        * gdb.threads/watchthreads.exp: Change to obtain consistent output.
index 42a48d01e4cd7ff151cd35b31a2c31730301eb22..9ee2633b48d87c25d867e739dff9071f3c95b1c8 100644 (file)
@@ -36,7 +36,7 @@ if { [skip_shlib_tests] || [is_remote target] } {
 set libname "solib-display-lib"
 set srcfile_lib ${srcdir}/${subdir}/${libname}.c
 set binfile_lib ${objdir}/${subdir}/${libname}.so
-set lib_flags [list debug]
+set lib_flags {}
 # Binary file.
 set testfile "solib-display-main"
 set srcfile ${srcdir}/${subdir}/${testfile}.c
@@ -48,60 +48,92 @@ if [get_compiler_info ${binfile}] {
     return -1
 }
 
-if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != ""
-     || [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } {
-  untested "Could not compile $binfile_lib or $binfile."
-  return -1
+set save_pf_prefix $pf_prefix
+# SEP must be last for the possible `unsupported' error path.
+foreach libsepdebug {NO IN SEP} {
+
+    set pf_prefix $save_pf_prefix
+    lappend pf_prefix "$libsepdebug:"
+
+    set sep_lib_flags $lib_flags
+    if {$libsepdebug != "NO"} {
+       lappend sep_lib_flags {debug}
+    }
+    if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $sep_lib_flags] != ""
+        || [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } {
+      untested "Could not compile $binfile_lib or $binfile."
+      return -1
+    }
+
+    if {$libsepdebug == "SEP"} {
+       if {[gdb_gnu_strip_debug $binfile_lib] != 0} {
+           unsupported "Could not split debug of $binfile_lib."
+           return
+       } else {
+           pass "split solib"
+       }
+    }
+
+    clean_restart $executable
+
+    if ![runto_main] then {
+      fail "Can't run to main"
+      return 0
+    }
+
+    gdb_test "display a_global" "1: a_global = 41"
+    gdb_test "display b_global" "2: b_global = 42"
+    gdb_test "display c_global" "3: c_global = 43"
+
+    if { [gdb_start_cmd] < 0 } {
+       fail "Can't run to main (2)"
+       continue
+    }
+
+    gdb_test "" "3: c_global = 43\\r\\n2: b_global = 42\\r\\n1: a_global = 41" "after rerun"
+
+    # Now rebuild the library without b_global
+    if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} \
+             "$sep_lib_flags additional_flags=-DNO_B_GLOBAL"] != ""} {
+       fail "Can't rebuild $binfile_lib"
+    }
+
+    if {$libsepdebug == "SEP"} {
+       set test "split solib second time"
+       if {[gdb_gnu_strip_debug $binfile_lib] != 0} {
+           fail $test
+           continue
+       } else {
+           pass $test
+       }
+    }
+
+    if { [gdb_start_cmd] < 0 } {
+       fail "Can't run to main (3)"
+       continue
+    }
+
+    gdb_test "" "3: c_global = 43\\r\\nwarning: .*b_global.*\\r\\n1: a_global = 41" "after rerun (2)"
+
+    # Now verify that displays which are not in the shared library
+    # are not cleared permaturely.
+
+    gdb_test "break [gdb_get_line_number "break here" ${testfile}.c]" \
+           ".*Breakpoint.* at .*" 
+
+    gdb_test "continue"
+    gdb_test "display main_global" "4: main_global = 44"
+    gdb_test "display a_local" "5: a_local = 45"
+    gdb_test "display a_static" "6: a_static = 46"
+
+    if { [gdb_start_cmd] < 0 } {
+       fail "Can't run to main (4)"
+       continue
+    }
+
+    gdb_test "" "6: a_static = 46\\r\\n4: main_global = 44\\r\\n.*"
+    gdb_test "break [gdb_get_line_number "break here" ${testfile}.c]" \
+           ".*Breakpoint.* at .*" 
+    gdb_test "continue" "6: a_static = 46\\r\\n5: a_local = 45\\r\\n4: main_global = 44\\r\\n.*"
 }
-
-clean_restart ${executable}
-
-if ![runto_main] then {
-  fail "Can't run to main"
-  return 0
-}
-
-gdb_test "display a_global" "1: a_global = 41"
-gdb_test "display b_global" "2: b_global = 42"
-gdb_test "display c_global" "3: c_global = 43"
-
-if { [gdb_start_cmd] < 0 } {
-    fail "Can't run to main (2)"
-    return 0
-}
-
-gdb_test "" "3: c_global = 43\\r\\n2: b_global = 42\\r\\n1: a_global = 41" "after rerun"
-
-# Now rebuild the library without b_global
-if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} \
-         "$lib_flags additional_flags=-DNO_B_GLOBAL"] != ""} {
-    fail "Can't rebuild $binfile_lib"
-}
-
-if { [gdb_start_cmd] < 0 } {
-    fail "Can't run to main (3)"
-    return 0
-}
-
-gdb_test "" "3: c_global = 43\\r\\nwarning: .*b_global.*\\r\\n1: a_global = 41" "after rerun"
-
-# Now verify that displays which are not in the shared library
-# are not cleared permaturely.
-
-gdb_test "break [gdb_get_line_number "break here" ${testfile}.c]" \
-       ".*Breakpoint.* at .*" 
-
-gdb_test "continue"
-gdb_test "display main_global" "4: main_global = 44"
-gdb_test "display a_local" "5: a_local = 45"
-gdb_test "display a_static" "6: a_static = 46"
-
-if { [gdb_start_cmd] < 0 } {
-    fail "Can't run to main (4)"
-    return 0
-}
-
-gdb_test "" "6: a_static = 46\\r\\n4: main_global = 44\\r\\n.*"
-gdb_test "break [gdb_get_line_number "break here" ${testfile}.c]" \
-       ".*Breakpoint.* at .*" 
-gdb_test "continue" "6: a_static = 46\\r\\n5: a_local = 45\\r\\n4: main_global = 44\\r\\n.*"
+set pf_prefix $save_pf_prefix
index 19126a46ef57c9c149785ba1f5e03e370b65004a..3a1fad3cb9b3eedc7630ec0691f1178dfa168f46 100644 (file)
@@ -2896,6 +2896,9 @@ proc build_id_debug_filename_get { exec } {
 # Create stripped files for DEST, replacing it.  If ARGS is passed, it is a
 # list of optional flags.  The only currently supported flag is no-main,
 # which removes the symbol entry for main from the separate debug file.
+#
+# Function returns zero on success.  Function will return non-zero failure code
+# on some targets not supporting separate debug info (such as i386-msdos).
 
 proc gdb_gnu_strip_debug { dest args } {