gdb/
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.
This commit is contained in:
parent
793b0ff8d7
commit
c0201579c8
15 changed files with 355 additions and 114 deletions
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
145
gdb/parse.c
145
gdb/parse.c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 } {
|
||||
|
||||
|
|
Loading…
Reference in a new issue