aboutsummaryrefslogtreecommitdiff
path: root/gdb/printcmd.c
diff options
context:
space:
mode:
authorPaul Pluzhnikov <ppluzhnikov@google.com>2009-03-05 23:45:14 +0000
committerPaul Pluzhnikov <ppluzhnikov@google.com>2009-03-05 23:45:14 +0000
commita3247a22136e0b53cf5c40c67ee4f5e8eb92ec32 (patch)
treef87264eeaaddf26d435bc7553430988fb66560de /gdb/printcmd.c
parentd36df9c574a35b93e079b0058168474ad6872204 (diff)
downloadgdb-a3247a22136e0b53cf5c40c67ee4f5e8eb92ec32.zip
gdb-a3247a22136e0b53cf5c40c67ee4f5e8eb92ec32.tar.gz
gdb-a3247a22136e0b53cf5c40c67ee4f5e8eb92ec32.tar.bz2
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.
Diffstat (limited to 'gdb/printcmd.c')
-rw-r--r--gdb/printcmd.c94
1 files changed, 93 insertions, 1 deletions
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 375f82e..5862161 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -43,6 +43,11 @@
#include "disasm.h"
#include "dfp.h"
#include "valprint.h"
+#include "exceptions.h"
+#include "observer.h"
+#include "solist.h"
+#include "solib.h"
+#include "parser-defs.h"
#ifdef TUI
#include "tui/tui.h" /* For tui_active et.al. */
@@ -1395,7 +1400,7 @@ display_command (char *exp, int from_tty)
fmt.count = 0;
}
- innermost_block = 0;
+ innermost_block = NULL;
expr = parse_expression (exp);
new = (struct display *) xmalloc (sizeof (struct display));
@@ -1519,6 +1524,25 @@ do_one_display (struct display *d)
if (d->enabled_p == 0)
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)
within_current_scope = contained_in (get_selected_block (0), d->block);
else
@@ -1731,6 +1755,72 @@ disable_display_command (char *args, int from_tty)
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
@@ -2367,6 +2457,8 @@ _initialize_printcmd (void)
current_display_number = -1;
+ observer_attach_solib_unloaded (clear_dangling_display_expressions);
+
add_info ("address", address_info,
_("Describe where symbol SYM is stored."));