diff options
author | Hui Zhu <teawater@gmail.com> | 2008-07-30 03:43:29 +0000 |
---|---|---|
committer | Hui Zhu <teawater@gmail.com> | 2008-07-30 03:43:29 +0000 |
commit | ea1b2558e69d822ffe78c6e0dffc3814a88cf7b8 (patch) | |
tree | 4084ac9059df801b17f7ee2a0aa3744d4c9ff73d | |
parent | 7134d49c36e1bba9030229a4e641654f1d373b43 (diff) | |
download | gdb-ea1b2558e69d822ffe78c6e0dffc3814a88cf7b8.tar.gz |
Change record.c (record_list_release_next) just release "record_list".
Add record instructions limit.
Add a cleanup for displaced stepping in function "record_message_cleanups".
-rw-r--r-- | gdb/ChangeLog | 55 | ||||
-rw-r--r-- | gdb/infrun.c | 2 | ||||
-rw-r--r-- | gdb/record.c | 151 |
3 files changed, 203 insertions, 5 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8f535a3b5dc..0ae78a37846 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,58 @@ +2008-07-29 Hui Zhu <teawater@gmail.com> + + Change record.c (record_list_release_next) just release "record_list". + + * record.c (record_list_release_next): Change it just release + "record_list". + (record_prepare_to_store): Remove "record_list" from + "record_list_release_next". + (record_xfer_partial): Remove "record_list" from + "record_list_release_next". + (cmd_record_delete): Remove "record_list" from + "record_list_release_next". + + Add record instructions limit. + + * record.c (DEFAULT_RECORD_INSN_MAX_NUM): New macro. The default value + of record instructions max number. + (record_insn_max_mode): New static variable. Point out how to do if + record_insn_num >= record_insn_max_num. If 0, ask user. If not 0, auto + delete the first record_t. It can be "set" and "show" with command + "record-auto-delete". + (record_insn_max_num): New static variable. The record instructions max + number. If "record_insn_max_num" is 0, record target will not limit + record instructions number. It can be "set" and "show" with command + "record-insn-number-max". + (record_insn_num): New static variable. The record instructions number. + It can be "info" with command "record-insn-number". + (displaced_step_fixup): Extern. + (record_list_release_first): New function. Release the first + instruction record in "record_list". + (record_message): If record_insn_num >= record_insn_max_num and + record_insn_max_num is not 0, ask user how to do if + record_insn_max_mode == 0, auto delete the first record_t if + record_insn_max_mode != 0. "record_insn_num" add with 1 if record a new + instruction. + (record_open): Reset record_insn_num to 0. + (set_record_insn_max_num): New function. After set the value of + "record_insn_max_num", record instructions number is bigger than record + instructions max number and record_insn_max_num is not 0. Delete the + first record_t. + (show_record_insn_number): New function. Output the value of + "record_insn_num". + (_initialize_record): Add 3 record instructions number limit commands: + "record-auto-delete" "set" and "show" "record_insn_max_mode". + "record-insn-number-max" "set" and "show" "record_insn_max_num". + "record-insn-number" "info" "record_insn_num". + + Add a cleanup for displaced stepping in function + "record_message_cleanups". + + * infrun.c (displaced_step_fixup): Remove static. record.c + (record_message_cleanups) use it. + * record.c (record_message_cleanups): Call funtion + "displaced_step_fixup" to cleanup for displaced stepping. + 2008-07-27 Hui Zhu <teawater@gmail.com> Add a cleanup in function "record_message". diff --git a/gdb/infrun.c b/gdb/infrun.c index e39026644da..986f3504b7d 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -812,7 +812,7 @@ write_memory_ptid (ptid_t ptid, CORE_ADDR memaddr, const gdb_byte *myaddr, int l do_cleanups (ptid_cleanup); } -static void +void displaced_step_fixup (ptid_t event_ptid, enum target_signal signal) { struct cleanup *old_cleanups; diff --git a/gdb/record.c b/gdb/record.c index 059b35ee90c..452f6c567b7 100644 --- a/gdb/record.c +++ b/gdb/record.c @@ -27,7 +27,10 @@ #include <signal.h> +#define DEFAULT_RECORD_INSN_MAX_NUM 200000 + int record_debug = 0; + record_t record_first; record_t *record_list = &record_first; int record_list_status = 1; /* 0 normal 1 to the begin 2 to the end */ @@ -35,6 +38,14 @@ record_t *record_arch_list_head = NULL; record_t *record_arch_list_tail = NULL; struct regcache *record_regcache = NULL; +extern void displaced_step_fixup (ptid_t event_ptid, + enum target_signal signal); + +/* 0 ask user. 1 auto delete the last record_t. */ +static int record_insn_max_mode = 0; +static int record_insn_max_num = DEFAULT_RECORD_INSN_MAX_NUM; +static int record_insn_num = 0; + struct target_ops record_ops; int record_resume_step = 0; enum exec_direction_kind record_execdir = EXEC_FORWARD; @@ -83,8 +94,9 @@ record_list_release (record_t * rec) } static void -record_list_release_next (record_t * rec) +record_list_release_next (void) { + record_t *rec = record_list; record_t *tmp = rec->next; rec->next = NULL; while (tmp) @@ -92,6 +104,10 @@ record_list_release_next (record_t * rec) rec = tmp->next; if (tmp->type == record_reg) { + record_insn_num--; + } + else if (tmp->type == record_reg) + { xfree (tmp->u.reg.val); } else if (tmp->type == record_mem) @@ -103,6 +119,50 @@ record_list_release_next (record_t * rec) } } +static void +record_list_release_first (void) +{ + record_t *tmp = NULL; + enum record_type type; + + if (!record_first.next) + { + return; + } + + while (1) + { + type = record_first.next->type; + + if (type == record_reg) + { + xfree (record_first.next->u.reg.val); + } + else if (type == record_mem) + { + xfree (record_first.next->u.mem.val); + } + tmp = record_first.next; + record_first.next = tmp->next; + xfree (tmp); + + if (!record_first.next) + { + gdb_assert (record_insn_num == 1); + break; + } + + record_first.next->prev = &record_first; + + if (type == record_end) + { + break; + } + } + + record_insn_num--; +} + /* Add a record_t to "record_arch_list". */ static void record_arch_list_add (record_t * rec) @@ -217,6 +277,11 @@ static void record_message_cleanups (void *ignore) { record_list_release (record_arch_list_tail); + + /* Clean for displaced stepping */ + if (!ptid_equal (displaced_step_ptid, null_ptid)) + displaced_step_fixup (displaced_step_ptid, TARGET_SIGNAL_TRAP); + set_executing (inferior_ptid, 0); normal_stop (); } @@ -236,6 +301,33 @@ record_message (struct gdbarch *gdbarch) record_arch_list_tail = NULL; record_regcache = get_current_regcache (); + /* Check record_insn_num */ + if (record_insn_max_num) + { + gdb_assert (record_insn_num <= record_insn_max_num); + if (record_insn_num == record_insn_max_num) + { + /* Ask user how to do */ + if (!record_insn_max_mode) + { + int q; + target_terminal_ours (); + q = + yquery (_ + ("The record instructions number (record-insn-number) is same with the record instructions max number (record-insn-number-max). Do you want to open auto delete first record_t function (record-auto-delete)?")); + target_terminal_inferior (); + if (q) + { + record_insn_max_mode = 1; + } + else + { + error (_("Record: record pause the program.")); + } + } + } + } + /* Deal with displaced stepping */ if (!ptid_equal (displaced_step_ptid, null_ptid)) { @@ -265,6 +357,15 @@ record_message (struct gdbarch *gdbarch) record_list->next = record_arch_list_head; record_arch_list_head->prev = record_list; record_list = record_arch_list_tail; + + if (record_insn_num == record_insn_max_num && record_insn_max_num) + { + record_list_release_first (); + } + else + { + record_insn_num++; + } } /* Things to clean up if we QUIT out of function that set record_not_record. */ @@ -312,6 +413,7 @@ record_open (char *name, int from_tty) } } + record_insn_num = 0; push_target (&record_ops); } @@ -665,7 +767,7 @@ record_prepare_to_store (struct regcache *regcache) } /* Destory the record in the next */ - record_list_release_next (record_list); + record_list_release_next (); } record_registers_change (regcache, record_regcache_raw_write_regnum); @@ -693,7 +795,7 @@ record_xfer_partial (struct target_ops *ops, enum target_object object, } /* Destory the record in the next */ - record_list_release_next (record_list); + record_list_release_next (); } /* Record registers change to list as an instruction */ @@ -816,7 +918,7 @@ cmd_record_delete (char *args, int from_tty) if (!from_tty || query (_ ("Record: delete the next running messages and begin to record the running message at current address?"))) { - record_list_release_next (record_list); + record_list_release_next (); } } else @@ -849,6 +951,28 @@ cmd_record_stop (char *args, int from_tty) } } +static void +set_record_insn_max_num (char *args, int from_tty, struct cmd_list_element *c) +{ + if (record_insn_num > record_insn_max_num && record_insn_max_num) + { + printf_unfiltered (_ + ("Record: record instructions number is bigger than record instructions max number. Auto delete the first ones.\n")); + + while (record_insn_num > record_insn_max_num) + { + record_list_release_first (); + } + } +} + +static void +show_record_insn_number (char *ignore, int from_tty) +{ + printf_unfiltered (_("Record instructions number is %d.\n"), + record_insn_num); +} + void _initialize_record (void) { @@ -890,4 +1014,23 @@ _initialize_record (void) add_com ("stoprecord", class_obscure, cmd_record_stop, _("Stop the record target.")); add_com_alias ("sr", "stoprecord", class_obscure, 1); + + /* Record instructions number limit command. */ + add_setshow_zinteger_cmd ("record-auto-delete", no_class, + &record_insn_max_mode, + _("Set record auto delete mode."), + _("Show record auto delete mode."), + _ + ("When number of instructions that record target record is same with record-insn-max, if 0 will ask user howto do, if no 0 will auto delete the first record_t."), + NULL, NULL, &setlist, &showlist); + add_setshow_zinteger_cmd ("record-insn-number-max", no_class, + &record_insn_max_num, + _("Set record instructions max number."), + _("Show record instructions max number."), + _ + ("The max instructions number that record target can record. When 0, record target will not limit it."), + set_record_insn_max_num, NULL, &setlist, + &showlist); + add_info ("record-insn-number", show_record_insn_number, + _("Show the record instructions number.")); } |