aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog13
-rw-r--r--gdb/defs.h3
-rw-r--r--gdb/mi/mi-main.c4
-rw-r--r--gdb/testsuite/ChangeLog5
-rw-r--r--gdb/testsuite/gdb.python/py-function.exp14
-rw-r--r--gdb/top.c15
-rw-r--r--gdb/top.h5
-rw-r--r--gdb/utils.c17
8 files changed, 68 insertions, 8 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ab2ecde..06ff560 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,16 @@
+2011-05-13 Thiago Jung Bauermann <bauerman@br.ibm.com>
+
+ * mi/mi-main.c (mi_cmd_execute): Use cleanup from
+ prepare_execute_command.
+ * top.c (prepare_execute_command): Return cleanup.
+ (execute_command): Use cleanup from prepare_execute_command.
+ * top.h (prepare_execute_command): Change prototype to return
+ cleanup.
+ * defs.h (struct value): Add opaque declaration.
+ (make_cleanup_value_free_to_mark): Add prototype.
+ * utils.c (do_value_free_to_mark): New function.
+ (make_cleanup_value_free_to_mark): Likewise.
+
2011-05-12 Tom Tromey <tromey@redhat.com>
* dwarf2expr.c (execute_stack_op) <DW_OP_shr>: Unconditionally
diff --git a/gdb/defs.h b/gdb/defs.h
index 4df2a3e..771d3ad 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -281,6 +281,7 @@ struct symtab;
struct breakpoint;
struct frame_info;
struct gdbarch;
+struct value;
/* From main.c. */
@@ -360,6 +361,8 @@ extern struct cleanup *make_cleanup_unpush_target (struct target_ops *ops);
extern struct cleanup *
make_cleanup_restore_ui_file (struct ui_file **variable);
+extern struct cleanup *make_cleanup_value_free_to_mark (struct value *);
+
extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *);
extern struct cleanup *make_my_cleanup (struct cleanup **,
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index e37f3b5..5181273 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -2025,9 +2025,7 @@ mi_cmd_execute (struct mi_parse *parse)
{
struct cleanup *cleanup;
- prepare_execute_command ();
-
- cleanup = make_cleanup (null_cleanup, NULL);
+ cleanup = prepare_execute_command ();
if (parse->all && parse->thread_group != -1)
error (_("Cannot specify --thread-group together with --all"));
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 9231ae2..f6ad357 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-05-13 Thiago Jung Bauermann <bauerman@br.ibm.com>
+
+ * gdb.python/py-function.exp: Test setting a value from a function
+ which executes a command.
+
2011-05-12 Tom Tromey <tromey@redhat.com>
* gdb.dwarf2/typeddwarf.S: New file.
diff --git a/gdb/testsuite/gdb.python/py-function.exp b/gdb/testsuite/gdb.python/py-function.exp
index dfccdff..ffadb5b 100644
--- a/gdb/testsuite/gdb.python/py-function.exp
+++ b/gdb/testsuite/gdb.python/py-function.exp
@@ -95,3 +95,17 @@ gdb_py_test_multiple "Test Normal Error" \
gdb_test "print \$normalerror()" "Traceback.*File.*line 5.*in invoke.*RuntimeError.*This is a Normal Error.*" \
"Test a Runtime error. There should be a stack trace."
+
+gdb_py_test_multiple "input command-calling function" \
+ "python" "" \
+ "class CallCommand(gdb.Function):" "" \
+ " def __init__(self):" "" \
+ " gdb.Function.__init__(self, 'call_command')" "" \
+ " def invoke(self):" "" \
+ " return gdb.execute('print 1', to_string=True)" "" \
+ "CallCommand ()" "" \
+ "end" ""
+
+gdb_test_no_output "set var \$foo = \$call_command()" "Setting a value from a function which executes a command."
+# There was a bug where GDB would segfault in the second call, so try calling again.
+gdb_test_no_output "set var \$foo = \$call_command()" "Setting a value from a function which executes a command, again."
diff --git a/gdb/top.c b/gdb/top.c
index 2b14f75..b69f7d6 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -339,10 +339,14 @@ do_chdir_cleanup (void *old_dir)
}
#endif
-void
+struct cleanup *
prepare_execute_command (void)
{
- free_all_values ();
+ struct value *mark;
+ struct cleanup *cleanup;
+
+ mark = value_mark ();
+ cleanup = make_cleanup_value_free_to_mark (mark);
/* With multiple threads running while the one we're examining is
stopped, the dcache can get stale without us being able to detect
@@ -350,6 +354,8 @@ prepare_execute_command (void)
help things like backtrace. */
if (non_stop)
target_dcache_invalidate ();
+
+ return cleanup;
}
/* Execute the line P as a command, in the current user context.
@@ -358,12 +364,13 @@ prepare_execute_command (void)
void
execute_command (char *p, int from_tty)
{
+ struct cleanup *cleanup;
struct cmd_list_element *c;
enum language flang;
static int warned = 0;
char *line;
- prepare_execute_command ();
+ cleanup = prepare_execute_command ();
/* Force cleanup of any alloca areas if using C alloca instead of
a builtin alloca. */
@@ -462,6 +469,8 @@ execute_command (char *p, int from_tty)
warned = 1;
}
}
+
+ do_cleanups (cleanup);
}
/* Run execute_command for P and FROM_TTY. Capture its output into the
diff --git a/gdb/top.h b/gdb/top.h
index ff96b75..ce509b5 100644
--- a/gdb/top.h
+++ b/gdb/top.h
@@ -48,8 +48,9 @@ extern int quit_cover (void *);
extern void execute_command (char *, int);
/* Prepare for execution of a command.
- Call this before every command, CLI or MI. */
-extern void prepare_execute_command (void);
+ Call this before every command, CLI or MI.
+ Returns a cleanup to be run after the command is completed. */
+extern struct cleanup *prepare_execute_command (void);
/* This function returns a pointer to the string that is used
by gdb for its command prompt. */
diff --git a/gdb/utils.c b/gdb/utils.c
index a1dac63..3e4a54d 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -431,6 +431,23 @@ make_cleanup_restore_ui_file (struct ui_file **variable)
return make_cleanup_dtor (do_restore_ui_file, (void *) c, xfree);
}
+/* Helper for make_cleanup_value_free_to_mark. */
+
+static void
+do_value_free_to_mark (void *value)
+{
+ value_free_to_mark ((struct value *) value);
+}
+
+/* Free all values allocated since MARK was obtained by value_mark
+ (except for those released) when the cleanup is run. */
+
+struct cleanup *
+make_cleanup_value_free_to_mark (struct value *mark)
+{
+ return make_my_cleanup (&cleanup_chain, do_value_free_to_mark, mark);
+}
+
struct cleanup *
make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function,
void *arg, void (*free_arg) (void *))