mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-06 15:38:45 +08:00
2009-03-05 Paul Pluzhnikov <ppluzhnikov@google.com>
* printcmd.c (do_one_display): Reparse exp_string. (display_uses_solib_p): New function. (clear_dangling_display_expressions): New function. (_initialize_printcmd): Add observer. * solib.c (no_shared_libraries): Swap order of calls to clear_solib and objfile_purge_solibs.
This commit is contained in:
@ -1,3 +1,12 @@
|
|||||||
|
2009-03-05 Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||||
|
|
||||||
|
* printcmd.c (do_one_display): Reparse exp_string.
|
||||||
|
(display_uses_solib_p): New function.
|
||||||
|
(clear_dangling_display_expressions): New function.
|
||||||
|
(_initialize_printcmd): Add observer.
|
||||||
|
* solib.c (no_shared_libraries): Swap order of calls to
|
||||||
|
clear_solib and objfile_purge_solibs.
|
||||||
|
|
||||||
2009-03-05 Joel Brobecker <brobecker@adacore.com>
|
2009-03-05 Joel Brobecker <brobecker@adacore.com>
|
||||||
|
|
||||||
Implement the target-specific part of Ada tasking support
|
Implement the target-specific part of Ada tasking support
|
||||||
|
@ -43,6 +43,11 @@
|
|||||||
#include "disasm.h"
|
#include "disasm.h"
|
||||||
#include "dfp.h"
|
#include "dfp.h"
|
||||||
#include "valprint.h"
|
#include "valprint.h"
|
||||||
|
#include "exceptions.h"
|
||||||
|
#include "observer.h"
|
||||||
|
#include "solist.h"
|
||||||
|
#include "solib.h"
|
||||||
|
#include "parser-defs.h"
|
||||||
|
|
||||||
#ifdef TUI
|
#ifdef TUI
|
||||||
#include "tui/tui.h" /* For tui_active et.al. */
|
#include "tui/tui.h" /* For tui_active et.al. */
|
||||||
@ -1395,7 +1400,7 @@ display_command (char *exp, int from_tty)
|
|||||||
fmt.count = 0;
|
fmt.count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
innermost_block = 0;
|
innermost_block = NULL;
|
||||||
expr = parse_expression (exp);
|
expr = parse_expression (exp);
|
||||||
|
|
||||||
new = (struct display *) xmalloc (sizeof (struct display));
|
new = (struct display *) xmalloc (sizeof (struct display));
|
||||||
@ -1519,6 +1524,25 @@ do_one_display (struct display *d)
|
|||||||
if (d->enabled_p == 0)
|
if (d->enabled_p == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (d->exp == NULL)
|
||||||
|
{
|
||||||
|
volatile struct gdb_exception ex;
|
||||||
|
TRY_CATCH (ex, RETURN_MASK_ALL)
|
||||||
|
{
|
||||||
|
innermost_block = NULL;
|
||||||
|
d->exp = parse_expression (d->exp_string);
|
||||||
|
d->block = innermost_block;
|
||||||
|
}
|
||||||
|
if (ex.reason < 0)
|
||||||
|
{
|
||||||
|
/* Can't re-parse the expression. Disable this display item. */
|
||||||
|
d->enabled_p = 0;
|
||||||
|
warning (_("Unable to display \"%s\": %s"),
|
||||||
|
d->exp_string, ex.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (d->block)
|
if (d->block)
|
||||||
within_current_scope = contained_in (get_selected_block (0), d->block);
|
within_current_scope = contained_in (get_selected_block (0), d->block);
|
||||||
else
|
else
|
||||||
@ -1731,6 +1755,72 @@ disable_display_command (char *args, int from_tty)
|
|||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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 i;
|
||||||
|
struct expression *const exp = d->exp;
|
||||||
|
|
||||||
|
if (d->block != NULL
|
||||||
|
&& solib_address (d->block->startaddr) == solib->so_name)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for (i = 0; i < exp->nelts; )
|
||||||
|
{
|
||||||
|
int args, oplen = 0;
|
||||||
|
const union exp_element *const elts = exp->elts;
|
||||||
|
|
||||||
|
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;
|
||||||
|
const struct obj_section *const section =
|
||||||
|
SYMBOL_OBJ_SECTION (symbol);
|
||||||
|
|
||||||
|
if (block != NULL
|
||||||
|
&& solib_address (block->startaddr) == solib->so_name)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (section && section->objfile == solib->objfile)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
exp->language_defn->la_exp_desc->operator_length (exp, i + 1,
|
||||||
|
&oplen, &args);
|
||||||
|
gdb_assert (oplen > 0);
|
||||||
|
i += 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
|
||||||
|
obstack_free'd when a shared library is unloaded.
|
||||||
|
Clear pointers that are about to become dangling.
|
||||||
|
Both .exp and .block fields will be restored next time we need to display
|
||||||
|
an item by re-parsing .exp_string field in the new execution context. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_dangling_display_expressions (struct so_list *solib)
|
||||||
|
{
|
||||||
|
struct display *d;
|
||||||
|
struct objfile *objfile = NULL;
|
||||||
|
|
||||||
|
for (d = display_chain; d; d = d->next)
|
||||||
|
{
|
||||||
|
if (d->exp && display_uses_solib_p (d, solib))
|
||||||
|
{
|
||||||
|
xfree (d->exp);
|
||||||
|
d->exp = NULL;
|
||||||
|
d->block = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Print the value in stack frame FRAME of a variable specified by a
|
/* Print the value in stack frame FRAME of a variable specified by a
|
||||||
@ -2367,6 +2457,8 @@ _initialize_printcmd (void)
|
|||||||
|
|
||||||
current_display_number = -1;
|
current_display_number = -1;
|
||||||
|
|
||||||
|
observer_attach_solib_unloaded (clear_dangling_display_expressions);
|
||||||
|
|
||||||
add_info ("address", address_info,
|
add_info ("address", address_info,
|
||||||
_("Describe where symbol SYM is stored."));
|
_("Describe where symbol SYM is stored."));
|
||||||
|
|
||||||
|
@ -999,8 +999,13 @@ sharedlibrary_command (char *args, int from_tty)
|
|||||||
void
|
void
|
||||||
no_shared_libraries (char *ignored, int from_tty)
|
no_shared_libraries (char *ignored, int from_tty)
|
||||||
{
|
{
|
||||||
objfile_purge_solibs ();
|
/* The order of the two routines below is important: clear_solib notifies
|
||||||
|
the solib_unloaded observers, and some of these observers might need
|
||||||
|
access to their associated objfiles. Therefore, we can not purge the
|
||||||
|
solibs' objfiles before clear_solib has been called. */
|
||||||
|
|
||||||
clear_solib ();
|
clear_solib ();
|
||||||
|
objfile_purge_solibs ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
2009-03-05 Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||||
|
|
||||||
|
* solib-display.exp: New file.
|
||||||
|
* solib-display-main.c: New file.
|
||||||
|
* solib-display-lib.c: New file.
|
||||||
|
|
||||||
2009-03-05 Pedro Alves <pedro@codesourcery.com>
|
2009-03-05 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
* gdb.arch/i386-permbkpt.S, gdb.arch/i386-permbkpt.exp: New.
|
* gdb.arch/i386-permbkpt.S, gdb.arch/i386-permbkpt.exp: New.
|
||||||
|
30
gdb/testsuite/gdb.base/solib-display-lib.c
Normal file
30
gdb/testsuite/gdb.base/solib-display-lib.c
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/* This testcase is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
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/>. */
|
||||||
|
|
||||||
|
int a_global = 41;
|
||||||
|
#ifndef NO_B_GLOBAL
|
||||||
|
int b_global = 42;
|
||||||
|
#endif
|
||||||
|
int c_global = 43;
|
||||||
|
|
||||||
|
int foo () {
|
||||||
|
return a_global +
|
||||||
|
#ifndef NO_B_GLOBAL
|
||||||
|
b_global +
|
||||||
|
#endif
|
||||||
|
c_global;
|
||||||
|
}
|
32
gdb/testsuite/gdb.base/solib-display-main.c
Normal file
32
gdb/testsuite/gdb.base/solib-display-main.c
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* This testcase is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
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/>. */
|
||||||
|
|
||||||
|
extern int foo ();
|
||||||
|
|
||||||
|
int main_global = 44;
|
||||||
|
int bar ()
|
||||||
|
{
|
||||||
|
int a_local = 45;
|
||||||
|
static int a_static = 46;
|
||||||
|
return main_global + a_local + a_static; /* break here */
|
||||||
|
}
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
bar ();
|
||||||
|
return foo ();
|
||||||
|
}
|
115
gdb/testsuite/gdb.base/solib-display.exp
Normal file
115
gdb/testsuite/gdb.base/solib-display.exp
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
# 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/>.
|
||||||
|
#
|
||||||
|
# Contributed by Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||||
|
#
|
||||||
|
|
||||||
|
# This test case verifies that if a display is active on a variable
|
||||||
|
# which belongs in a shared library, and that shared library is
|
||||||
|
# reloaded (e.g. due to re-execution of the program), GDB will continue
|
||||||
|
# to display it (gdb-6.8 crashed under this scenario).
|
||||||
|
|
||||||
|
# Also test that a display of variable which is currently present in
|
||||||
|
# a shared library, but disappears before re-run, doesn't cause GDB
|
||||||
|
# difficulties, and that it continues to display other variables.
|
||||||
|
|
||||||
|
# Finally, test that displays which refer to main executable
|
||||||
|
# (and thus aren't affected by shared library unloading) are not
|
||||||
|
# disabled prematurely.
|
||||||
|
|
||||||
|
if [skip_shlib_tests] then {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Library file.
|
||||||
|
set libname "solib-display-lib"
|
||||||
|
set srcfile_lib ${srcdir}/${subdir}/${libname}.c
|
||||||
|
set binfile_lib ${objdir}/${subdir}/${libname}.so
|
||||||
|
set lib_flags [list debug]
|
||||||
|
# Binary file.
|
||||||
|
set testfile "solib-display-main"
|
||||||
|
set srcfile ${srcdir}/${subdir}/${testfile}.c
|
||||||
|
set binfile ${objdir}/${subdir}/${testfile}
|
||||||
|
set bin_flags [list debug shlib=${binfile_lib}]
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_exit
|
||||||
|
gdb_start
|
||||||
|
gdb_reinitialize_dir $srcdir/$subdir
|
||||||
|
gdb_load ${binfile}
|
||||||
|
|
||||||
|
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.*"
|
||||||
|
|
||||||
|
gdb_exit
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user