1 /* Process record and replay target for GDB, the GNU debugger.
3 Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 #include "gdbthread.h"
24 #include "event-top.h"
25 #include "exceptions.h"
26 #include "completer.h"
27 #include "arch-utils.h"
36 /* This module implements "target record", also known as "process
37 record and replay". This target sits on top of a "normal" target
38 (a target that "has execution"), and provides a record and replay
39 functionality, including reverse debugging.
41 Target record has two modes: recording, and replaying.
43 In record mode, we intercept the to_resume and to_wait methods.
44 Whenever gdb resumes the target, we run the target in single step
45 mode, and we build up an execution log in which, for each executed
46 instruction, we record all changes in memory and register state.
47 This is invisible to the user, to whom it just looks like an
48 ordinary debugging session (except for performance degredation).
50 In replay mode, instead of actually letting the inferior run as a
51 process, we simulate its execution by playing back the recorded
52 execution log. For each instruction in the log, we simulate the
53 instruction's side effects by duplicating the changes that it would
54 have made on memory and registers. */
56 #define DEFAULT_RECORD_INSN_MAX_NUM 200000
58 #define RECORD_IS_REPLAY \
59 (record_list->next || execution_direction == EXEC_REVERSE)
61 #define RECORD_FILE_MAGIC netorder32(0x20091016)
63 /* These are the core structs of the process record functionality.
65 A record_entry is a record of the value change of a register
66 ("record_reg") or a part of memory ("record_mem"). And each
67 instruction must have a struct record_entry ("record_end") that
68 indicates that this is the last struct record_entry of this
71 Each struct record_entry is linked to "record_list" by "prev" and
74 struct record_mem_entry
78 /* Set this flag if target memory for this entry
79 can no longer be accessed. */
80 int mem_entry_not_accessible
;
84 gdb_byte buf
[sizeof (gdb_byte
*)];
88 struct record_reg_entry
95 gdb_byte buf
[2 * sizeof (gdb_byte
*)];
99 struct record_end_entry
101 enum target_signal sigval
;
112 /* This is the data structure that makes up the execution log.
114 The execution log consists of a single linked list of entries
115 of type "struct record_entry". It is doubly linked so that it
116 can be traversed in either direction.
118 The start of the list is anchored by a struct called
119 "record_first". The pointer "record_list" either points to the
120 last entry that was added to the list (in record mode), or to the
121 next entry in the list that will be executed (in replay mode).
123 Each list element (struct record_entry), in addition to next and
124 prev pointers, consists of a union of three entry types: mem, reg,
125 and end. A field called "type" determines which entry type is
126 represented by a given list element.
128 Each instruction that is added to the execution log is represented
129 by a variable number of list elements ('entries'). The instruction
130 will have one "reg" entry for each register that is changed by
131 executing the instruction (including the PC in every case). It
132 will also have one "mem" entry for each memory change. Finally,
133 each instruction will have an "end" entry that separates it from
134 the changes associated with the next instruction. */
138 struct record_entry
*prev
;
139 struct record_entry
*next
;
140 enum record_type type
;
144 struct record_reg_entry reg
;
146 struct record_mem_entry mem
;
148 struct record_end_entry end
;
152 /* This is the debug switch for process record. */
153 int record_debug
= 0;
155 /* If true, query if PREC cannot record memory
156 change of next instruction. */
157 int record_memory_query
= 0;
159 struct record_core_buf_entry
161 struct record_core_buf_entry
*prev
;
162 struct target_section
*p
;
166 /* Record buf with core target. */
167 static gdb_byte
*record_core_regbuf
= NULL
;
168 static struct target_section
*record_core_start
;
169 static struct target_section
*record_core_end
;
170 static struct record_core_buf_entry
*record_core_buf_list
= NULL
;
172 /* The following variables are used for managing the linked list that
173 represents the execution log.
175 record_first is the anchor that holds down the beginning of the list.
177 record_list serves two functions:
178 1) In record mode, it anchors the end of the list.
179 2) In replay mode, it traverses the list and points to
180 the next instruction that must be emulated.
182 record_arch_list_head and record_arch_list_tail are used to manage
183 a separate list, which is used to build up the change elements of
184 the currently executing instruction during record mode. When this
185 instruction has been completely annotated in the "arch list", it
186 will be appended to the main execution log. */
188 static struct record_entry record_first
;
189 static struct record_entry
*record_list
= &record_first
;
190 static struct record_entry
*record_arch_list_head
= NULL
;
191 static struct record_entry
*record_arch_list_tail
= NULL
;
193 /* 1 ask user. 0 auto delete the last struct record_entry. */
194 static int record_stop_at_limit
= 1;
195 /* Maximum allowed number of insns in execution log. */
196 static unsigned int record_insn_max_num
= DEFAULT_RECORD_INSN_MAX_NUM
;
197 /* Actual count of insns presently in execution log. */
198 static int record_insn_num
= 0;
199 /* Count of insns logged so far (may be larger
200 than count of insns presently in execution log). */
201 static ULONGEST record_insn_count
;
203 /* The target_ops of process record. */
204 static struct target_ops record_ops
;
205 static struct target_ops record_core_ops
;
207 /* The beneath function pointers. */
208 static struct target_ops
*record_beneath_to_resume_ops
;
209 static void (*record_beneath_to_resume
) (struct target_ops
*, ptid_t
, int,
211 static struct target_ops
*record_beneath_to_wait_ops
;
212 static ptid_t (*record_beneath_to_wait
) (struct target_ops
*, ptid_t
,
213 struct target_waitstatus
*,
215 static struct target_ops
*record_beneath_to_store_registers_ops
;
216 static void (*record_beneath_to_store_registers
) (struct target_ops
*,
219 static struct target_ops
*record_beneath_to_xfer_partial_ops
;
220 static LONGEST (*record_beneath_to_xfer_partial
) (struct target_ops
*ops
,
221 enum target_object object
,
224 const gdb_byte
*writebuf
,
227 static int (*record_beneath_to_insert_breakpoint
) (struct gdbarch
*,
228 struct bp_target_info
*);
229 static int (*record_beneath_to_remove_breakpoint
) (struct gdbarch
*,
230 struct bp_target_info
*);
231 static int (*record_beneath_to_stopped_by_watchpoint
) (void);
232 static int (*record_beneath_to_stopped_data_address
) (struct target_ops
*,
235 /* Alloc and free functions for record_reg, record_mem, and record_end
238 /* Alloc a record_reg record entry. */
240 static inline struct record_entry
*
241 record_reg_alloc (struct regcache
*regcache
, int regnum
)
243 struct record_entry
*rec
;
244 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
246 rec
= (struct record_entry
*) xcalloc (1, sizeof (struct record_entry
));
247 rec
->type
= record_reg
;
248 rec
->u
.reg
.num
= regnum
;
249 rec
->u
.reg
.len
= register_size (gdbarch
, regnum
);
250 if (rec
->u
.reg
.len
> sizeof (rec
->u
.reg
.u
.buf
))
251 rec
->u
.reg
.u
.ptr
= (gdb_byte
*) xmalloc (rec
->u
.reg
.len
);
256 /* Free a record_reg record entry. */
259 record_reg_release (struct record_entry
*rec
)
261 gdb_assert (rec
->type
== record_reg
);
262 if (rec
->u
.reg
.len
> sizeof (rec
->u
.reg
.u
.buf
))
263 xfree (rec
->u
.reg
.u
.ptr
);
267 /* Alloc a record_mem record entry. */
269 static inline struct record_entry
*
270 record_mem_alloc (CORE_ADDR addr
, int len
)
272 struct record_entry
*rec
;
274 rec
= (struct record_entry
*) xcalloc (1, sizeof (struct record_entry
));
275 rec
->type
= record_mem
;
276 rec
->u
.mem
.addr
= addr
;
277 rec
->u
.mem
.len
= len
;
278 if (rec
->u
.mem
.len
> sizeof (rec
->u
.mem
.u
.buf
))
279 rec
->u
.mem
.u
.ptr
= (gdb_byte
*) xmalloc (len
);
284 /* Free a record_mem record entry. */
287 record_mem_release (struct record_entry
*rec
)
289 gdb_assert (rec
->type
== record_mem
);
290 if (rec
->u
.mem
.len
> sizeof (rec
->u
.mem
.u
.buf
))
291 xfree (rec
->u
.mem
.u
.ptr
);
295 /* Alloc a record_end record entry. */
297 static inline struct record_entry
*
298 record_end_alloc (void)
300 struct record_entry
*rec
;
302 rec
= (struct record_entry
*) xcalloc (1, sizeof (struct record_entry
));
303 rec
->type
= record_end
;
308 /* Free a record_end record entry. */
311 record_end_release (struct record_entry
*rec
)
316 /* Free one record entry, any type.
317 Return entry->type, in case caller wants to know. */
319 static inline enum record_type
320 record_entry_release (struct record_entry
*rec
)
322 enum record_type type
= rec
->type
;
326 record_reg_release (rec
);
329 record_mem_release (rec
);
332 record_end_release (rec
);
338 /* Free all record entries in list pointed to by REC. */
341 record_list_release (struct record_entry
*rec
)
352 record_entry_release (rec
->next
);
355 if (rec
== &record_first
)
358 record_first
.next
= NULL
;
361 record_entry_release (rec
);
364 /* Free all record entries forward of the given list position. */
367 record_list_release_following (struct record_entry
*rec
)
369 struct record_entry
*tmp
= rec
->next
;
375 if (record_entry_release (tmp
) == record_end
)
384 /* Delete the first instruction from the beginning of the log, to make
385 room for adding a new instruction at the end of the log.
387 Note -- this function does not modify record_insn_num. */
390 record_list_release_first (void)
392 struct record_entry
*tmp
;
394 if (!record_first
.next
)
397 /* Loop until a record_end. */
400 /* Cut record_first.next out of the linked list. */
401 tmp
= record_first
.next
;
402 record_first
.next
= tmp
->next
;
403 tmp
->next
->prev
= &record_first
;
405 /* tmp is now isolated, and can be deleted. */
406 if (record_entry_release (tmp
) == record_end
)
407 break; /* End loop at first record_end. */
409 if (!record_first
.next
)
411 gdb_assert (record_insn_num
== 1);
412 break; /* End loop when list is empty. */
417 /* Add a struct record_entry to record_arch_list. */
420 record_arch_list_add (struct record_entry
*rec
)
422 if (record_debug
> 1)
423 fprintf_unfiltered (gdb_stdlog
,
424 "Process record: record_arch_list_add %s.\n",
425 host_address_to_string (rec
));
427 if (record_arch_list_tail
)
429 record_arch_list_tail
->next
= rec
;
430 rec
->prev
= record_arch_list_tail
;
431 record_arch_list_tail
= rec
;
435 record_arch_list_head
= rec
;
436 record_arch_list_tail
= rec
;
440 /* Return the value storage location of a record entry. */
441 static inline gdb_byte
*
442 record_get_loc (struct record_entry
*rec
)
446 if (rec
->u
.mem
.len
> sizeof (rec
->u
.mem
.u
.buf
))
447 return rec
->u
.mem
.u
.ptr
;
449 return rec
->u
.mem
.u
.buf
;
451 if (rec
->u
.reg
.len
> sizeof (rec
->u
.reg
.u
.buf
))
452 return rec
->u
.reg
.u
.ptr
;
454 return rec
->u
.reg
.u
.buf
;
462 /* Record the value of a register NUM to record_arch_list. */
465 record_arch_list_add_reg (struct regcache
*regcache
, int regnum
)
467 struct record_entry
*rec
;
469 if (record_debug
> 1)
470 fprintf_unfiltered (gdb_stdlog
,
471 "Process record: add register num = %d to "
475 rec
= record_reg_alloc (regcache
, regnum
);
477 regcache_raw_read (regcache
, regnum
, record_get_loc (rec
));
479 record_arch_list_add (rec
);
484 /* Record the value of a region of memory whose address is ADDR and
485 length is LEN to record_arch_list. */
488 record_arch_list_add_mem (CORE_ADDR addr
, int len
)
490 struct record_entry
*rec
;
492 if (record_debug
> 1)
493 fprintf_unfiltered (gdb_stdlog
,
494 "Process record: add mem addr = %s len = %d to "
496 paddress (target_gdbarch
, addr
), len
);
498 if (!addr
) /* FIXME: Why? Some arch must permit it... */
501 rec
= record_mem_alloc (addr
, len
);
503 if (target_read_memory (addr
, record_get_loc (rec
), len
))
506 fprintf_unfiltered (gdb_stdlog
,
507 "Process record: error reading memory at "
508 "addr = %s len = %d.\n",
509 paddress (target_gdbarch
, addr
), len
);
510 record_mem_release (rec
);
514 record_arch_list_add (rec
);
519 /* Add a record_end type struct record_entry to record_arch_list. */
522 record_arch_list_add_end (void)
524 struct record_entry
*rec
;
526 if (record_debug
> 1)
527 fprintf_unfiltered (gdb_stdlog
,
528 "Process record: add end to arch list.\n");
530 rec
= record_end_alloc ();
531 rec
->u
.end
.sigval
= TARGET_SIGNAL_0
;
532 rec
->u
.end
.insn_num
= ++record_insn_count
;
534 record_arch_list_add (rec
);
540 record_check_insn_num (int set_terminal
)
542 if (record_insn_max_num
)
544 gdb_assert (record_insn_num
<= record_insn_max_num
);
545 if (record_insn_num
== record_insn_max_num
)
547 /* Ask user what to do. */
548 if (record_stop_at_limit
)
553 target_terminal_ours ();
554 q
= yquery (_("Do you want to auto delete previous execution "
555 "log entries when record/replay buffer becomes "
556 "full (record stop-at-limit)?"));
558 target_terminal_inferior ();
560 record_stop_at_limit
= 0;
562 error (_("Process record: stopped by user."));
569 record_arch_list_cleanups (void *ignore
)
571 record_list_release (record_arch_list_tail
);
574 /* Before inferior step (when GDB record the running message, inferior
575 only can step), GDB will call this function to record the values to
576 record_list. This function will call gdbarch_process_record to
577 record the running message of inferior and set them to
578 record_arch_list, and add it to record_list. */
581 record_message (struct regcache
*regcache
, enum target_signal signal
)
584 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
585 struct cleanup
*old_cleanups
= make_cleanup (record_arch_list_cleanups
, 0);
587 record_arch_list_head
= NULL
;
588 record_arch_list_tail
= NULL
;
590 /* Check record_insn_num. */
591 record_check_insn_num (1);
593 /* If gdb sends a signal value to target_resume,
594 save it in the 'end' field of the previous instruction.
596 Maybe process record should record what really happened,
597 rather than what gdb pretends has happened.
599 So if Linux delivered the signal to the child process during
600 the record mode, we will record it and deliver it again in
603 If user says "ignore this signal" during the record mode, then
604 it will be ignored again during the replay mode (no matter if
605 the user says something different, like "deliver this signal"
606 during the replay mode).
608 User should understand that nothing he does during the replay
609 mode will change the behavior of the child. If he tries,
610 then that is a user error.
612 But we should still deliver the signal to gdb during the replay,
613 if we delivered it during the recording. Therefore we should
614 record the signal during record_wait, not record_resume. */
615 if (record_list
!= &record_first
) /* FIXME better way to check */
617 gdb_assert (record_list
->type
== record_end
);
618 record_list
->u
.end
.sigval
= signal
;
621 if (signal
== TARGET_SIGNAL_0
622 || !gdbarch_process_record_signal_p (gdbarch
))
623 ret
= gdbarch_process_record (gdbarch
,
625 regcache_read_pc (regcache
));
627 ret
= gdbarch_process_record_signal (gdbarch
,
632 error (_("Process record: inferior program stopped."));
634 error (_("Process record: failed to record execution log."));
636 discard_cleanups (old_cleanups
);
638 record_list
->next
= record_arch_list_head
;
639 record_arch_list_head
->prev
= record_list
;
640 record_list
= record_arch_list_tail
;
642 if (record_insn_num
== record_insn_max_num
&& record_insn_max_num
)
643 record_list_release_first ();
650 struct record_message_args
{
651 struct regcache
*regcache
;
652 enum target_signal signal
;
656 record_message_wrapper (void *args
)
658 struct record_message_args
*record_args
= args
;
660 return record_message (record_args
->regcache
, record_args
->signal
);
664 record_message_wrapper_safe (struct regcache
*regcache
,
665 enum target_signal signal
)
667 struct record_message_args args
;
669 args
.regcache
= regcache
;
670 args
.signal
= signal
;
672 return catch_errors (record_message_wrapper
, &args
, NULL
, RETURN_MASK_ALL
);
675 /* Set to 1 if record_store_registers and record_xfer_partial
676 doesn't need record. */
678 static int record_gdb_operation_disable
= 0;
681 record_gdb_operation_disable_set (void)
683 struct cleanup
*old_cleanups
= NULL
;
686 make_cleanup_restore_integer (&record_gdb_operation_disable
);
687 record_gdb_operation_disable
= 1;
692 /* Flag set to TRUE for target_stopped_by_watchpoint. */
693 static int record_hw_watchpoint
= 0;
695 /* Execute one instruction from the record log. Each instruction in
696 the log will be represented by an arbitrary sequence of register
697 entries and memory entries, followed by an 'end' entry. */
700 record_exec_insn (struct regcache
*regcache
, struct gdbarch
*gdbarch
,
701 struct record_entry
*entry
)
705 case record_reg
: /* reg */
707 gdb_byte reg
[MAX_REGISTER_SIZE
];
709 if (record_debug
> 1)
710 fprintf_unfiltered (gdb_stdlog
,
711 "Process record: record_reg %s to "
712 "inferior num = %d.\n",
713 host_address_to_string (entry
),
716 regcache_cooked_read (regcache
, entry
->u
.reg
.num
, reg
);
717 regcache_cooked_write (regcache
, entry
->u
.reg
.num
,
718 record_get_loc (entry
));
719 memcpy (record_get_loc (entry
), reg
, entry
->u
.reg
.len
);
723 case record_mem
: /* mem */
725 /* Nothing to do if the entry is flagged not_accessible. */
726 if (!entry
->u
.mem
.mem_entry_not_accessible
)
728 gdb_byte
*mem
= alloca (entry
->u
.mem
.len
);
730 if (record_debug
> 1)
731 fprintf_unfiltered (gdb_stdlog
,
732 "Process record: record_mem %s to "
733 "inferior addr = %s len = %d.\n",
734 host_address_to_string (entry
),
735 paddress (gdbarch
, entry
->u
.mem
.addr
),
738 if (target_read_memory (entry
->u
.mem
.addr
, mem
, entry
->u
.mem
.len
))
740 entry
->u
.mem
.mem_entry_not_accessible
= 1;
742 warning ("Process record: error reading memory at "
743 "addr = %s len = %d.",
744 paddress (gdbarch
, entry
->u
.mem
.addr
),
749 if (target_write_memory (entry
->u
.mem
.addr
,
750 record_get_loc (entry
),
753 entry
->u
.mem
.mem_entry_not_accessible
= 1;
755 warning ("Process record: error writing memory at "
756 "addr = %s len = %d.",
757 paddress (gdbarch
, entry
->u
.mem
.addr
),
762 memcpy (record_get_loc (entry
), mem
, entry
->u
.mem
.len
);
764 /* We've changed memory --- check if a hardware
765 watchpoint should trap. Note that this
766 presently assumes the target beneath supports
767 continuable watchpoints. On non-continuable
768 watchpoints target, we'll want to check this
769 _before_ actually doing the memory change, and
770 not doing the change at all if the watchpoint
772 if (hardware_watchpoint_inserted_in_range
773 (get_regcache_aspace (regcache
),
774 entry
->u
.mem
.addr
, entry
->u
.mem
.len
))
775 record_hw_watchpoint
= 1;
784 static struct target_ops
*tmp_to_resume_ops
;
785 static void (*tmp_to_resume
) (struct target_ops
*, ptid_t
, int,
787 static struct target_ops
*tmp_to_wait_ops
;
788 static ptid_t (*tmp_to_wait
) (struct target_ops
*, ptid_t
,
789 struct target_waitstatus
*,
791 static struct target_ops
*tmp_to_store_registers_ops
;
792 static void (*tmp_to_store_registers
) (struct target_ops
*,
795 static struct target_ops
*tmp_to_xfer_partial_ops
;
796 static LONGEST (*tmp_to_xfer_partial
) (struct target_ops
*ops
,
797 enum target_object object
,
800 const gdb_byte
*writebuf
,
803 static int (*tmp_to_insert_breakpoint
) (struct gdbarch
*,
804 struct bp_target_info
*);
805 static int (*tmp_to_remove_breakpoint
) (struct gdbarch
*,
806 struct bp_target_info
*);
807 static int (*tmp_to_stopped_by_watchpoint
) (void);
808 static int (*tmp_to_stopped_data_address
) (struct target_ops
*, CORE_ADDR
*);
810 static void record_restore (void);
812 /* Open the process record target. */
815 record_core_open_1 (char *name
, int from_tty
)
817 struct regcache
*regcache
= get_current_regcache ();
818 int regnum
= gdbarch_num_regs (get_regcache_arch (regcache
));
821 /* Get record_core_regbuf. */
822 target_fetch_registers (regcache
, -1);
823 record_core_regbuf
= xmalloc (MAX_REGISTER_SIZE
* regnum
);
824 for (i
= 0; i
< regnum
; i
++)
825 regcache_raw_collect (regcache
, i
,
826 record_core_regbuf
+ MAX_REGISTER_SIZE
* i
);
828 /* Get record_core_start and record_core_end. */
829 if (build_section_table (core_bfd
, &record_core_start
, &record_core_end
))
831 xfree (record_core_regbuf
);
832 record_core_regbuf
= NULL
;
833 error (_("\"%s\": Can't find sections: %s"),
834 bfd_get_filename (core_bfd
), bfd_errmsg (bfd_get_error ()));
837 push_target (&record_core_ops
);
841 /* "to_open" target method for 'live' processes. */
844 record_open_1 (char *name
, int from_tty
)
847 fprintf_unfiltered (gdb_stdlog
, "Process record: record_open\n");
850 if (!target_has_execution
)
851 error (_("Process record: the program is not being run."));
853 error (_("Process record target can't debug inferior in non-stop mode "
855 if (target_async_permitted
)
856 error (_("Process record target can't debug inferior in asynchronous "
857 "mode (target-async)."));
859 if (!gdbarch_process_record_p (target_gdbarch
))
860 error (_("Process record: the current architecture doesn't support "
861 "record function."));
864 error (_("Could not find 'to_resume' method on the target stack."));
866 error (_("Could not find 'to_wait' method on the target stack."));
867 if (!tmp_to_store_registers
)
868 error (_("Could not find 'to_store_registers' method on the target stack."));
869 if (!tmp_to_insert_breakpoint
)
870 error (_("Could not find 'to_insert_breakpoint' method on the target stack."));
871 if (!tmp_to_remove_breakpoint
)
872 error (_("Could not find 'to_remove_breakpoint' method on the target stack."));
873 if (!tmp_to_stopped_by_watchpoint
)
874 error (_("Could not find 'to_stopped_by_watchpoint' method on the target stack."));
875 if (!tmp_to_stopped_data_address
)
876 error (_("Could not find 'to_stopped_data_address' method on the target stack."));
878 push_target (&record_ops
);
881 /* "to_open" target method. Open the process record target. */
884 record_open (char *name
, int from_tty
)
886 struct target_ops
*t
;
889 fprintf_unfiltered (gdb_stdlog
, "Process record: record_open\n");
891 /* Check if record target is already running. */
892 if (current_target
.to_stratum
== record_stratum
)
893 error (_("Process record target already running. Use \"record stop\" to "
894 "stop record target first."));
896 /* Reset the tmp beneath pointers. */
897 tmp_to_resume_ops
= NULL
;
898 tmp_to_resume
= NULL
;
899 tmp_to_wait_ops
= NULL
;
901 tmp_to_store_registers_ops
= NULL
;
902 tmp_to_store_registers
= NULL
;
903 tmp_to_xfer_partial_ops
= NULL
;
904 tmp_to_xfer_partial
= NULL
;
905 tmp_to_insert_breakpoint
= NULL
;
906 tmp_to_remove_breakpoint
= NULL
;
907 tmp_to_stopped_by_watchpoint
= NULL
;
908 tmp_to_stopped_data_address
= NULL
;
910 /* Set the beneath function pointers. */
911 for (t
= current_target
.beneath
; t
!= NULL
; t
= t
->beneath
)
915 tmp_to_resume
= t
->to_resume
;
916 tmp_to_resume_ops
= t
;
920 tmp_to_wait
= t
->to_wait
;
923 if (!tmp_to_store_registers
)
925 tmp_to_store_registers
= t
->to_store_registers
;
926 tmp_to_store_registers_ops
= t
;
928 if (!tmp_to_xfer_partial
)
930 tmp_to_xfer_partial
= t
->to_xfer_partial
;
931 tmp_to_xfer_partial_ops
= t
;
933 if (!tmp_to_insert_breakpoint
)
934 tmp_to_insert_breakpoint
= t
->to_insert_breakpoint
;
935 if (!tmp_to_remove_breakpoint
)
936 tmp_to_remove_breakpoint
= t
->to_remove_breakpoint
;
937 if (!tmp_to_stopped_by_watchpoint
)
938 tmp_to_stopped_by_watchpoint
= t
->to_stopped_by_watchpoint
;
939 if (!tmp_to_stopped_data_address
)
940 tmp_to_stopped_data_address
= t
->to_stopped_data_address
;
942 if (!tmp_to_xfer_partial
)
943 error (_("Could not find 'to_xfer_partial' method on the target stack."));
947 record_insn_count
= 0;
948 record_list
= &record_first
;
949 record_list
->next
= NULL
;
951 /* Set the tmp beneath pointers to beneath pointers. */
952 record_beneath_to_resume_ops
= tmp_to_resume_ops
;
953 record_beneath_to_resume
= tmp_to_resume
;
954 record_beneath_to_wait_ops
= tmp_to_wait_ops
;
955 record_beneath_to_wait
= tmp_to_wait
;
956 record_beneath_to_store_registers_ops
= tmp_to_store_registers_ops
;
957 record_beneath_to_store_registers
= tmp_to_store_registers
;
958 record_beneath_to_xfer_partial_ops
= tmp_to_xfer_partial_ops
;
959 record_beneath_to_xfer_partial
= tmp_to_xfer_partial
;
960 record_beneath_to_insert_breakpoint
= tmp_to_insert_breakpoint
;
961 record_beneath_to_remove_breakpoint
= tmp_to_remove_breakpoint
;
962 record_beneath_to_stopped_by_watchpoint
= tmp_to_stopped_by_watchpoint
;
963 record_beneath_to_stopped_data_address
= tmp_to_stopped_data_address
;
965 if (current_target
.to_stratum
== core_stratum
)
966 record_core_open_1 (name
, from_tty
);
968 record_open_1 (name
, from_tty
);
971 /* "to_close" target method. Close the process record target. */
974 record_close (int quitting
)
976 struct record_core_buf_entry
*entry
;
979 fprintf_unfiltered (gdb_stdlog
, "Process record: record_close\n");
981 record_list_release (record_list
);
983 /* Release record_core_regbuf. */
984 if (record_core_regbuf
)
986 xfree (record_core_regbuf
);
987 record_core_regbuf
= NULL
;
990 /* Release record_core_buf_list. */
991 if (record_core_buf_list
)
993 for (entry
= record_core_buf_list
->prev
; entry
; entry
= entry
->prev
)
995 xfree (record_core_buf_list
);
996 record_core_buf_list
= entry
;
998 record_core_buf_list
= NULL
;
1002 static int record_resume_step
= 0;
1004 /* "to_resume" target method. Resume the process record target. */
1007 record_resume (struct target_ops
*ops
, ptid_t ptid
, int step
,
1008 enum target_signal signal
)
1010 record_resume_step
= step
;
1012 if (!RECORD_IS_REPLAY
)
1014 record_message (get_current_regcache (), signal
);
1015 record_beneath_to_resume (record_beneath_to_resume_ops
, ptid
, 1,
1020 static int record_get_sig
= 0;
1022 /* SIGINT signal handler, registered by "to_wait" method. */
1025 record_sig_handler (int signo
)
1028 fprintf_unfiltered (gdb_stdlog
, "Process record: get a signal\n");
1030 /* It will break the running inferior in replay mode. */
1031 record_resume_step
= 1;
1033 /* It will let record_wait set inferior status to get the signal
1039 record_wait_cleanups (void *ignore
)
1041 if (execution_direction
== EXEC_REVERSE
)
1043 if (record_list
->next
)
1044 record_list
= record_list
->next
;
1047 record_list
= record_list
->prev
;
1050 /* "to_wait" target method for process record target.
1052 In record mode, the target is always run in singlestep mode
1053 (even when gdb says to continue). The to_wait method intercepts
1054 the stop events and determines which ones are to be passed on to
1055 gdb. Most stop events are just singlestep events that gdb is not
1056 to know about, so the to_wait method just records them and keeps
1059 In replay mode, this function emulates the recorded execution log,
1060 one instruction at a time (forward or backward), and determines
1064 record_wait (struct target_ops
*ops
,
1065 ptid_t ptid
, struct target_waitstatus
*status
,
1068 struct cleanup
*set_cleanups
= record_gdb_operation_disable_set ();
1071 fprintf_unfiltered (gdb_stdlog
,
1072 "Process record: record_wait "
1073 "record_resume_step = %d\n",
1074 record_resume_step
);
1077 signal (SIGINT
, record_sig_handler
);
1079 if (!RECORD_IS_REPLAY
&& ops
!= &record_core_ops
)
1081 if (record_resume_step
)
1083 /* This is a single step. */
1084 return record_beneath_to_wait (record_beneath_to_wait_ops
,
1085 ptid
, status
, options
);
1089 /* This is not a single step. */
1095 ret
= record_beneath_to_wait (record_beneath_to_wait_ops
,
1096 ptid
, status
, options
);
1098 if (record_resume_step
)
1101 /* Is this a SIGTRAP? */
1102 if (status
->kind
== TARGET_WAITKIND_STOPPED
1103 && status
->value
.sig
== TARGET_SIGNAL_TRAP
)
1105 struct regcache
*regcache
;
1106 struct address_space
*aspace
;
1108 /* Yes -- this is likely our single-step finishing,
1109 but check if there's any reason the core would be
1110 interested in the event. */
1112 registers_changed ();
1113 regcache
= get_current_regcache ();
1114 tmp_pc
= regcache_read_pc (regcache
);
1115 aspace
= get_regcache_aspace (regcache
);
1117 if (target_stopped_by_watchpoint ())
1119 /* Always interested in watchpoints. */
1121 else if (breakpoint_inserted_here_p (aspace
, tmp_pc
))
1123 /* There is a breakpoint here. Let the core
1125 if (software_breakpoint_inserted_here_p (aspace
, tmp_pc
))
1127 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
1128 CORE_ADDR decr_pc_after_break
1129 = gdbarch_decr_pc_after_break (gdbarch
);
1130 if (decr_pc_after_break
)
1131 regcache_write_pc (regcache
,
1132 tmp_pc
+ decr_pc_after_break
);
1137 /* This must be a single-step trap. Record the
1138 insn and issue another step. */
1139 if (!record_message_wrapper_safe (regcache
,
1142 status
->kind
= TARGET_WAITKIND_STOPPED
;
1143 status
->value
.sig
= TARGET_SIGNAL_0
;
1147 record_beneath_to_resume (record_beneath_to_resume_ops
,
1154 /* The inferior is broken by a breakpoint or a signal. */
1163 struct regcache
*regcache
= get_current_regcache ();
1164 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
1165 struct address_space
*aspace
= get_regcache_aspace (regcache
);
1166 int continue_flag
= 1;
1167 int first_record_end
= 1;
1168 struct cleanup
*old_cleanups
= make_cleanup (record_wait_cleanups
, 0);
1171 record_hw_watchpoint
= 0;
1172 status
->kind
= TARGET_WAITKIND_STOPPED
;
1174 /* Check breakpoint when forward execute. */
1175 if (execution_direction
== EXEC_FORWARD
)
1177 tmp_pc
= regcache_read_pc (regcache
);
1178 if (breakpoint_inserted_here_p (aspace
, tmp_pc
))
1180 int decr_pc_after_break
= gdbarch_decr_pc_after_break (gdbarch
);
1183 fprintf_unfiltered (gdb_stdlog
,
1184 "Process record: break at %s.\n",
1185 paddress (gdbarch
, tmp_pc
));
1187 if (decr_pc_after_break
1188 && !record_resume_step
1189 && software_breakpoint_inserted_here_p (aspace
, tmp_pc
))
1190 regcache_write_pc (regcache
,
1191 tmp_pc
+ decr_pc_after_break
);
1196 /* If GDB is in terminal_inferior mode, it will not get the signal.
1197 And in GDB replay mode, GDB doesn't need to be in terminal_inferior
1198 mode, because inferior will not executed.
1199 Then set it to terminal_ours to make GDB get the signal. */
1200 target_terminal_ours ();
1202 /* In EXEC_FORWARD mode, record_list points to the tail of prev
1204 if (execution_direction
== EXEC_FORWARD
&& record_list
->next
)
1205 record_list
= record_list
->next
;
1207 /* Loop over the record_list, looking for the next place to
1211 /* Check for beginning and end of log. */
1212 if (execution_direction
== EXEC_REVERSE
1213 && record_list
== &record_first
)
1215 /* Hit beginning of record log in reverse. */
1216 status
->kind
= TARGET_WAITKIND_NO_HISTORY
;
1219 if (execution_direction
!= EXEC_REVERSE
&& !record_list
->next
)
1221 /* Hit end of record log going forward. */
1222 status
->kind
= TARGET_WAITKIND_NO_HISTORY
;
1226 record_exec_insn (regcache
, gdbarch
, record_list
);
1228 if (record_list
->type
== record_end
)
1230 if (record_debug
> 1)
1231 fprintf_unfiltered (gdb_stdlog
,
1232 "Process record: record_end %s to "
1234 host_address_to_string (record_list
));
1236 if (first_record_end
&& execution_direction
== EXEC_REVERSE
)
1238 /* When reverse excute, the first record_end is the part of
1239 current instruction. */
1240 first_record_end
= 0;
1244 /* In EXEC_REVERSE mode, this is the record_end of prev
1246 In EXEC_FORWARD mode, this is the record_end of current
1249 if (record_resume_step
)
1251 if (record_debug
> 1)
1252 fprintf_unfiltered (gdb_stdlog
,
1253 "Process record: step.\n");
1257 /* check breakpoint */
1258 tmp_pc
= regcache_read_pc (regcache
);
1259 if (breakpoint_inserted_here_p (aspace
, tmp_pc
))
1261 int decr_pc_after_break
1262 = gdbarch_decr_pc_after_break (gdbarch
);
1265 fprintf_unfiltered (gdb_stdlog
,
1266 "Process record: break "
1268 paddress (gdbarch
, tmp_pc
));
1269 if (decr_pc_after_break
1270 && execution_direction
== EXEC_FORWARD
1271 && !record_resume_step
1272 && software_breakpoint_inserted_here_p (aspace
,
1274 regcache_write_pc (regcache
,
1275 tmp_pc
+ decr_pc_after_break
);
1279 if (record_hw_watchpoint
)
1282 fprintf_unfiltered (gdb_stdlog
, "\
1283 Process record: hit hw watchpoint.\n");
1286 /* Check target signal */
1287 if (record_list
->u
.end
.sigval
!= TARGET_SIGNAL_0
)
1288 /* FIXME: better way to check */
1295 if (execution_direction
== EXEC_REVERSE
)
1297 if (record_list
->prev
)
1298 record_list
= record_list
->prev
;
1302 if (record_list
->next
)
1303 record_list
= record_list
->next
;
1307 while (continue_flag
);
1311 status
->value
.sig
= TARGET_SIGNAL_INT
;
1312 else if (record_list
->u
.end
.sigval
!= TARGET_SIGNAL_0
)
1313 /* FIXME: better way to check */
1314 status
->value
.sig
= record_list
->u
.end
.sigval
;
1316 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
1318 discard_cleanups (old_cleanups
);
1321 signal (SIGINT
, handle_sigint
);
1323 do_cleanups (set_cleanups
);
1324 return inferior_ptid
;
1328 record_stopped_by_watchpoint (void)
1330 if (RECORD_IS_REPLAY
)
1331 return record_hw_watchpoint
;
1333 return record_beneath_to_stopped_by_watchpoint ();
1337 record_stopped_data_address (struct target_ops
*ops
, CORE_ADDR
*addr_p
)
1339 if (RECORD_IS_REPLAY
)
1342 return record_beneath_to_stopped_data_address (ops
, addr_p
);
1345 /* "to_disconnect" method for process record target. */
1348 record_disconnect (struct target_ops
*target
, char *args
, int from_tty
)
1351 fprintf_unfiltered (gdb_stdlog
, "Process record: record_disconnect\n");
1353 unpush_target (&record_ops
);
1354 target_disconnect (args
, from_tty
);
1357 /* "to_detach" method for process record target. */
1360 record_detach (struct target_ops
*ops
, char *args
, int from_tty
)
1363 fprintf_unfiltered (gdb_stdlog
, "Process record: record_detach\n");
1365 unpush_target (&record_ops
);
1366 target_detach (args
, from_tty
);
1369 /* "to_mourn_inferior" method for process record target. */
1372 record_mourn_inferior (struct target_ops
*ops
)
1375 fprintf_unfiltered (gdb_stdlog
, "Process record: "
1376 "record_mourn_inferior\n");
1378 unpush_target (&record_ops
);
1379 target_mourn_inferior ();
1382 /* Close process record target before killing the inferior process. */
1385 record_kill (struct target_ops
*ops
)
1388 fprintf_unfiltered (gdb_stdlog
, "Process record: record_kill\n");
1390 unpush_target (&record_ops
);
1394 /* Record registers change (by user or by GDB) to list as an instruction. */
1397 record_registers_change (struct regcache
*regcache
, int regnum
)
1399 /* Check record_insn_num. */
1400 record_check_insn_num (0);
1402 record_arch_list_head
= NULL
;
1403 record_arch_list_tail
= NULL
;
1409 for (i
= 0; i
< gdbarch_num_regs (get_regcache_arch (regcache
)); i
++)
1411 if (record_arch_list_add_reg (regcache
, i
))
1413 record_list_release (record_arch_list_tail
);
1414 error (_("Process record: failed to record execution log."));
1420 if (record_arch_list_add_reg (regcache
, regnum
))
1422 record_list_release (record_arch_list_tail
);
1423 error (_("Process record: failed to record execution log."));
1426 if (record_arch_list_add_end ())
1428 record_list_release (record_arch_list_tail
);
1429 error (_("Process record: failed to record execution log."));
1431 record_list
->next
= record_arch_list_head
;
1432 record_arch_list_head
->prev
= record_list
;
1433 record_list
= record_arch_list_tail
;
1435 if (record_insn_num
== record_insn_max_num
&& record_insn_max_num
)
1436 record_list_release_first ();
1441 /* "to_store_registers" method for process record target. */
1444 record_store_registers (struct target_ops
*ops
, struct regcache
*regcache
,
1447 if (!record_gdb_operation_disable
)
1449 if (RECORD_IS_REPLAY
)
1453 /* Let user choose if he wants to write register or not. */
1456 query (_("Because GDB is in replay mode, changing the "
1457 "value of a register will make the execution "
1458 "log unusable from this point onward. "
1459 "Change all registers?"));
1462 query (_("Because GDB is in replay mode, changing the value "
1463 "of a register will make the execution log unusable "
1464 "from this point onward. Change register %s?"),
1465 gdbarch_register_name (get_regcache_arch (regcache
),
1470 /* Invalidate the value of regcache that was set in function
1471 "regcache_raw_write". */
1477 i
< gdbarch_num_regs (get_regcache_arch (regcache
));
1479 regcache_invalidate (regcache
, i
);
1482 regcache_invalidate (regcache
, regno
);
1484 error (_("Process record canceled the operation."));
1487 /* Destroy the record from here forward. */
1488 record_list_release_following (record_list
);
1491 record_registers_change (regcache
, regno
);
1493 record_beneath_to_store_registers (record_beneath_to_store_registers_ops
,
1497 /* "to_xfer_partial" method. Behavior is conditional on RECORD_IS_REPLAY.
1498 In replay mode, we cannot write memory unles we are willing to
1499 invalidate the record/replay log from this point forward. */
1502 record_xfer_partial (struct target_ops
*ops
, enum target_object object
,
1503 const char *annex
, gdb_byte
*readbuf
,
1504 const gdb_byte
*writebuf
, ULONGEST offset
, LONGEST len
)
1506 if (!record_gdb_operation_disable
1507 && (object
== TARGET_OBJECT_MEMORY
1508 || object
== TARGET_OBJECT_RAW_MEMORY
) && writebuf
)
1510 if (RECORD_IS_REPLAY
)
1512 /* Let user choose if he wants to write memory or not. */
1513 if (!query (_("Because GDB is in replay mode, writing to memory "
1514 "will make the execution log unusable from this "
1515 "point onward. Write memory at address %s?"),
1516 paddress (target_gdbarch
, offset
)))
1517 error (_("Process record canceled the operation."));
1519 /* Destroy the record from here forward. */
1520 record_list_release_following (record_list
);
1523 /* Check record_insn_num */
1524 record_check_insn_num (0);
1526 /* Record registers change to list as an instruction. */
1527 record_arch_list_head
= NULL
;
1528 record_arch_list_tail
= NULL
;
1529 if (record_arch_list_add_mem (offset
, len
))
1531 record_list_release (record_arch_list_tail
);
1533 fprintf_unfiltered (gdb_stdlog
,
1534 "Process record: failed to record "
1538 if (record_arch_list_add_end ())
1540 record_list_release (record_arch_list_tail
);
1542 fprintf_unfiltered (gdb_stdlog
,
1543 "Process record: failed to record "
1547 record_list
->next
= record_arch_list_head
;
1548 record_arch_list_head
->prev
= record_list
;
1549 record_list
= record_arch_list_tail
;
1551 if (record_insn_num
== record_insn_max_num
&& record_insn_max_num
)
1552 record_list_release_first ();
1557 return record_beneath_to_xfer_partial (record_beneath_to_xfer_partial_ops
,
1558 object
, annex
, readbuf
, writebuf
,
1562 /* Behavior is conditional on RECORD_IS_REPLAY.
1563 We will not actually insert or remove breakpoints when replaying,
1564 nor when recording. */
1567 record_insert_breakpoint (struct gdbarch
*gdbarch
,
1568 struct bp_target_info
*bp_tgt
)
1570 if (!RECORD_IS_REPLAY
)
1572 struct cleanup
*old_cleanups
= record_gdb_operation_disable_set ();
1573 int ret
= record_beneath_to_insert_breakpoint (gdbarch
, bp_tgt
);
1575 do_cleanups (old_cleanups
);
1583 /* "to_remove_breakpoint" method for process record target. */
1586 record_remove_breakpoint (struct gdbarch
*gdbarch
,
1587 struct bp_target_info
*bp_tgt
)
1589 if (!RECORD_IS_REPLAY
)
1591 struct cleanup
*old_cleanups
= record_gdb_operation_disable_set ();
1592 int ret
= record_beneath_to_remove_breakpoint (gdbarch
, bp_tgt
);
1594 do_cleanups (old_cleanups
);
1602 /* "to_can_execute_reverse" method for process record target. */
1605 record_can_execute_reverse (void)
1610 /* "to_get_bookmark" method for process record and prec over core. */
1613 record_get_bookmark (char *args
, int from_tty
)
1615 gdb_byte
*ret
= NULL
;
1617 /* Return stringified form of instruction count. */
1618 if (record_list
&& record_list
->type
== record_end
)
1619 ret
= xstrdup (pulongest (record_list
->u
.end
.insn_num
));
1624 fprintf_unfiltered (gdb_stdlog
,
1625 "record_get_bookmark returns %s\n", ret
);
1627 fprintf_unfiltered (gdb_stdlog
,
1628 "record_get_bookmark returns NULL\n");
1633 /* The implementation of the command "record goto". */
1634 static void cmd_record_goto (char *, int);
1636 /* "to_goto_bookmark" method for process record and prec over core. */
1639 record_goto_bookmark (gdb_byte
*bookmark
, int from_tty
)
1642 fprintf_unfiltered (gdb_stdlog
,
1643 "record_goto_bookmark receives %s\n", bookmark
);
1645 if (bookmark
[0] == '\'' || bookmark
[0] == '\"')
1647 if (bookmark
[strlen (bookmark
) - 1] != bookmark
[0])
1648 error (_("Unbalanced quotes: %s"), bookmark
);
1650 /* Strip trailing quote. */
1651 bookmark
[strlen (bookmark
) - 1] = '\0';
1652 /* Strip leading quote. */
1654 /* Pass along to cmd_record_goto. */
1657 cmd_record_goto ((char *) bookmark
, from_tty
);
1662 init_record_ops (void)
1664 record_ops
.to_shortname
= "record";
1665 record_ops
.to_longname
= "Process record and replay target";
1667 "Log program while executing and replay execution from log.";
1668 record_ops
.to_open
= record_open
;
1669 record_ops
.to_close
= record_close
;
1670 record_ops
.to_resume
= record_resume
;
1671 record_ops
.to_wait
= record_wait
;
1672 record_ops
.to_disconnect
= record_disconnect
;
1673 record_ops
.to_detach
= record_detach
;
1674 record_ops
.to_mourn_inferior
= record_mourn_inferior
;
1675 record_ops
.to_kill
= record_kill
;
1676 record_ops
.to_create_inferior
= find_default_create_inferior
;
1677 record_ops
.to_store_registers
= record_store_registers
;
1678 record_ops
.to_xfer_partial
= record_xfer_partial
;
1679 record_ops
.to_insert_breakpoint
= record_insert_breakpoint
;
1680 record_ops
.to_remove_breakpoint
= record_remove_breakpoint
;
1681 record_ops
.to_stopped_by_watchpoint
= record_stopped_by_watchpoint
;
1682 record_ops
.to_stopped_data_address
= record_stopped_data_address
;
1683 record_ops
.to_can_execute_reverse
= record_can_execute_reverse
;
1684 record_ops
.to_stratum
= record_stratum
;
1685 /* Add bookmark target methods. */
1686 record_ops
.to_get_bookmark
= record_get_bookmark
;
1687 record_ops
.to_goto_bookmark
= record_goto_bookmark
;
1688 record_ops
.to_magic
= OPS_MAGIC
;
1691 /* "to_resume" method for prec over corefile. */
1694 record_core_resume (struct target_ops
*ops
, ptid_t ptid
, int step
,
1695 enum target_signal signal
)
1697 record_resume_step
= step
;
1700 /* "to_kill" method for prec over corefile. */
1703 record_core_kill (struct target_ops
*ops
)
1706 fprintf_unfiltered (gdb_stdlog
, "Process record: record_core_kill\n");
1708 unpush_target (&record_core_ops
);
1711 /* "to_fetch_registers" method for prec over corefile. */
1714 record_core_fetch_registers (struct target_ops
*ops
,
1715 struct regcache
*regcache
,
1720 int num
= gdbarch_num_regs (get_regcache_arch (regcache
));
1723 for (i
= 0; i
< num
; i
++)
1724 regcache_raw_supply (regcache
, i
,
1725 record_core_regbuf
+ MAX_REGISTER_SIZE
* i
);
1728 regcache_raw_supply (regcache
, regno
,
1729 record_core_regbuf
+ MAX_REGISTER_SIZE
* regno
);
1732 /* "to_prepare_to_store" method for prec over corefile. */
1735 record_core_prepare_to_store (struct regcache
*regcache
)
1739 /* "to_store_registers" method for prec over corefile. */
1742 record_core_store_registers (struct target_ops
*ops
,
1743 struct regcache
*regcache
,
1746 if (record_gdb_operation_disable
)
1747 regcache_raw_collect (regcache
, regno
,
1748 record_core_regbuf
+ MAX_REGISTER_SIZE
* regno
);
1750 error (_("You can't do that without a process to debug."));
1753 /* "to_xfer_partial" method for prec over corefile. */
1756 record_core_xfer_partial (struct target_ops
*ops
, enum target_object object
,
1757 const char *annex
, gdb_byte
*readbuf
,
1758 const gdb_byte
*writebuf
, ULONGEST offset
,
1761 if (object
== TARGET_OBJECT_MEMORY
)
1763 if (record_gdb_operation_disable
|| !writebuf
)
1765 struct target_section
*p
;
1767 for (p
= record_core_start
; p
< record_core_end
; p
++)
1769 if (offset
>= p
->addr
)
1771 struct record_core_buf_entry
*entry
;
1772 ULONGEST sec_offset
;
1774 if (offset
>= p
->endaddr
)
1777 if (offset
+ len
> p
->endaddr
)
1778 len
= p
->endaddr
- offset
;
1780 sec_offset
= offset
- p
->addr
;
1782 /* Read readbuf or write writebuf p, offset, len. */
1784 if (p
->the_bfd_section
->flags
& SEC_CONSTRUCTOR
1785 || (p
->the_bfd_section
->flags
& SEC_HAS_CONTENTS
) == 0)
1788 memset (readbuf
, 0, len
);
1791 /* Get record_core_buf_entry. */
1792 for (entry
= record_core_buf_list
; entry
;
1793 entry
= entry
->prev
)
1800 /* Add a new entry. */
1801 entry
= (struct record_core_buf_entry
*)
1802 xmalloc (sizeof (struct record_core_buf_entry
));
1804 if (!bfd_malloc_and_get_section (p
->bfd
,
1811 entry
->prev
= record_core_buf_list
;
1812 record_core_buf_list
= entry
;
1815 memcpy (entry
->buf
+ sec_offset
, writebuf
,
1821 return record_beneath_to_xfer_partial
1822 (record_beneath_to_xfer_partial_ops
,
1823 object
, annex
, readbuf
, writebuf
,
1826 memcpy (readbuf
, entry
->buf
+ sec_offset
,
1837 error (_("You can't do that without a process to debug."));
1840 return record_beneath_to_xfer_partial (record_beneath_to_xfer_partial_ops
,
1841 object
, annex
, readbuf
, writebuf
,
1845 /* "to_insert_breakpoint" method for prec over corefile. */
1848 record_core_insert_breakpoint (struct gdbarch
*gdbarch
,
1849 struct bp_target_info
*bp_tgt
)
1854 /* "to_remove_breakpoint" method for prec over corefile. */
1857 record_core_remove_breakpoint (struct gdbarch
*gdbarch
,
1858 struct bp_target_info
*bp_tgt
)
1863 /* "to_has_execution" method for prec over corefile. */
1866 record_core_has_execution (struct target_ops
*ops
)
1872 init_record_core_ops (void)
1874 record_core_ops
.to_shortname
= "record-core";
1875 record_core_ops
.to_longname
= "Process record and replay target";
1876 record_core_ops
.to_doc
=
1877 "Log program while executing and replay execution from log.";
1878 record_core_ops
.to_open
= record_open
;
1879 record_core_ops
.to_close
= record_close
;
1880 record_core_ops
.to_resume
= record_core_resume
;
1881 record_core_ops
.to_wait
= record_wait
;
1882 record_core_ops
.to_kill
= record_core_kill
;
1883 record_core_ops
.to_fetch_registers
= record_core_fetch_registers
;
1884 record_core_ops
.to_prepare_to_store
= record_core_prepare_to_store
;
1885 record_core_ops
.to_store_registers
= record_core_store_registers
;
1886 record_core_ops
.to_xfer_partial
= record_core_xfer_partial
;
1887 record_core_ops
.to_insert_breakpoint
= record_core_insert_breakpoint
;
1888 record_core_ops
.to_remove_breakpoint
= record_core_remove_breakpoint
;
1889 record_core_ops
.to_stopped_by_watchpoint
= record_stopped_by_watchpoint
;
1890 record_core_ops
.to_stopped_data_address
= record_stopped_data_address
;
1891 record_core_ops
.to_can_execute_reverse
= record_can_execute_reverse
;
1892 record_core_ops
.to_has_execution
= record_core_has_execution
;
1893 record_core_ops
.to_stratum
= record_stratum
;
1894 /* Add bookmark target methods. */
1895 record_core_ops
.to_get_bookmark
= record_get_bookmark
;
1896 record_core_ops
.to_goto_bookmark
= record_goto_bookmark
;
1897 record_core_ops
.to_magic
= OPS_MAGIC
;
1900 /* Implement "show record debug" command. */
1903 show_record_debug (struct ui_file
*file
, int from_tty
,
1904 struct cmd_list_element
*c
, const char *value
)
1906 fprintf_filtered (file
, _("Debugging of process record target is %s.\n"),
1910 /* Alias for "target record". */
1913 cmd_record_start (char *args
, int from_tty
)
1915 execute_command ("target record", from_tty
);
1918 /* Truncate the record log from the present point
1919 of replay until the end. */
1922 cmd_record_delete (char *args
, int from_tty
)
1924 if (current_target
.to_stratum
== record_stratum
)
1926 if (RECORD_IS_REPLAY
)
1928 if (!from_tty
|| query (_("Delete the log from this point forward "
1929 "and begin to record the running message "
1931 record_list_release_following (record_list
);
1934 printf_unfiltered (_("Already at end of record list.\n"));
1938 printf_unfiltered (_("Process record is not started.\n"));
1941 /* Implement the "stoprecord" or "record stop" command. */
1944 cmd_record_stop (char *args
, int from_tty
)
1946 if (current_target
.to_stratum
== record_stratum
)
1948 unpush_target (&record_ops
);
1949 printf_unfiltered (_("Process record is stopped and all execution "
1950 "logs are deleted.\n"));
1953 printf_unfiltered (_("Process record is not started.\n"));
1956 /* Set upper limit of record log size. */
1959 set_record_insn_max_num (char *args
, int from_tty
, struct cmd_list_element
*c
)
1961 if (record_insn_num
> record_insn_max_num
&& record_insn_max_num
)
1963 /* Count down record_insn_num while releasing records from list. */
1964 while (record_insn_num
> record_insn_max_num
)
1966 record_list_release_first ();
1972 static struct cmd_list_element
*record_cmdlist
, *set_record_cmdlist
,
1973 *show_record_cmdlist
, *info_record_cmdlist
;
1976 set_record_command (char *args
, int from_tty
)
1978 printf_unfiltered (_("\
1979 \"set record\" must be followed by an apporpriate subcommand.\n"));
1980 help_list (set_record_cmdlist
, "set record ", all_commands
, gdb_stdout
);
1984 show_record_command (char *args
, int from_tty
)
1986 cmd_show_list (show_record_cmdlist
, from_tty
, "");
1989 /* Display some statistics about the execution log. */
1992 info_record_command (char *args
, int from_tty
)
1994 struct record_entry
*p
;
1996 if (current_target
.to_stratum
== record_stratum
)
1998 if (RECORD_IS_REPLAY
)
1999 printf_filtered (_("Replay mode:\n"));
2001 printf_filtered (_("Record mode:\n"));
2003 /* Find entry for first actual instruction in the log. */
2004 for (p
= record_first
.next
;
2005 p
!= NULL
&& p
->type
!= record_end
;
2009 /* Do we have a log at all? */
2010 if (p
!= NULL
&& p
->type
== record_end
)
2012 /* Display instruction number for first instruction in the log. */
2013 printf_filtered (_("Lowest recorded instruction number is %s.\n"),
2014 pulongest (p
->u
.end
.insn_num
));
2016 /* If in replay mode, display where we are in the log. */
2017 if (RECORD_IS_REPLAY
)
2018 printf_filtered (_("Current instruction number is %s.\n"),
2019 pulongest (record_list
->u
.end
.insn_num
));
2021 /* Display instruction number for last instruction in the log. */
2022 printf_filtered (_("Highest recorded instruction number is %s.\n"),
2023 pulongest (record_insn_count
));
2025 /* Display log count. */
2026 printf_filtered (_("Log contains %d instructions.\n"),
2031 printf_filtered (_("No instructions have been logged.\n"));
2036 printf_filtered (_("target record is not active.\n"));
2039 /* Display max log size. */
2040 printf_filtered (_("Max logged instructions is %d.\n"),
2041 record_insn_max_num
);
2044 /* Record log save-file format
2045 Version 1 (never released)
2048 4 bytes: magic number htonl(0x20090829).
2049 NOTE: be sure to change whenever this file format changes!
2053 1 byte: record type (record_end, see enum record_type).
2055 1 byte: record type (record_reg, see enum record_type).
2056 8 bytes: register id (network byte order).
2057 MAX_REGISTER_SIZE bytes: register value.
2059 1 byte: record type (record_mem, see enum record_type).
2060 8 bytes: memory length (network byte order).
2061 8 bytes: memory address (network byte order).
2062 n bytes: memory value (n == memory length).
2065 4 bytes: magic number netorder32(0x20091016).
2066 NOTE: be sure to change whenever this file format changes!
2070 1 byte: record type (record_end, see enum record_type).
2072 4 bytes: instruction count
2074 1 byte: record type (record_reg, see enum record_type).
2075 4 bytes: register id (network byte order).
2076 n bytes: register value (n == actual register size).
2077 (eg. 4 bytes for x86 general registers).
2079 1 byte: record type (record_mem, see enum record_type).
2080 4 bytes: memory length (network byte order).
2081 8 bytes: memory address (network byte order).
2082 n bytes: memory value (n == memory length).
2086 /* bfdcore_read -- read bytes from a core file section. */
2089 bfdcore_read (bfd
*obfd
, asection
*osec
, void *buf
, int len
, int *offset
)
2091 int ret
= bfd_get_section_contents (obfd
, osec
, buf
, *offset
, len
);
2096 error (_("Failed to read %d bytes from core file %s ('%s').\n"),
2097 len
, bfd_get_filename (obfd
),
2098 bfd_errmsg (bfd_get_error ()));
2101 static inline uint64_t
2102 netorder64 (uint64_t input
)
2106 store_unsigned_integer ((gdb_byte
*) &ret
, sizeof (ret
),
2107 BFD_ENDIAN_BIG
, input
);
2111 static inline uint32_t
2112 netorder32 (uint32_t input
)
2116 store_unsigned_integer ((gdb_byte
*) &ret
, sizeof (ret
),
2117 BFD_ENDIAN_BIG
, input
);
2121 static inline uint16_t
2122 netorder16 (uint16_t input
)
2126 store_unsigned_integer ((gdb_byte
*) &ret
, sizeof (ret
),
2127 BFD_ENDIAN_BIG
, input
);
2131 /* Restore the execution log from a core_bfd file. */
2133 record_restore (void)
2136 struct cleanup
*old_cleanups
;
2137 struct record_entry
*rec
;
2141 struct regcache
*regcache
;
2143 /* We restore the execution log from the open core bfd,
2145 if (core_bfd
== NULL
)
2148 /* "record_restore" can only be called when record list is empty. */
2149 gdb_assert (record_first
.next
== NULL
);
2152 fprintf_unfiltered (gdb_stdlog
, "Restoring recording from core file.\n");
2154 /* Now need to find our special note section. */
2155 osec
= bfd_get_section_by_name (core_bfd
, "null0");
2156 osec_size
= bfd_section_size (core_bfd
, osec
);
2158 fprintf_unfiltered (gdb_stdlog
, "Find precord section %s.\n",
2159 osec
? "succeeded" : "failed");
2163 fprintf_unfiltered (gdb_stdlog
, "%s", bfd_section_name (core_bfd
, osec
));
2165 /* Check the magic code. */
2166 bfdcore_read (core_bfd
, osec
, &magic
, sizeof (magic
), &bfd_offset
);
2167 if (magic
!= RECORD_FILE_MAGIC
)
2168 error (_("Version mis-match or file format error in core file %s."),
2169 bfd_get_filename (core_bfd
));
2171 fprintf_unfiltered (gdb_stdlog
, "\
2172 Reading 4-byte magic cookie RECORD_FILE_MAGIC (0x%s)\n",
2173 phex_nz (netorder32 (magic
), 4));
2175 /* Restore the entries in recfd into record_arch_list_head and
2176 record_arch_list_tail. */
2177 record_arch_list_head
= NULL
;
2178 record_arch_list_tail
= NULL
;
2179 record_insn_num
= 0;
2180 old_cleanups
= make_cleanup (record_arch_list_cleanups
, 0);
2181 regcache
= get_current_regcache ();
2186 uint32_t regnum
, len
, signal
, count
;
2189 /* We are finished when offset reaches osec_size. */
2190 if (bfd_offset
>= osec_size
)
2192 bfdcore_read (core_bfd
, osec
, &rectype
, sizeof (rectype
), &bfd_offset
);
2196 case record_reg
: /* reg */
2197 /* Get register number to regnum. */
2198 bfdcore_read (core_bfd
, osec
, ®num
,
2199 sizeof (regnum
), &bfd_offset
);
2200 regnum
= netorder32 (regnum
);
2202 rec
= record_reg_alloc (regcache
, regnum
);
2205 bfdcore_read (core_bfd
, osec
, record_get_loc (rec
),
2206 rec
->u
.reg
.len
, &bfd_offset
);
2209 fprintf_unfiltered (gdb_stdlog
, "\
2210 Reading register %d (1 plus %lu plus %d bytes)\n",
2212 (unsigned long) sizeof (regnum
),
2216 case record_mem
: /* mem */
2218 bfdcore_read (core_bfd
, osec
, &len
,
2219 sizeof (len
), &bfd_offset
);
2220 len
= netorder32 (len
);
2223 bfdcore_read (core_bfd
, osec
, &addr
,
2224 sizeof (addr
), &bfd_offset
);
2225 addr
= netorder64 (addr
);
2227 rec
= record_mem_alloc (addr
, len
);
2230 bfdcore_read (core_bfd
, osec
, record_get_loc (rec
),
2231 rec
->u
.mem
.len
, &bfd_offset
);
2234 fprintf_unfiltered (gdb_stdlog
, "\
2235 Reading memory %s (1 plus %lu plus %lu plus %d bytes)\n",
2236 paddress (get_current_arch (),
2238 (unsigned long) sizeof (addr
),
2239 (unsigned long) sizeof (len
),
2243 case record_end
: /* end */
2244 rec
= record_end_alloc ();
2247 /* Get signal value. */
2248 bfdcore_read (core_bfd
, osec
, &signal
,
2249 sizeof (signal
), &bfd_offset
);
2250 signal
= netorder32 (signal
);
2251 rec
->u
.end
.sigval
= signal
;
2253 /* Get insn count. */
2254 bfdcore_read (core_bfd
, osec
, &count
,
2255 sizeof (count
), &bfd_offset
);
2256 count
= netorder32 (count
);
2257 rec
->u
.end
.insn_num
= count
;
2258 record_insn_count
= count
+ 1;
2260 fprintf_unfiltered (gdb_stdlog
, "\
2261 Reading record_end (1 + %lu + %lu bytes), offset == %s\n",
2262 (unsigned long) sizeof (signal
),
2263 (unsigned long) sizeof (count
),
2264 paddress (get_current_arch (),
2269 error (_("Bad entry type in core file %s."),
2270 bfd_get_filename (core_bfd
));
2274 /* Add rec to record arch list. */
2275 record_arch_list_add (rec
);
2278 discard_cleanups (old_cleanups
);
2280 /* Add record_arch_list_head to the end of record list. */
2281 record_first
.next
= record_arch_list_head
;
2282 record_arch_list_head
->prev
= &record_first
;
2283 record_arch_list_tail
->next
= NULL
;
2284 record_list
= &record_first
;
2286 /* Update record_insn_max_num. */
2287 if (record_insn_num
> record_insn_max_num
)
2289 record_insn_max_num
= record_insn_num
;
2290 warning (_("Auto increase record/replay buffer limit to %d."),
2291 record_insn_max_num
);
2295 printf_filtered (_("Restored records from core file %s.\n"),
2296 bfd_get_filename (core_bfd
));
2298 print_stack_frame (get_selected_frame (NULL
), 1, SRC_AND_LOC
);
2301 /* bfdcore_write -- write bytes into a core file section. */
2304 bfdcore_write (bfd
*obfd
, asection
*osec
, void *buf
, int len
, int *offset
)
2306 int ret
= bfd_set_section_contents (obfd
, osec
, buf
, *offset
, len
);
2311 error (_("Failed to write %d bytes to core file %s ('%s').\n"),
2312 len
, bfd_get_filename (obfd
),
2313 bfd_errmsg (bfd_get_error ()));
2316 /* Restore the execution log from a file. We use a modified elf
2317 corefile format, with an extra section for our data. */
2320 cmd_record_restore (char *args
, int from_tty
)
2322 core_file_command (args
, from_tty
);
2323 record_open (args
, from_tty
);
2327 record_save_cleanups (void *data
)
2330 char *pathname
= xstrdup (bfd_get_filename (obfd
));
2337 /* Save the execution log to a file. We use a modified elf corefile
2338 format, with an extra section for our data. */
2341 cmd_record_save (char *args
, int from_tty
)
2343 char *recfilename
, recfilename_buffer
[40];
2344 struct record_entry
*cur_record_list
;
2346 struct regcache
*regcache
;
2347 struct gdbarch
*gdbarch
;
2348 struct cleanup
*old_cleanups
;
2349 struct cleanup
*set_cleanups
;
2352 asection
*osec
= NULL
;
2355 if (strcmp (current_target
.to_shortname
, "record") != 0)
2356 error (_("This command can only be used with target 'record'.\n"
2357 "Use 'target record' first.\n"));
2363 /* Default recfile name is "gdb_record.PID". */
2364 snprintf (recfilename_buffer
, sizeof (recfilename_buffer
),
2365 "gdb_record.%d", PIDGET (inferior_ptid
));
2366 recfilename
= recfilename_buffer
;
2369 /* Open the save file. */
2371 fprintf_unfiltered (gdb_stdlog
, "Saving execution log to core file '%s'\n",
2374 /* Open the output file. */
2375 obfd
= create_gcore_bfd (recfilename
);
2376 old_cleanups
= make_cleanup (record_save_cleanups
, obfd
);
2378 /* Save the current record entry to "cur_record_list". */
2379 cur_record_list
= record_list
;
2381 /* Get the values of regcache and gdbarch. */
2382 regcache
= get_current_regcache ();
2383 gdbarch
= get_regcache_arch (regcache
);
2385 /* Disable the GDB operation record. */
2386 set_cleanups
= record_gdb_operation_disable_set ();
2388 /* Reverse execute to the begin of record list. */
2391 /* Check for beginning and end of log. */
2392 if (record_list
== &record_first
)
2395 record_exec_insn (regcache
, gdbarch
, record_list
);
2397 if (record_list
->prev
)
2398 record_list
= record_list
->prev
;
2401 /* Compute the size needed for the extra bfd section. */
2402 save_size
= 4; /* magic cookie */
2403 for (record_list
= record_first
.next
; record_list
;
2404 record_list
= record_list
->next
)
2405 switch (record_list
->type
)
2408 save_size
+= 1 + 4 + 4;
2411 save_size
+= 1 + 4 + record_list
->u
.reg
.len
;
2414 save_size
+= 1 + 4 + 8 + record_list
->u
.mem
.len
;
2418 /* Make the new bfd section. */
2419 osec
= bfd_make_section_anyway_with_flags (obfd
, "precord",
2423 error (_("Failed to create 'precord' section for corefile %s: %s"),
2425 bfd_errmsg (bfd_get_error ()));
2426 bfd_set_section_size (obfd
, osec
, save_size
);
2427 bfd_set_section_vma (obfd
, osec
, 0);
2428 bfd_set_section_alignment (obfd
, osec
, 0);
2429 bfd_section_lma (obfd
, osec
) = 0;
2431 /* Save corefile state. */
2432 write_gcore_file (obfd
);
2434 /* Write out the record log. */
2435 /* Write the magic code. */
2436 magic
= RECORD_FILE_MAGIC
;
2438 fprintf_unfiltered (gdb_stdlog
, "\
2439 Writing 4-byte magic cookie RECORD_FILE_MAGIC (0x%s)\n",
2440 phex_nz (magic
, 4));
2441 bfdcore_write (obfd
, osec
, &magic
, sizeof (magic
), &bfd_offset
);
2443 /* Save the entries to recfd and forward execute to the end of
2445 record_list
= &record_first
;
2449 if (record_list
!= &record_first
)
2452 uint32_t regnum
, len
, signal
, count
;
2455 type
= record_list
->type
;
2456 bfdcore_write (obfd
, osec
, &type
, sizeof (type
), &bfd_offset
);
2458 switch (record_list
->type
)
2460 case record_reg
: /* reg */
2462 fprintf_unfiltered (gdb_stdlog
, "\
2463 Writing register %d (1 plus %lu plus %d bytes)\n",
2464 record_list
->u
.reg
.num
,
2465 (unsigned long) sizeof (regnum
),
2466 record_list
->u
.reg
.len
);
2469 regnum
= netorder32 (record_list
->u
.reg
.num
);
2470 bfdcore_write (obfd
, osec
, ®num
,
2471 sizeof (regnum
), &bfd_offset
);
2474 bfdcore_write (obfd
, osec
, record_get_loc (record_list
),
2475 record_list
->u
.reg
.len
, &bfd_offset
);
2478 case record_mem
: /* mem */
2480 fprintf_unfiltered (gdb_stdlog
, "\
2481 Writing memory %s (1 plus %lu plus %lu plus %d bytes)\n",
2483 record_list
->u
.mem
.addr
),
2484 (unsigned long) sizeof (addr
),
2485 (unsigned long) sizeof (len
),
2486 record_list
->u
.mem
.len
);
2489 len
= netorder32 (record_list
->u
.mem
.len
);
2490 bfdcore_write (obfd
, osec
, &len
, sizeof (len
), &bfd_offset
);
2492 /* Write memaddr. */
2493 addr
= netorder64 (record_list
->u
.mem
.addr
);
2494 bfdcore_write (obfd
, osec
, &addr
,
2495 sizeof (addr
), &bfd_offset
);
2498 bfdcore_write (obfd
, osec
, record_get_loc (record_list
),
2499 record_list
->u
.mem
.len
, &bfd_offset
);
2504 fprintf_unfiltered (gdb_stdlog
, "\
2505 Writing record_end (1 + %lu + %lu bytes)\n",
2506 (unsigned long) sizeof (signal
),
2507 (unsigned long) sizeof (count
));
2508 /* Write signal value. */
2509 signal
= netorder32 (record_list
->u
.end
.sigval
);
2510 bfdcore_write (obfd
, osec
, &signal
,
2511 sizeof (signal
), &bfd_offset
);
2513 /* Write insn count. */
2514 count
= netorder32 (record_list
->u
.end
.insn_num
);
2515 bfdcore_write (obfd
, osec
, &count
,
2516 sizeof (count
), &bfd_offset
);
2521 /* Execute entry. */
2522 record_exec_insn (regcache
, gdbarch
, record_list
);
2524 if (record_list
->next
)
2525 record_list
= record_list
->next
;
2530 /* Reverse execute to cur_record_list. */
2533 /* Check for beginning and end of log. */
2534 if (record_list
== cur_record_list
)
2537 record_exec_insn (regcache
, gdbarch
, record_list
);
2539 if (record_list
->prev
)
2540 record_list
= record_list
->prev
;
2543 do_cleanups (set_cleanups
);
2545 discard_cleanups (old_cleanups
);
2548 printf_filtered (_("Saved core file %s with execution log.\n"),
2552 /* For "record pic" command. */
2554 static struct cmd_list_element
*set_record_pic_cmdlist
,
2555 *show_record_pic_cmdlist
;
2558 set_record_pic_command (char *args
, int from_tty
)
2560 printf_unfiltered (_("\
2561 \"set record pic\" must be followed by an apporpriate subcommand.\n"));
2562 help_list (set_record_cmdlist
, "set record pic ", all_commands
, gdb_stdout
);
2566 show_record_pic_command (char *args
, int from_tty
)
2568 cmd_show_list (show_record_pic_cmdlist
, from_tty
, "");
2571 static const char record_pic_function
[] = "function";
2572 static const char record_pic_line
[] = "line";
2573 static const char *record_pic_enum
[] =
2575 record_pic_function
,
2579 static const char *set_record_pic_type
= record_pic_line
;
2581 static int record_pic_hide_nofunction
= 1;
2582 static int record_pic_hide_nosource
= 1;
2583 static int record_pic_hide_same
= 1;
2586 record_pic_fputs (FILE *fp
, const char *buf
)
2588 if (fputs (buf
, fp
) == EOF
)
2589 error (_("Write to file error."));
2592 struct function_list
2594 struct function_list
*next
;
2600 struct node_list
*next
;
2604 struct symtab
*symtab
;
2606 struct minimal_symbol
*function
;
2611 struct edge_list
*next
;
2613 struct node_list
*s
;
2614 struct node_list
*t
;
2618 struct function_list
*function_list
= NULL
;
2619 struct node_list
*node_list
= NULL
;
2620 struct edge_list
*edge_list
= NULL
;
2623 record_pic_cleanups (void *data
)
2626 struct function_list
*fl
, *fl2
;
2627 struct node_list
*nl
, *nl2
;
2628 struct edge_list
*el
, *el2
;
2637 function_list
= NULL
;
2661 record_pic_node (char *buf
, int buf_max
, struct gdbarch
*gdbarch
,
2662 const char *type
, struct node_list
*nlp
)
2664 if (type
== record_pic_function
)
2666 snprintf (buf
, buf_max
, "%s %s %s",
2667 (nlp
->symtab
) ? nlp
->symtab
->filename
: "",
2668 (nlp
->function
) ? SYMBOL_LINKAGE_NAME (nlp
->function
) : "",
2669 (!nlp
->function
) ? paddress (gdbarch
, nlp
->addr
) : "");
2675 snprintf (buf
, buf_max
, "%s:%d %s %s", nlp
->symtab
->filename
,
2677 (nlp
->function
) ? SYMBOL_LINKAGE_NAME (nlp
->function
) : "",
2678 paddress (gdbarch
, nlp
->addr
));
2683 snprintf (buf
, buf_max
, "%s %d %s",
2684 (nlp
->function
) ? SYMBOL_LINKAGE_NAME (nlp
->function
) : "",
2685 nlp
->line
, paddress (gdbarch
, nlp
->addr
));
2687 snprintf (buf
, buf_max
, "%s %s",
2688 (nlp
->function
) ? SYMBOL_LINKAGE_NAME (nlp
->function
) : "",
2689 paddress (gdbarch
, nlp
->addr
));
2695 record_pic_edge (char *buf
, int buf_max
, struct edge_list
*elp
,
2696 char *node
, char *prev_node
)
2698 if (elp
->frame_diff
)
2701 snprintf (buf
, buf_max
, "edge: {color:blue sourcename: \"%s\" "
2702 "targetname: \"%s\"",
2705 snprintf (buf
, buf_max
, "edge: {color:red sourcename: \"%s\" "
2706 "targetname: \"%s\"",
2710 snprintf (buf
, buf_max
,
2711 "edge: {sourcename: \"%s\" targetname: \"%s\"",
2715 /* Save the execution log to a vcg file. */
2718 cmd_record_pic (char *args
, int from_tty
)
2720 char *recfilename
, recfilename_buffer
[40];
2722 struct cleanup
*old_cleanups
, *set_cleanups
;
2723 struct regcache
*regcache
;
2724 struct gdbarch
*gdbarch
;
2725 struct record_entry
*cur_record_list
;
2726 char prev_node
[256], line
[256];
2727 CORE_ADDR prev_addr
;
2728 struct frame_id fi
, caller_fi
, prev_fi
, prev_caller_fi
;
2729 struct function_list
*function_list_tail
, *function_list_prev
;
2730 struct edge_list
*edge_list_tail
= NULL
;
2731 struct node_list
*node_list_tail
= NULL
;
2732 struct symtab_and_line sal
, prev_sal
;
2733 struct node_list
*prev_nlp
;
2734 struct node_list prev_nlp_real
;
2737 /* Check if record target is running. */
2738 if (current_target
.to_stratum
!= record_stratum
)
2739 error (_("This command can only be used with target 'record' \
2740 or target 'record-core'."));
2746 /* Default recfile name is "gdb_record_PID.vcg". */
2747 snprintf (recfilename_buffer
, sizeof (recfilename_buffer
),
2748 "gdb_record_%d.vcg", PIDGET (inferior_ptid
));
2749 recfilename
= recfilename_buffer
;
2752 /* Open the output file. */
2753 fp
= fopen (recfilename
, "wb");
2755 error (_("Unable to open file '%s'"), recfilename
);
2757 old_cleanups
= make_cleanup (record_pic_cleanups
, fp
);
2759 /* Save the current record entry to "cur_record_list". */
2760 cur_record_list
= record_list
;
2762 /* Get the values of regcache and gdbarch. */
2763 regcache
= get_current_regcache ();
2764 gdbarch
= get_regcache_arch (regcache
);
2766 /* Disable the GDB operation record. */
2767 set_cleanups
= record_gdb_operation_disable_set ();
2769 /* Reverse execute to the begin of record list. */
2772 /* Check for beginning and end of log. */
2773 if (record_list
== &record_first
)
2776 record_exec_insn (regcache
, gdbarch
, record_list
);
2778 if (record_list
->prev
)
2779 record_list
= record_list
->prev
;
2782 /* Write out the record log. */
2783 /* Write the head. */
2784 record_pic_fputs (fp
, "graph: {title: \"GDB process record\"\n");
2786 /* Write the first node. */
2787 record_pic_fputs (fp
, "node: {title: \"[BEGIN]\" vertical_order:0}\n");
2789 /* Initialization. */
2790 snprintf (prev_node
, 256, "[BEGIN]");
2791 prev_fi
= null_frame_id
;
2792 prev_caller_fi
= null_frame_id
;
2794 prev_sal
.symtab
= NULL
;
2797 prev_nlp_real
.addr
= 0;
2798 prev_nlp
= &prev_nlp_real
;
2800 /* Create first entry for function_list. */
2801 function_list
= xmalloc (sizeof (struct function_list
));
2802 function_list
->next
= NULL
;
2803 function_list
->addr
= 0;
2804 function_list
->fid
= -1;
2805 function_list_tail
= function_list
;
2806 function_list_prev
= function_list
;
2808 /* Save the entries to fp and forward execute to the end of
2810 record_list
= &record_first
;
2813 if (record_list
->type
== record_end
)
2816 CORE_ADDR addr
= regcache_read_pc (regcache
);
2818 /* Check if the ADDR is stil in the same line with the
2821 && addr
>= prev_sal
.pc
&& addr
< prev_sal
.end
)
2823 sal
= find_pc_line (addr
, 0);
2825 if (record_pic_hide_nosource
&& !sal
.symtab
)
2828 /* Check if the inferior is in same frame with prev cycle.
2829 Check both the current fi and caller fi because the last
2830 addr of function is different with current function. */
2831 reinit_frame_cache ();
2832 fi
= get_frame_id (get_current_frame ());
2833 caller_fi
= frame_unwind_caller_id (get_current_frame ());
2834 if (!frame_id_eq (prev_fi
, fi
)
2835 && !frame_id_eq (prev_caller_fi
, caller_fi
))
2838 if (set_record_pic_type
== record_pic_line
|| frame_diff
)
2841 struct node_list
*nlp
= NULL
;
2842 struct edge_list
*elp
= NULL
;
2844 struct minimal_symbol
*function
;
2846 /* Get the node addr. */
2847 if (set_record_pic_type
== record_pic_function
)
2849 /* Get the start addr of function. */
2850 addr
= get_pc_function_start (addr
);
2853 if (record_pic_hide_nofunction
)
2855 addr
= regcache_read_pc (regcache
);
2860 /* Get the start addr of line. */
2865 function
= lookup_minimal_symbol_by_pc (addr
);
2866 if (!function
&& record_pic_hide_nofunction
)
2869 if (frame_id_eq (fi
, prev_caller_fi
))
2872 if (record_pic_hide_same
)
2874 /* Check if addr in node_list. */
2875 for (nlp
= node_list
; nlp
; nlp
= nlp
->next
)
2877 if (nlp
->addr
== addr
)
2880 || set_record_pic_type
!= record_pic_function
)
2886 /* Check if prev_addr and addr in edge_list. */
2889 for (elp
= edge_list
; elp
; elp
= elp
->next
)
2891 if (elp
->s
->addr
== prev_addr
&& elp
->t
->addr
== addr
)
2902 struct node_list nl
;
2903 CORE_ADDR function_addr
;
2904 struct function_list
*flp
;
2907 if (frame_diff
&& sal
.symtab
)
2911 nl
.symtab
= sal
.symtab
;
2913 nl
.function
= function
;
2915 /* Get the fid of the nl. */
2916 if (set_record_pic_type
!= record_pic_function
)
2917 function_addr
= get_pc_function_start (addr
);
2919 function_addr
= addr
;
2920 if (function_list_prev
->addr
== function_addr
)
2921 nl
.fid
= function_list_prev
->fid
;
2924 for (flp
= function_list
; flp
; flp
= flp
->next
)
2926 if (flp
->addr
== function_addr
)
2934 /* Creat a new entry to function_list. */
2935 nl
.fid
= fid_count
++;
2936 flp
= xmalloc (sizeof (struct function_list
));
2937 flp
->addr
= function_addr
;
2940 function_list_tail
->next
= flp
;
2941 function_list_tail
= flp
;
2943 function_list_prev
= flp
;
2946 if (record_pic_hide_same
)
2948 nlp
= xmalloc (sizeof (struct node_list
));
2952 /* Add node to node_list. */
2955 node_list_tail
->next
= nlp
;
2956 if (node_list
== NULL
)
2958 node_list_tail
= nlp
;
2962 /* Draw the node. */
2963 record_pic_node (node
, 256, gdbarch
,
2964 set_record_pic_type
, &nl
);
2965 snprintf (line
, 256, "%s i:%s", node
,
2966 pulongest (record_list
->u
.end
.insn_num
));
2967 strcpy (node
, line
);
2968 snprintf (line
, 256, "node: {title: \"%s\" "
2969 "vertical_order: %d}\n",
2971 record_pic_fputs (fp
, line
);
2977 struct edge_list el
;
2979 el
.is_return
= is_return
;
2980 el
.frame_diff
= frame_diff
;
2982 if (record_pic_hide_same
)
2984 elp
= xmalloc (sizeof (struct edge_list
));
2990 /* Add edge to edge_list. */
2993 edge_list_tail
->next
= elp
;
2994 if (edge_list
== NULL
)
2996 edge_list_tail
= elp
;
3000 /* Draw the edge. */
3001 record_pic_edge (line
, 256, &el
, node
, prev_node
);
3002 record_pic_fputs (fp
, line
);
3003 record_pic_fputs (fp
, " }\n");
3007 if (record_pic_hide_same
)
3010 snprintf (prev_node
, 256, "%s", node
);
3016 prev_caller_fi
= caller_fi
;
3020 /* Execute entry. */
3021 record_exec_insn (regcache
, gdbarch
, record_list
);
3023 if (record_list
->next
)
3024 record_list
= record_list
->next
;
3029 if (record_pic_hide_same
)
3031 struct node_list
*nlp
= NULL
;
3032 struct edge_list
*elp
= NULL
;
3035 for (nlp
= node_list
; nlp
; nlp
= nlp
->next
)
3037 /* Draw the node. */
3038 record_pic_node (node
, 256, gdbarch
, set_record_pic_type
, nlp
);
3039 snprintf (line
, 256, "node: {title: \"%s c:%d\" "
3040 "vertical_order: %d}\n", node
,
3041 nlp
->count
, nlp
->fid
);
3042 record_pic_fputs (fp
, line
);
3045 record_pic_node (node
, 256, gdbarch
, set_record_pic_type
, edge_list
->t
);
3046 snprintf (line
, 256,
3047 "edge: {color:red sourcename: \"[BEGIN]\" targetname: \"%s c:%d\"}\n",
3048 node
, edge_list
->count
);
3049 record_pic_fputs (fp
, line
);
3050 for (elp
= edge_list
->next
; elp
; elp
= elp
->next
)
3052 /* Draw the edge. */
3053 record_pic_node (prev_node
, 256, gdbarch
, set_record_pic_type
,
3055 snprintf (line
, 256, "%s c:%d", prev_node
, elp
->s
->count
);
3056 strcpy (prev_node
, line
);
3057 record_pic_node (node
, 256, gdbarch
, set_record_pic_type
,
3059 snprintf (line
, 256, "%s c:%d", node
, elp
->t
->count
);
3060 strcpy (node
, line
);
3061 record_pic_edge (line
, 256, elp
, node
, prev_node
);
3062 record_pic_fputs (fp
, line
);
3063 snprintf (line
, 256, " label: \"c:%d\"}\n", elp
->count
);
3064 record_pic_fputs (fp
, line
);
3068 /* Write the last node. */
3069 snprintf (line
, 256, "node: {title: \"[END]\" vertical_order: %d}\n",
3071 record_pic_fputs (fp
, line
);
3072 snprintf (line
, 256,
3073 "edge: {color:red sourcename: \"%s\" targetname: \"[END]\" }\n",
3075 record_pic_fputs (fp
, line
);
3077 /* Write the tail. */
3078 record_pic_fputs (fp
, "}\n");
3080 /* Reverse execute to cur_record_list. */
3083 /* Check for beginning and end of log. */
3084 if (record_list
== cur_record_list
)
3087 record_exec_insn (regcache
, gdbarch
, record_list
);
3089 if (record_list
->prev
)
3090 record_list
= record_list
->prev
;
3093 do_cleanups (set_cleanups
);
3094 do_cleanups (old_cleanups
);
3097 printf_filtered (_("Saved file %s with execution log.\n"),
3101 /* record_goto_insn -- rewind the record log (forward or backward,
3102 depending on DIR) to the given entry, changing the program state
3106 record_goto_insn (struct record_entry
*entry
,
3107 enum exec_direction_kind dir
)
3109 struct cleanup
*set_cleanups
= record_gdb_operation_disable_set ();
3110 struct regcache
*regcache
= get_current_regcache ();
3111 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
3113 /* Assume everything is valid: we will hit the entry,
3114 and we will not hit the end of the recording. */
3116 if (dir
== EXEC_FORWARD
)
3117 record_list
= record_list
->next
;
3121 record_exec_insn (regcache
, gdbarch
, record_list
);
3122 if (dir
== EXEC_REVERSE
)
3123 record_list
= record_list
->prev
;
3125 record_list
= record_list
->next
;
3126 } while (record_list
!= entry
);
3127 do_cleanups (set_cleanups
);
3130 /* "record goto" command. Argument is an instruction number,
3131 as given by "info record".
3133 Rewinds the recording (forward or backward) to the given instruction. */
3136 cmd_record_goto (char *arg
, int from_tty
)
3138 struct record_entry
*p
= NULL
;
3139 ULONGEST target_insn
= 0;
3141 if (arg
== NULL
|| *arg
== '\0')
3142 error (_("Command requires an argument (insn number to go to)."));
3144 if (strncmp (arg
, "start", strlen ("start")) == 0
3145 || strncmp (arg
, "begin", strlen ("begin")) == 0)
3147 /* Special case. Find first insn. */
3148 for (p
= &record_first
; p
!= NULL
; p
= p
->next
)
3149 if (p
->type
== record_end
)
3152 target_insn
= p
->u
.end
.insn_num
;
3154 else if (strncmp (arg
, "end", strlen ("end")) == 0)
3156 /* Special case. Find last insn. */
3157 for (p
= record_list
; p
->next
!= NULL
; p
= p
->next
)
3159 for (; p
!= NULL
; p
= p
->prev
)
3160 if (p
->type
== record_end
)
3163 target_insn
= p
->u
.end
.insn_num
;
3167 /* General case. Find designated insn. */
3168 target_insn
= parse_and_eval_long (arg
);
3170 for (p
= &record_first
; p
!= NULL
; p
= p
->next
)
3171 if (p
->type
== record_end
&& p
->u
.end
.insn_num
== target_insn
)
3176 error (_("Target insn '%s' not found."), arg
);
3177 else if (p
== record_list
)
3178 error (_("Already at insn '%s'."), arg
);
3179 else if (p
->u
.end
.insn_num
> record_list
->u
.end
.insn_num
)
3181 printf_filtered (_("Go forward to insn number %s\n"),
3182 pulongest (target_insn
));
3183 record_goto_insn (p
, EXEC_FORWARD
);
3187 printf_filtered (_("Go backward to insn number %s\n"),
3188 pulongest (target_insn
));
3189 record_goto_insn (p
, EXEC_REVERSE
);
3191 registers_changed ();
3192 reinit_frame_cache ();
3193 print_stack_frame (get_selected_frame (NULL
), 1, SRC_AND_LOC
);
3197 _initialize_record (void)
3199 struct cmd_list_element
*c
;
3201 /* Init record_first. */
3202 record_first
.prev
= NULL
;
3203 record_first
.next
= NULL
;
3204 record_first
.type
= record_end
;
3207 add_target (&record_ops
);
3208 init_record_core_ops ();
3209 add_target (&record_core_ops
);
3211 add_setshow_zinteger_cmd ("record", no_class
, &record_debug
,
3212 _("Set debugging of record/replay feature."),
3213 _("Show debugging of record/replay feature."),
3214 _("When enabled, debugging output for "
3215 "record/replay feature is displayed."),
3216 NULL
, show_record_debug
, &setdebuglist
,
3219 c
= add_prefix_cmd ("record", class_obscure
, cmd_record_start
,
3220 _("Abbreviated form of \"target record\" command."),
3221 &record_cmdlist
, "record ", 0, &cmdlist
);
3222 set_cmd_completer (c
, filename_completer
);
3224 add_com_alias ("rec", "record", class_obscure
, 1);
3225 add_prefix_cmd ("record", class_support
, set_record_command
,
3226 _("Set record options"), &set_record_cmdlist
,
3227 "set record ", 0, &setlist
);
3228 add_alias_cmd ("rec", "record", class_obscure
, 1, &setlist
);
3229 add_prefix_cmd ("record", class_support
, show_record_command
,
3230 _("Show record options"), &show_record_cmdlist
,
3231 "show record ", 0, &showlist
);
3232 add_alias_cmd ("rec", "record", class_obscure
, 1, &showlist
);
3233 add_prefix_cmd ("record", class_support
, info_record_command
,
3234 _("Info record options"), &info_record_cmdlist
,
3235 "info record ", 0, &infolist
);
3236 add_alias_cmd ("rec", "record", class_obscure
, 1, &infolist
);
3238 c
= add_cmd ("save", class_obscure
, cmd_record_save
,
3239 _("Save the execution log to a file.\n\
3240 Argument is optional filename.\n\
3241 Default filename is 'gdb_record.<process_id>'."),
3243 set_cmd_completer (c
, filename_completer
);
3245 c
= add_cmd ("restore", class_obscure
, cmd_record_restore
,
3246 _("Restore the execution log from a file.\n\
3247 Argument is filename. File must be created with 'record save'."),
3249 set_cmd_completer (c
, filename_completer
);
3251 add_cmd ("delete", class_obscure
, cmd_record_delete
,
3252 _("Delete the rest of execution log and start recording it anew."),
3254 add_alias_cmd ("d", "delete", class_obscure
, 1, &record_cmdlist
);
3255 add_alias_cmd ("del", "delete", class_obscure
, 1, &record_cmdlist
);
3257 add_cmd ("stop", class_obscure
, cmd_record_stop
,
3258 _("Stop the record/replay target."),
3260 add_alias_cmd ("s", "stop", class_obscure
, 1, &record_cmdlist
);
3262 /* Record instructions number limit command. */
3263 add_setshow_boolean_cmd ("stop-at-limit", no_class
,
3264 &record_stop_at_limit
, _("\
3265 Set whether record/replay stops when record/replay buffer becomes full."), _("\
3266 Show whether record/replay stops when record/replay buffer becomes full."), _("\
3268 When ON, if the record/replay buffer becomes full, ask user what to do.\n\
3269 When OFF, if the record/replay buffer becomes full,\n\
3270 delete the oldest recorded instruction to make room for each new one."),
3272 &set_record_cmdlist
, &show_record_cmdlist
);
3273 add_setshow_uinteger_cmd ("insn-number-max", no_class
,
3274 &record_insn_max_num
,
3275 _("Set record/replay buffer limit."),
3276 _("Show record/replay buffer limit."), _("\
3277 Set the maximum number of instructions to be stored in the\n\
3278 record/replay buffer. Zero means unlimited. Default is 200000."),
3279 set_record_insn_max_num
,
3280 NULL
, &set_record_cmdlist
, &show_record_cmdlist
);
3282 add_cmd ("goto", class_obscure
, cmd_record_goto
, _("\
3283 Restore the program to its state at instruction number N.\n\
3284 Argument is instruction number, as shown by 'info record'."),
3287 add_setshow_boolean_cmd ("memory-query", no_class
,
3288 &record_memory_query
, _("\
3289 Set whether query if PREC cannot record memory change of next instruction."),
3291 Show whether query if PREC cannot record memory change of next instruction."),
3294 When ON, query if PREC cannot record memory change of next instruction."),
3296 &set_record_cmdlist
, &show_record_cmdlist
);
3298 /* For "record pic" command. */
3299 c
= add_cmd ("pic", class_obscure
, cmd_record_pic
,
3300 _("Save the execution log to a vcg file.\n\
3301 Argument is optional filename.\n\
3302 Default filename is 'gdb_record_<process_id>.vcg'."),
3304 set_cmd_completer (c
, filename_completer
);
3305 add_prefix_cmd ("pic", class_support
, set_record_pic_command
,
3306 _("Set record pic options"), &set_record_pic_cmdlist
,
3307 "set record pic ", 0, &set_record_cmdlist
);
3308 add_prefix_cmd ("pic", class_support
, show_record_pic_command
,
3309 _("Show record pic options"), &show_record_pic_cmdlist
,
3310 "show record pic ", 0, &show_record_cmdlist
);
3311 add_setshow_enum_cmd ("type", no_class
,
3312 record_pic_enum
, &set_record_pic_type
, _("\
3313 Set the type of the nodes that record pic command saved."), _("\
3314 Show the type of the nodes that record pic command saved."), _("\
3315 When LINE, each node of vcg file that command record pic saved\n\
3316 will be a line of the inferior.\n\
3317 When FUNCTION, each node of vcg file that command record pic saved\n\
3318 will be a function of the inferior."),
3320 &set_record_pic_cmdlist
, &show_record_pic_cmdlist
);
3321 add_setshow_boolean_cmd ("hide-nofunction", no_class
,
3322 &record_pic_hide_nofunction
, _("\
3323 Set whether record pic command hide the nodes that don't have the function name."), _("\
3324 Show whether record pic command hide the nodes that don't have the function name."), _("\
3326 When ON, record pic command will hide the nodes that don't have\n\
3327 the function name.\n\
3328 When OFF, record pic command will show the nodes that don't have\n\
3329 the function name."),
3331 &set_record_pic_cmdlist
, &show_record_pic_cmdlist
);
3332 add_setshow_boolean_cmd ("hide-nosource", no_class
,
3333 &record_pic_hide_nosource
, _("\
3334 Set whether record pic command hide the nodes that don't have the source message."), _("\
3335 Show whether record pic command hide the nodes that don't have the source message."), _("\
3337 When ON, record pic command will hide the nodes that don't have\n\
3338 the source message.\n\
3339 When OFF, record pic command will show the nodes that don't have\n\
3340 the source message."),
3342 &set_record_pic_cmdlist
, &show_record_pic_cmdlist
);
3343 add_setshow_boolean_cmd ("hide-sameaddr", no_class
,
3344 &record_pic_hide_same
, _("\
3345 Set whether record pic command hide the nodes that have the same address node in vcg file."), _("\
3346 Show whether record pic command hide the nodes that have the same address node in vcg file."), _("\
3348 When ON, record pic command will hide the nodes that have\n\
3349 the same address node in vcg file.\n\
3350 And record pic will show the execute count number of this line\n\
3351 in format \"c:number\".\n\
3352 When OFF, record pic command will show the nodes that have\n\
3353 the same address node in vcg file.\n\
3354 And record pic show the instruction number in format \"i:number\"\n\
3355 that \"record goto\" support."),
3357 &set_record_pic_cmdlist
, &show_record_pic_cmdlist
);