8aabf36e77
- Fix entryval feature crash on some .debug files optimized by dwz (BZ 839596). - Fix another stale frame_info * (PR 11914, like PR 13866).
296 lines
9.4 KiB
Diff
296 lines
9.4 KiB
Diff
http://sourceware.org/ml/gdb-patches/2012-07/msg00197.html
|
|
Subject: [patch] Fix another stale frame_info * (PR 11914, like PR 13866)
|
|
|
|
Hi,
|
|
|
|
http://sourceware.org/bugzilla/show_bug.cgi?id=11914
|
|
|
|
has another case of stale frame_info *. Originally I found it unfixable with
|
|
the current struct frame_info * usage but Pedro has shown in PR 13866 it is
|
|
possible to fix the cases one by one so I have fixed also this one.
|
|
|
|
It follows the path of valgrind backtrace showing where the memory is being
|
|
freed:
|
|
http://sourceware.org/bugzilla/show_bug.cgi?id=11914#c5
|
|
|
|
This message has been already present in GDB so I used it in more cases:
|
|
+ warning (_("Unable to restore previously selected frame."));
|
|
|
|
No regressions on {x86_64,x86_64-m32,i686}-fedorarawhide-linux-gnu.
|
|
|
|
I will check it in soon for 7.5.
|
|
|
|
I find it a bit difficult to reliably reproduce, this testcases mostly always
|
|
crashes for me (at least with -lmcheck).
|
|
|
|
|
|
Thanks,
|
|
Jan
|
|
|
|
|
|
gdb/
|
|
2012-07-14 Jan Kratochvil <jan.kratochvil@redhat.com>
|
|
|
|
PR 11914
|
|
* f-valprint.c (info_common_command): New variable frame_id.
|
|
Reinitialize FI form FRAME_ID after each print_variable_and_value.
|
|
* printcmd.c (print_variable_and_value): Extend function comment.
|
|
Add comment for invalidated FRAME.
|
|
* stack.c (backtrace_command_1): New variable frame_id. Reinitialize
|
|
FI form FRAME_ID after each print_frame_local_vars.
|
|
(struct print_variable_and_value_data): Change frame to frame_id.
|
|
(do_print_variable_and_value): New variable frame, initialize it from
|
|
p->frame_id. Add comment for invalidated FRAME.
|
|
(print_frame_local_vars, print_frame_arg_vars): New function comment.
|
|
Update CB_DATA.FRAME to CB_DATA.FRAME_ID initialization. Add comment
|
|
for invalidated FRAME.
|
|
|
|
gdb/testsuite/
|
|
2012-07-14 Jan Kratochvil <jan.kratochvil@redhat.com>
|
|
|
|
PR 11914
|
|
* gdb.python/py-prettyprint.c (eval_func, eval_sub): New.
|
|
(main): Call eval_sub.
|
|
* gdb.python/py-prettyprint.exp:
|
|
(python execfile ('py-prettyprint.py')): Move it earlier.
|
|
New breakpoint for eval-break.
|
|
(continue to breakpoint: eval-break, info locals): New test.
|
|
(python execfile ('py-prettyprint.py')): Move it from here.
|
|
* gdb.python/py-prettyprint.py (class pp_eval_type): New.
|
|
(register_pretty_printers): Register pp_eval_type.
|
|
|
|
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
|
|
index 2a0a886..d5b5b63 100644
|
|
--- a/gdb/printcmd.c
|
|
+++ b/gdb/printcmd.c
|
|
@@ -1961,7 +1961,9 @@ clear_dangling_display_expressions (struct so_list *solib)
|
|
struct symbol. NAME is the name to print; if NULL then VAR's print
|
|
name will be used. STREAM is the ui_file on which to print the
|
|
value. INDENT specifies the number of indent levels to print
|
|
- before printing the variable name. */
|
|
+ before printing the variable name.
|
|
+
|
|
+ This function invalidates FRAME. */
|
|
|
|
void
|
|
print_variable_and_value (const char *name, struct symbol *var,
|
|
@@ -1983,6 +1985,10 @@ print_variable_and_value (const char *name, struct symbol *var,
|
|
get_user_print_options (&opts);
|
|
opts.deref_ref = 1;
|
|
common_val_print (val, stream, indent, &opts, current_language);
|
|
+
|
|
+ /* common_val_print invalidates FRAME when a pretty printer calls inferior
|
|
+ function. */
|
|
+ frame = NULL;
|
|
}
|
|
if (except.reason < 0)
|
|
fprintf_filtered(stream, "<error reading variable %s (%s)>", name,
|
|
diff --git a/gdb/stack.c b/gdb/stack.c
|
|
index 2520e2c..35d379d 100644
|
|
--- a/gdb/stack.c
|
|
+++ b/gdb/stack.c
|
|
@@ -1727,7 +1727,20 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
|
|
the frame->prev field gets set to NULL in that case). */
|
|
print_frame_info (fi, 1, LOCATION, 1);
|
|
if (show_locals)
|
|
- print_frame_local_vars (fi, 1, gdb_stdout);
|
|
+ {
|
|
+ struct frame_id frame_id = get_frame_id (fi);
|
|
+
|
|
+ print_frame_local_vars (fi, 1, gdb_stdout);
|
|
+
|
|
+ /* print_frame_local_vars invalidates FI. */
|
|
+ fi = frame_find_by_id (frame_id);
|
|
+ if (fi == NULL)
|
|
+ {
|
|
+ trailing = NULL;
|
|
+ warning (_("Unable to restore previously selected frame."));
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
|
|
/* Save the last frame to check for error conditions. */
|
|
trailing = fi;
|
|
@@ -1919,7 +1932,7 @@ iterate_over_block_local_vars (struct block *block,
|
|
|
|
struct print_variable_and_value_data
|
|
{
|
|
- struct frame_info *frame;
|
|
+ struct frame_id frame_id;
|
|
int num_tabs;
|
|
struct ui_file *stream;
|
|
int values_printed;
|
|
@@ -1933,12 +1946,28 @@ do_print_variable_and_value (const char *print_name,
|
|
void *cb_data)
|
|
{
|
|
struct print_variable_and_value_data *p = cb_data;
|
|
+ struct frame_info *frame;
|
|
+
|
|
+ frame = frame_find_by_id (p->frame_id);
|
|
+ if (frame == NULL)
|
|
+ {
|
|
+ warning (_("Unable to restore previously selected frame."));
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ print_variable_and_value (print_name, sym, frame, p->stream, p->num_tabs);
|
|
+
|
|
+ /* print_variable_and_value invalidates FRAME. */
|
|
+ frame = NULL;
|
|
|
|
- print_variable_and_value (print_name, sym,
|
|
- p->frame, p->stream, p->num_tabs);
|
|
p->values_printed = 1;
|
|
}
|
|
|
|
+/* Print all variables from the innermost up to the function block of FRAME.
|
|
+ Print them with values to STREAM indented by NUM_TABS.
|
|
+
|
|
+ This function will invalidate FRAME. */
|
|
+
|
|
static void
|
|
print_frame_local_vars (struct frame_info *frame, int num_tabs,
|
|
struct ui_file *stream)
|
|
@@ -1961,7 +1990,7 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs,
|
|
return;
|
|
}
|
|
|
|
- cb_data.frame = frame;
|
|
+ cb_data.frame_id = get_frame_id (frame);
|
|
cb_data.num_tabs = 4 * num_tabs;
|
|
cb_data.stream = stream;
|
|
cb_data.values_printed = 0;
|
|
@@ -1970,6 +1999,9 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs,
|
|
do_print_variable_and_value,
|
|
&cb_data);
|
|
|
|
+ /* do_print_variable_and_value invalidates FRAME. */
|
|
+ frame = NULL;
|
|
+
|
|
if (!cb_data.values_printed)
|
|
fprintf_filtered (stream, _("No locals.\n"));
|
|
}
|
|
@@ -2016,6 +2048,11 @@ iterate_over_block_arg_vars (struct block *b,
|
|
}
|
|
}
|
|
|
|
+/* Print all argument variables of the function of FRAME.
|
|
+ Print them with values to STREAM.
|
|
+
|
|
+ This function will invalidate FRAME. */
|
|
+
|
|
static void
|
|
print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
|
|
{
|
|
@@ -2036,7 +2073,7 @@ print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
|
|
return;
|
|
}
|
|
|
|
- cb_data.frame = frame;
|
|
+ cb_data.frame_id = get_frame_id (frame);
|
|
cb_data.num_tabs = 0;
|
|
cb_data.stream = gdb_stdout;
|
|
cb_data.values_printed = 0;
|
|
@@ -2044,6 +2081,9 @@ print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
|
|
iterate_over_block_arg_vars (SYMBOL_BLOCK_VALUE (func),
|
|
do_print_variable_and_value, &cb_data);
|
|
|
|
+ /* do_print_variable_and_value invalidates FRAME. */
|
|
+ frame = NULL;
|
|
+
|
|
if (!cb_data.values_printed)
|
|
fprintf_filtered (stream, _("No arguments.\n"));
|
|
}
|
|
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.c b/gdb/testsuite/gdb.python/py-prettyprint.c
|
|
index 0ff7b33..1ff9e05 100644
|
|
--- a/gdb/testsuite/gdb.python/py-prettyprint.c
|
|
+++ b/gdb/testsuite/gdb.python/py-prettyprint.c
|
|
@@ -219,6 +219,22 @@ struct nullstr
|
|
struct string_repr string_1 = { { "one" } };
|
|
struct string_repr string_2 = { { "two" } };
|
|
|
|
+static int
|
|
+eval_func (int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8)
|
|
+{
|
|
+ return p1;
|
|
+}
|
|
+
|
|
+static void
|
|
+eval_sub (void)
|
|
+{
|
|
+ struct eval_type_s { int x; } eval1 = { 1 }, eval2 = { 2 }, eval3 = { 3 },
|
|
+ eval4 = { 4 }, eval5 = { 5 }, eval6 = { 6 },
|
|
+ eval7 = { 7 }, eval8 = { 8 }, eval9 = { 9 };
|
|
+
|
|
+ eval1.x++; /* eval-break */
|
|
+}
|
|
+
|
|
int
|
|
main ()
|
|
{
|
|
@@ -309,5 +325,7 @@ main ()
|
|
|
|
nstype2 = nstype;
|
|
|
|
+ eval_sub ();
|
|
+
|
|
return 0; /* break to inspect struct and union */
|
|
}
|
|
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.exp b/gdb/testsuite/gdb.python/py-prettyprint.exp
|
|
index a6c241a..22af83c 100644
|
|
--- a/gdb/testsuite/gdb.python/py-prettyprint.exp
|
|
+++ b/gdb/testsuite/gdb.python/py-prettyprint.exp
|
|
@@ -123,14 +123,19 @@ if ![runto_main ] then {
|
|
return
|
|
}
|
|
|
|
-gdb_test "b [gdb_get_line_number {break to inspect} ${testfile}.c ]" \
|
|
- ".*Breakpoint.*"
|
|
-gdb_test "continue" ".*Breakpoint.*"
|
|
-
|
|
set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py]
|
|
|
|
gdb_test_no_output "python execfile ('${remote_python_file}')"
|
|
|
|
+gdb_breakpoint [gdb_get_line_number "eval-break"]
|
|
+gdb_continue_to_breakpoint "eval-break" ".* eval-break .*"
|
|
+
|
|
+gdb_test "info locals" "eval9 = eval=<123456789>"
|
|
+
|
|
+gdb_test "b [gdb_get_line_number {break to inspect} ${testfile}.c ]" \
|
|
+ ".*Breakpoint.*"
|
|
+gdb_test "continue" ".*Breakpoint.*"
|
|
+
|
|
gdb_test "print ss" " = a=< a=<1> b=<$hex>> b=< a=<2> b=<$hex>>" \
|
|
"print ss enabled #1"
|
|
|
|
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.py b/gdb/testsuite/gdb.python/py-prettyprint.py
|
|
index 52ffd1a..b02b90f 100644
|
|
--- a/gdb/testsuite/gdb.python/py-prettyprint.py
|
|
+++ b/gdb/testsuite/gdb.python/py-prettyprint.py
|
|
@@ -199,6 +199,14 @@ class MemoryErrorString:
|
|
def display_hint (self):
|
|
return 'string'
|
|
|
|
+class pp_eval_type:
|
|
+ def __init__(self, val):
|
|
+ self.val = val
|
|
+
|
|
+ def to_string(self):
|
|
+ gdb.execute("bt", to_string=True)
|
|
+ return "eval=<" + str(gdb.parse_and_eval("eval_func (123456789, 2, 3, 4, 5, 6, 7, 8)")) + ">"
|
|
+
|
|
def lookup_function (val):
|
|
"Look-up and return a pretty-printer that can print val."
|
|
|
|
@@ -276,6 +284,8 @@ def register_pretty_printers ():
|
|
|
|
pretty_printers_dict[re.compile ('^memory_error$')] = MemoryErrorString
|
|
|
|
+ pretty_printers_dict[re.compile ('^eval_type_s$')] = pp_eval_type
|
|
+
|
|
pretty_printers_dict = {}
|
|
|
|
register_pretty_printers ()
|
|
|