#include "extension.h"
#include "gdbcmd.h"
#include "observer.h"
+#include "common/gdb_optional.h"
+#include "common/byte-vector.h"
#include <ctype.h>
#include "run-time-clock.h"
#include <chrono>
+#include "progspace-and-thread.h"
enum
{
See comment on infcmd.c:proceed_thread_callback for rationale. */
if (current_context->all || current_context->thread_group != -1)
{
+ scoped_restore_current_thread restore_thread;
int pid = 0;
- struct cleanup *back_to = make_cleanup_restore_current_thread ();
if (!current_context->all)
{
pid = inf->pid;
}
iterate_over_threads (proceed_thread_callback, &pid);
- do_cleanups (back_to);
}
else
{
}
}
-static void
-exec_direction_forward (void *notused)
-{
- execution_direction = EXEC_FORWARD;
-}
-
static void
exec_reverse_continue (char **argv, int argc)
{
enum exec_direction_kind dir = execution_direction;
- struct cleanup *old_chain;
if (dir == EXEC_REVERSE)
error (_("Already in reverse mode."));
if (!target_can_execute_reverse)
error (_("Target %s does not support this command."), target_shortname);
- old_chain = make_cleanup (exec_direction_forward, NULL);
- execution_direction = EXEC_REVERSE;
+ scoped_restore save_exec_dir = make_scoped_restore (&execution_direction,
+ EXEC_REVERSE);
exec_continue (argv, argc);
- do_cleanups (old_chain);
}
void
if (current_context->all)
{
- struct cleanup *back_to = save_current_space_and_thread ();
+ scoped_restore_current_pspace_and_thread restore_pspace_thread;
iterate_over_inferiors (run_one_inferior, &start_p);
- do_cleanups (back_to);
}
else
{
compare_positive_ints))
{
struct collect_cores_data data;
- struct cleanup *back_to
- = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+ ui_out_emit_tuple tuple_emitter (uiout, NULL);
uiout->field_fmt ("id", "i%d", inferior->num);
uiout->field_string ("type", "process");
if (!VEC_empty (int, data.cores))
{
int *b, *e;
- struct cleanup *back_to_2 =
- make_cleanup_ui_out_list_begin_end (uiout, "cores");
+ ui_out_emit_list list_emitter (uiout, "cores");
qsort (VEC_address (int, data.cores),
VEC_length (int, data.cores), sizeof (int),
for (; b != e; ++b)
uiout->field_int (NULL, *b);
-
- do_cleanups (back_to_2);
}
if (top_data->recurse)
print_thread_info (uiout, NULL, inferior->pid);
-
- do_cleanups (back_to);
}
return 0;
ix_items, item);
ix_items++)
{
- struct cleanup *back_to;
-
const char *pid = get_osdata_column (item, "pid");
const char *cmd = get_osdata_column (item, "command");
const char *user = get_osdata_column (item, "user");
continue;
- back_to = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+ ui_out_emit_tuple tuple_emitter (uiout, NULL);
uiout->field_fmt ("id", "%s", pid);
uiout->field_string ("type", "process");
VEC_iterate (osdata_item_s, children, ix_child, child);
++ix_child)
{
- struct cleanup *back_to_2 =
- make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+ ui_out_emit_tuple tuple_emitter (uiout, NULL);
const char *tid = get_osdata_column (child, "tid");
const char *tcore = get_osdata_column (child, "core");
uiout->field_string ("id", tid);
if (tcore)
uiout->field_string ("core", tcore);
-
- do_cleanups (back_to_2);
}
}
}
-
- do_cleanups (back_to);
}
do_cleanups (cleanup);
struct ui_out *uiout = current_uiout;
int regnum, numregs;
int i;
- struct cleanup *cleanup;
/* Note that the test for a valid register must include checking the
gdbarch_register_name because gdbarch_num_regs may be allocated
gdbarch = get_current_arch ();
numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
- cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-names");
+ ui_out_emit_list list_emitter (uiout, "register-names");
if (argc == 0) /* No args, just do all the regs. */
{
else
uiout->field_string (NULL, gdbarch_register_name (gdbarch, regnum));
}
- do_cleanups (cleanup);
}
void
struct regcache *this_regs)
{
struct gdbarch *gdbarch = get_regcache_arch (this_regs);
- gdb_byte prev_buffer[MAX_REGISTER_SIZE];
- gdb_byte this_buffer[MAX_REGISTER_SIZE];
- enum register_status prev_status;
- enum register_status this_status;
+ struct value *prev_value, *this_value;
+ int ret;
/* First time through or after gdbarch change consider all registers
as changed. */
return 1;
/* Get register contents and compare. */
- prev_status = regcache_cooked_read (prev_regs, regnum, prev_buffer);
- this_status = regcache_cooked_read (this_regs, regnum, this_buffer);
+ prev_value = prev_regs->cooked_read_value (regnum);
+ this_value = this_regs->cooked_read_value (regnum);
+ gdb_assert (prev_value != NULL);
+ gdb_assert (this_value != NULL);
- if (this_status != prev_status)
- return 1;
- else if (this_status == REG_VALID)
- return memcmp (prev_buffer, this_buffer,
- register_size (gdbarch, regnum)) != 0;
- else
- return 0;
+ ret = value_contents_eq (prev_value, 0, this_value, 0,
+ register_size (gdbarch, regnum)) == 0;
+
+ release_value (prev_value);
+ release_value (this_value);
+ value_free (prev_value);
+ value_free (this_value);
+ return ret;
}
/* Return a list of register number and value pairs. The valid
struct gdbarch *gdbarch;
int regnum, numregs, format;
int i;
- struct cleanup *list_cleanup;
int skip_unavailable = 0;
int oind = 0;
enum opt
gdbarch = get_frame_arch (frame);
numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
- list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-values");
+ ui_out_emit_list list_emitter (uiout, "register-values");
if (argc - oind == 1)
{
else
error (_("bad register number"));
}
- do_cleanups (list_cleanup);
}
/* Output one register REGNUM's contents in the desired FORMAT. If
{
struct ui_out *uiout = current_uiout;
struct value *val = value_of_register (regnum, frame);
- struct cleanup *tuple_cleanup;
struct value_print_options opts;
if (skip_unavailable && !value_entirely_available (val))
return;
- tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+ ui_out_emit_tuple tuple_emitter (uiout, NULL);
uiout->field_int ("number", regnum);
if (format == 'N')
value_embedded_offset (val), 0,
&stb, 0, val, &opts, current_language);
uiout->field_stream ("value", stb);
-
- do_cleanups (tuple_cleanup);
}
/* Write given values into registers. The registers and values are
/* Create a buffer and read it in. */
total_bytes = word_size * nr_rows * nr_cols;
- std::unique_ptr<gdb_byte[]> mbuf (new gdb_byte[total_bytes]);
+ gdb::byte_vector mbuf (total_bytes);
/* Dispatch memory reads to the topmost target, not the flattened
current_target. */
nr_bytes = target_read (current_target.beneath,
- TARGET_OBJECT_MEMORY, NULL, mbuf.get (),
+ TARGET_OBJECT_MEMORY, NULL, mbuf.data (),
addr, total_bytes);
if (nr_bytes <= 0)
error (_("Unable to read memory."));
{
int col;
int col_byte;
- struct cleanup *cleanup_tuple;
struct cleanup *cleanup_list_data;
struct value_print_options opts;
- cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+ ui_out_emit_tuple tuple_emitter (uiout, NULL);
uiout->field_core_addr ("addr", gdbarch, addr + row_byte);
/* ui_out_field_core_addr_symbolic (uiout, "saddr", addr +
row_byte); */
}
uiout->field_stream ("ascii", stream);
}
- do_cleanups (cleanup_tuple);
}
do_cleanups (cleanup_list);
}
VEC_iterate (memory_read_result_s, result, ix, read_result);
++ix)
{
- struct cleanup *t = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+ ui_out_emit_tuple tuple_emitter (uiout, NULL);
char *data, *p;
int i;
int alloc_len;
}
uiout->field_string ("contents", data);
xfree (data);
- do_cleanups (t);
}
do_cleanups (cleanups);
}
{
if (argc == 0)
{
- struct cleanup *cleanup = NULL;
struct ui_out *uiout = current_uiout;
- cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
+ ui_out_emit_list list_emitter (uiout, "features");
uiout->field_string (NULL, "frozen-varobjs");
uiout->field_string (NULL, "pending-breakpoints");
uiout->field_string (NULL, "thread-info");
if (ext_lang_initialized_p (get_ext_lang_defn (EXT_LANG_PYTHON)))
uiout->field_string (NULL, "python");
- do_cleanups (cleanup);
return;
}
{
if (argc == 0)
{
- struct cleanup *cleanup = NULL;
struct ui_out *uiout = current_uiout;
- cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
+ ui_out_emit_list list_emitter (uiout, "features");
if (mi_async_p ())
uiout->field_string (NULL, "async");
if (target_can_execute_reverse)
uiout->field_string (NULL, "reverse");
- do_cleanups (cleanup);
return;
}
mi_execute_command (const char *cmd, int from_tty)
{
char *token;
- struct mi_parse *command = NULL;
+ std::unique_ptr<struct mi_parse> command;
/* This is to handle EOF (^D). We just quit gdb. */
/* FIXME: we should call some API function here. */
if (command != NULL)
{
ptid_t previous_ptid = inferior_ptid;
- struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
- command->token = token;
+ gdb::optional<scoped_restore_tmpl<int>> restore_suppress;
if (command->cmd != NULL && command->cmd->suppress_notification != NULL)
- {
- make_cleanup_restore_integer (command->cmd->suppress_notification);
- *command->cmd->suppress_notification = 1;
- }
+ restore_suppress.emplace (command->cmd->suppress_notification, 1);
+
+ command->token = token;
if (do_timings)
{
TRY
{
- captured_mi_execute_command (current_uiout, command);
+ captured_mi_execute_command (current_uiout, command.get ());
}
CATCH (result, RETURN_MASK_ALL)
{
&& thread_count () != 0
/* If the command already reports the thread change, no need to do it
again. */
- && !command_notifies_uscc_observer (command))
+ && !command_notifies_uscc_observer (command.get ()))
{
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter ();
int report_change = 0;
(USER_SELECTED_THREAD | USER_SELECTED_FRAME);
}
}
-
- mi_parse_free (command);
-
- do_cleanups (cleanup);
}
}
strcmp (previous_sect_name, section_name) : 1);
if (new_section)
{
- struct cleanup *cleanup_tuple;
-
xfree (previous_sect_name);
previous_sect_name = xstrdup (section_name);
if (current_token)
fputs_unfiltered (current_token, mi->raw_stdout);
fputs_unfiltered ("+download", mi->raw_stdout);
- cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
- uiout->field_string ("section", section_name);
- uiout->field_int ("section-size", total_section);
- uiout->field_int ("total-size", grand_total);
- do_cleanups (cleanup_tuple);
+ {
+ ui_out_emit_tuple tuple_emitter (uiout, NULL);
+ uiout->field_string ("section", section_name);
+ uiout->field_int ("section-size", total_section);
+ uiout->field_int ("total-size", grand_total);
+ }
mi_out_put (uiout, mi->raw_stdout);
fputs_unfiltered ("\n", mi->raw_stdout);
gdb_flush (mi->raw_stdout);
steady_clock::time_point time_now = steady_clock::now ();
if (time_now - last_update > milliseconds (500))
{
- struct cleanup *cleanup_tuple;
-
last_update = time_now;
if (current_token)
fputs_unfiltered (current_token, mi->raw_stdout);
fputs_unfiltered ("+download", mi->raw_stdout);
- cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
- uiout->field_string ("section", section_name);
- uiout->field_int ("section-sent", sent_so_far);
- uiout->field_int ("section-size", total_section);
- uiout->field_int ("total-sent", total_sent);
- uiout->field_int ("total-size", grand_total);
- do_cleanups (cleanup_tuple);
+ {
+ ui_out_emit_tuple tuple_emitter (uiout, NULL);
+ uiout->field_string ("section", section_name);
+ uiout->field_int ("section-sent", sent_so_far);
+ uiout->field_int ("section-size", total_section);
+ uiout->field_int ("total-sent", total_sent);
+ uiout->field_int ("total-size", grand_total);
+ }
mi_out_put (uiout, mi->raw_stdout);
fputs_unfiltered ("\n", mi->raw_stdout);
gdb_flush (mi->raw_stdout);
static void
print_variable_or_computed (const char *expression, enum print_values values)
{
- struct cleanup *old_chain;
struct value *val;
struct type *type;
struct ui_out *uiout = current_uiout;
else
val = evaluate_expression (expr.get ());
- old_chain = make_cleanup (null_cleanup, NULL);
+ gdb::optional<ui_out_emit_tuple> tuple_emitter;
if (values != PRINT_NO_VALUES)
- make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+ tuple_emitter.emplace (uiout, nullptr);
uiout->field_string ("name", expression);
switch (values)
}
break;
}
-
- do_cleanups (old_chain);
}
/* Implement the "-trace-frame-collected" command. */
void
mi_cmd_trace_frame_collected (const char *command, char **argv, int argc)
{
- struct cleanup *old_chain;
struct bp_location *tloc;
int stepping_frame;
struct collection_list *clist;
/* This command only makes sense for the current frame, not the
selected frame. */
- old_chain = make_cleanup_restore_current_thread ();
+ scoped_restore_current_thread restore_thread;
select_frame (get_current_frame ());
encode_actions (tloc, &tracepoint_list, &stepping_list);
/* Explicitly wholly collected variables. */
{
- struct cleanup *list_cleanup;
int i;
- list_cleanup = make_cleanup_ui_out_list_begin_end (uiout,
- "explicit-variables");
-
+ ui_out_emit_list list_emitter (uiout, "explicit-variables");
const std::vector<std::string> &wholly_collected
= clist->wholly_collected ();
for (size_t i = 0; i < wholly_collected.size (); i++)
const std::string &str = wholly_collected[i];
print_variable_or_computed (str.c_str (), var_print_values);
}
-
- do_cleanups (list_cleanup);
}
/* Computed expressions. */
{
- struct cleanup *list_cleanup;
char *p;
int i;
- list_cleanup
- = make_cleanup_ui_out_list_begin_end (uiout,
- "computed-expressions");
+ ui_out_emit_list list_emitter (uiout, "computed-expressions");
const std::vector<std::string> &computed = clist->computed ();
for (size_t i = 0; i < computed.size (); i++)
const std::string &str = computed[i];
print_variable_or_computed (str.c_str (), comp_print_values);
}
-
- do_cleanups (list_cleanup);
}
/* Registers. Given pseudo-registers, and that some architectures
the trace frame info, but instead consult the register cache for
register availability. */
{
- struct cleanup *list_cleanup;
struct frame_info *frame;
struct gdbarch *gdbarch;
int regnum;
int numregs;
- list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "registers");
+ ui_out_emit_list list_emitter (uiout, "registers");
frame = get_selected_frame (NULL);
gdbarch = get_frame_arch (frame);
output_register (frame, regnum, registers_format, 1);
}
-
- do_cleanups (list_cleanup);
}
/* Trace state variables. */
for (i = 0; VEC_iterate (int, tinfo->tvars, i, tvar); i++)
{
- struct cleanup *cleanup_child;
struct trace_state_variable *tsv;
tsv = find_trace_state_variable_by_number (tvar);
- cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+ ui_out_emit_tuple tuple_emitter (uiout, NULL);
if (tsv != NULL)
{
uiout->field_skip ("name");
uiout->field_skip ("current");
}
-
- do_cleanups (cleanup_child);
}
do_cleanups (list_cleanup);
do_cleanups (list_cleanup);
}
-
- do_cleanups (old_chain);
}
void