22#include "readline/tilde.h"
23#include "gdbsupport/filestuff.h"
24#include "gdbsupport/rsp-low.h"
34#include "gdbsupport/buffer.h"
35#include "gdbsupport/pathstuff.h"
46 N_(
"Local trace dump file"),
47 N_(
"Use a trace file as a target.\n\
48Specify the filename of the trace file.")
57 void close ()
override;
62 const gdb_byte *writebuf,
63 ULONGEST offset, ULONGEST len,
64 ULONGEST *xfered_len)
override;
67 CORE_ADDR addr1, CORE_ADDR addr2,
int *tpp)
override;
111 if (writer->
fp != NULL)
125 writer->
pathname = tilde_expand (filename);
126 writer->
fp = gdb_fopen_cloexec (writer->
pathname,
"wb").release ();
127 if (writer->
fp == NULL)
128 error (_(
"Unable to open file '%s' for saving trace data (%s)"),
129 writer->
pathname, safe_strerror (errno));
145 written = fwrite (
"\x7fTRACE0\n", 8, 1, writer->
fp);
159 fprintf (writer->
fp,
"R %x\n",
size);
172 fprintf (writer->
fp,
"status %c;%s",
177 char *buf = (
char *) alloca (strlen (ts->
stop_desc) * 2 + 1);
180 fprintf (writer->
fp,
":%s", buf);
197 fprintf (writer->
fp,
";starttime:%s",
202 fprintf (writer->
fp,
";stoptime:%s",
205 if (ts->
notes != NULL)
207 char *buf = (
char *) alloca (strlen (ts->
notes) * 2 + 1);
209 bin2hex ((gdb_byte *) ts->
notes, buf, strlen (ts->
notes));
210 fprintf (writer->
fp,
";notes:%s", buf);
214 char *buf = (
char *) alloca (strlen (ts->
user_name) * 2 + 1);
217 fprintf (writer->
fp,
";username:%s", buf);
219 fprintf (writer->
fp,
"\n");
235 buf = (
char *)
xmalloc (strlen (utsv->
name) * 2 + 1);
236 bin2hex ((gdb_byte *) (utsv->
name), buf, strlen (utsv->
name));
239 fprintf (writer->
fp,
"tsv %x:%s:%x:%s\n",
241 utsv->
builtin, buf != NULL ? buf :
"");
247#define MAX_TRACE_UPLOAD 2000
260 fprintf (writer->
fp,
"tp T%x:%s:%c:%x:%x",
267 ":X%x,%s", (
unsigned int) strlen (utp->
cond.get ()) / 2,
269 fprintf (writer->
fp,
"\n");
270 for (
const auto &act : utp->
actions)
271 fprintf (writer->
fp,
"tp A%x:%s:%s\n",
272 utp->
number, phex_nz (utp->
addr, sizeof (utp->
addr)), act.get ());
274 fprintf (writer->
fp,
"tp S%x:%s:%s\n",
275 utp->
number, phex_nz (utp->
addr, sizeof (utp->
addr)), act.get ());
281 fprintf (writer->
fp,
"tp Z%s\n", buf);
288 fprintf (writer->
fp,
"tp Z%s\n", buf);
294 fprintf (writer->
fp,
"tp Z%s\n", buf);
296 fprintf (writer->
fp,
"tp V%x:%s:%x:%s\n",
312 gdb::optional<std::string> tdesc
318 const char *ptr = tdesc->c_str ();
323 const char *next = strchr (ptr,
'\n');
326 fprintf (writer->
fp,
"tdesc %.*s\n", (
int) (next - ptr), ptr);
330 else if (*ptr !=
'\0')
333 fprintf (writer->
fp,
"tdesc %s\n", ptr);
348 fprintf (writer->
fp,
"\n");
361 if (fwrite (buf, len, 1, writer->
fp) < 1)
376 if (fwrite (&gotten, 4, 1, writer->
fp) < 1)
418#define TRACE_HEADER_SIZE 8
449 else if (gotten <
size)
450 error (_(
"Premature end of file while reading trace file"));
470 error (_(
"No trace file specified."));
472 gdb::unique_xmalloc_ptr<char> filename (tilde_expand (arg));
473 if (!IS_ABSOLUTE_PATH (filename.get ()))
474 filename = make_unique_xstrdup (gdb_abspath (filename.get ()).c_str ());
478 scratch_chan = gdb_open_cloexec (filename.get (),
flags, 0).release ();
479 if (scratch_chan < 0)
497 if (!(header[0] == 0x7f
498 && (startswith (header + 1,
"TRACE0\n"))))
499 error (_(
"File is not a valid trace file."));
537 error (_(
"Excessively long lines in trace file"));
549 error (_(
"No register block size recorded in trace file"));
551 catch (
const gdb_exception &ex)
564 warning (_(
"No traceframes present in this file."));
586 if (startswith (p,
"R "))
591 else if (startswith (p,
"status "))
593 p += strlen (
"status ");
596 else if (startswith (p,
"tp "))
601 else if (startswith (p,
"tsv "))
603 p += strlen (
"tsv ");
606 else if (startswith (p,
"tdesc "))
608 p += strlen (
"tdesc ");
612 warning (_(
"Ignoring trace file definition \"%s\""), line);
687 CORE_ADDR addr1, CORE_ADDR addr2,
int *tpp)
690 int tfnum = 0, found = 0;
691 unsigned int data_size;
693 off_t offset, tframe_offset;
707 tframe_offset = offset;
717 ((gdb_byte *) &data_size, 4,
746 if (addr1 <= tfaddr && tfaddr <= addr2)
751 if (!(addr1 <= tfaddr && tfaddr <= addr2))
755 internal_error (_(
"unknown tfind type"));
790 char *wantedp = (
char *) data;
792 if (*wantedp == blocktype)
834 mlen = (
unsigned short)
839 pos += (8 + 2 + mlen);
846 error (_(
"Unknown block type '%c' (0x%x) in trace frame"),
872 int offset, regn, regsize,
dummy;
888 regn, &
dummy, &offset))
902 else if (regno == -1)
915 gdb_byte *readbuf,
const gdb_byte *writebuf,
916 ULONGEST offset, ULONGEST len,
917 ULONGEST *xfered_len)
919 if (strcmp (annex,
"target.xml"))
923 error (_(
"tfile_xfer_partial: tdesc is read-only"));
934 memcpy (readbuf,
trace_tdesc.buffer + offset, len);
942 const char *annex, gdb_byte *readbuf,
943 const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
944 ULONGEST *xfered_len)
949 offset, len, xfered_len);
954 error (_(
"tfile_xfer_partial: trace file is read-only"));
962 ULONGEST low_addr_available = 0;
976 mlen = (
unsigned short)
983 if (maddr <= offset && offset < (maddr + mlen))
985 amt = (maddr + mlen) - offset;
996 if (offset < maddr && maddr < (offset + len))
997 if (low_addr_available == 0 || low_addr_available > maddr)
998 low_addr_available = maddr;
1001 pos += (8 + 2 + mlen);
1007 if (offset < low_addr_available)
1008 len = std::min (len, low_addr_available - offset);
1078 unsigned short mlen;
1085 mlen = (
unsigned short)
1090 info->memory.emplace_back (maddr, mlen);
1098 info->tvars.push_back (vnum);
1106 warning (_(
"Unhandled trace block type (%d) '%c ' "
1107 "while building trace frame info."),
1108 blocktype, blocktype);
struct gdbarch * target_gdbarch(void)
struct tracepoint * get_tracepoint_by_number_on_target(int num)
struct tracepoint * get_tracepoint(int num)
int unpush_target(struct target_ops *t)
void push_target(struct target_ops *t)
void raw_supply(int regnum, const void *buf) override
enum register_status get_register_status(int regnum) const override
bool get_trace_state_variable_value(int tsv, LONGEST *val) override
void fetch_registers(struct regcache *, int) override
const target_info & info() const override
int trace_find(enum trace_find_type type, int num, CORE_ADDR addr1, CORE_ADDR addr2, int *tpp) override
traceframe_info_up traceframe_info() override
enum target_xfer_status xfer_partial(enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) override
void files_info() override
void get_tracepoint_status(struct breakpoint *tp, struct uploaded_tp *utp) override
void filename_completer(struct cmd_list_element *ignore, completion_tracker &tracker, const char *text, const char *word)
static LONGEST extract_signed_integer(gdb::array_view< const gdb_byte > buf, enum bfd_endian byte_order)
static ULONGEST extract_unsigned_integer(gdb::array_view< const gdb_byte > buf, enum bfd_endian byte_order)
enum target_xfer_status section_table_read_available_memory(gdb_byte *readbuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
enum target_xfer_status exec_read_partial_read_only(gdb_byte *readbuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
ssize_t read(int fd, void *buf, size_t count)
enum bfd_endian gdbarch_byte_order(struct gdbarch *gdbarch)
int gdbarch_num_regs(struct gdbarch *gdbarch)
struct thread_info * add_thread_silent(process_stratum_target *targ, ptid_t ptid)
void switch_to_thread(struct thread_info *thr)
void switch_to_no_thread()
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t err
mach_port_t kern_return_t mach_port_t mach_msg_type_name_t msgportsPoly mach_port_t kern_return_t pid_t pid mach_port_t kern_return_t mach_port_t task mach_port_t kern_return_t int flags
void post_create_inferior(int from_tty)
void inferior_appeared(struct inferior *inf, int pid)
struct inferior * current_inferior(void)
void exit_inferior_silent(inferior *inf)
int register_size(struct gdbarch *gdbarch, int regnum)
int remote_register_number_and_offset(struct gdbarch *gdbarch, int regnum, int *pnum, int *poffset)
struct trace_file_writer base
const struct trace_file_write_ops * ops
enum trace_stop_reason stop_reason
std::vector< gdb::unique_xmalloc_ptr< char[]> > cmd_strings
gdb::unique_xmalloc_ptr< char[]> cond_string
std::vector< gdb::unique_xmalloc_ptr< char[]> > step_actions
ULONGEST traceframe_usage
std::vector< gdb::unique_xmalloc_ptr< char[]> > actions
gdb::unique_xmalloc_ptr< char[]> at_string
gdb::unique_xmalloc_ptr< char[]> cond
void target_find_description(void)
void add_target(const target_info &t, target_open_ftype *func, completer_ftype *completer)
void target_preopen(int from_tty)
int target_save_trace_data(const char *filename)
@ TARGET_XFER_UNAVAILABLE
@ TARGET_OBJECT_AVAILABLE_FEATURES
static int traceframe_walk_blocks(walk_blocks_callback_func callback, int pos, void *data)
struct trace_file_writer * tfile_trace_file_writer_new(void)
static int tfile_target_save(struct trace_file_writer *self, const char *filename)
static char * trace_filename
static void tfile_write_header(struct trace_file_writer *self)
static void tfile_read(gdb_byte *readbuf, int size)
static off_t trace_frames_offset
static void tfile_write_definition_end(struct trace_file_writer *self)
#define TRACE_HEADER_SIZE
static void tfile_write_regblock_type(struct trace_file_writer *self, int size)
static void tfile_target_open(const char *arg, int from_tty)
static struct buffer trace_tdesc
int(* walk_blocks_callback_func)(char blocktype, void *data)
static int build_traceframe_info(char blocktype, void *data)
static CORE_ADDR tfile_get_traceframe_address(off_t tframe_offset)
static void tfile_write_status(struct trace_file_writer *self, struct trace_status *ts)
static void tfile_append_tdesc_line(const char *line)
static void tfile_write_uploaded_tp(struct trace_file_writer *self, struct uploaded_tp *utp)
static int traceframe_find_block_type(char type_wanted, int pos)
static void tfile_write_raw_data(struct trace_file_writer *self, gdb_byte *buf, LONGEST len)
static void tfile_write_tdesc(struct trace_file_writer *self)
static void tfile_end(struct trace_file_writer *self)
static void tfile_write_uploaded_tsv(struct trace_file_writer *self, struct uploaded_tsv *utsv)
static const target_info tfile_target_info
static enum target_xfer_status tfile_xfer_partial_features(const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
static void tfile_interp_line(char *line, struct uploaded_tp **utpp, struct uploaded_tsv **utsvp)
static const struct trace_file_write_ops tfile_write_ops
static void tfile_dtor(struct trace_file_writer *self)
static int match_blocktype(char blocktype, void *data)
static void tfile_start(struct trace_file_writer *self, const char *filename)
void _initialize_tracefile_tfile()
static tfile_target tfile_ops
void tracefile_fetch_registers(struct regcache *regcache, int regno)
struct trace_status * current_trace_status(void)
const char * stop_reason_names[]
void parse_trace_status(const char *line, struct trace_status *ts)
int get_traceframe_number(void)
void parse_tsv_definition(const char *line, struct uploaded_tsv **utsvp)
void trace_reset_local_state(void)
void merge_uploaded_tracepoints(struct uploaded_tp **uploaded_tps)
int encode_source_string(int tpnum, ULONGEST addr, const char *srctype, const char *src, char *buf, int buf_size)
void parse_tracepoint_definition(const char *line, struct uploaded_tp **utpp)
void merge_uploaded_trace_state_variables(struct uploaded_tsv **uploaded_tsvs)
std::unique_ptr< traceframe_info > traceframe_info_up
@ trace_stop_reason_unknown
void perror_with_name(const char *string)
void gdb_printf(struct ui_file *stream, const char *format,...)
gdb::optional< std::string > target_fetch_description_xml(struct target_ops *ops)