22#include "readline/tilde.h"
23#include "gdbsupport/filestuff.h"
24#include "gdbsupport/rsp-low.h"
34#include "gdbsupport/pathstuff.h"
45 N_(
"Local trace dump file"),
46 N_(
"Use a trace file as a target.\n\
47Specify the filename of the trace file.")
56 void close ()
override;
61 const gdb_byte *writebuf,
62 ULONGEST offset, ULONGEST len,
63 ULONGEST *xfered_len)
override;
66 CORE_ADDR addr1, CORE_ADDR addr2,
int *tpp)
override;
110 if (writer->
fp != NULL)
124 writer->
pathname = tilde_expand (filename);
125 writer->
fp = gdb_fopen_cloexec (writer->
pathname,
"wb").release ();
126 if (writer->
fp == NULL)
127 error (_(
"Unable to open file '%s' for saving trace data (%s)"),
128 writer->
pathname, safe_strerror (errno));
144 written = fwrite (
"\x7fTRACE0\n", 8, 1, writer->
fp);
146 perror_with_name (writer->
pathname);
158 fprintf (writer->
fp,
"R %x\n",
size);
171 fprintf (writer->
fp,
"status %c;%s",
176 char *buf = (
char *) alloca (strlen (ts->
stop_desc) * 2 + 1);
179 fprintf (writer->
fp,
":%s", buf);
196 fprintf (writer->
fp,
";starttime:%s",
201 fprintf (writer->
fp,
";stoptime:%s",
204 if (ts->
notes != NULL)
206 char *buf = (
char *) alloca (strlen (ts->
notes) * 2 + 1);
208 bin2hex ((gdb_byte *) ts->
notes, buf, strlen (ts->
notes));
209 fprintf (writer->
fp,
";notes:%s", buf);
213 char *buf = (
char *) alloca (strlen (ts->
user_name) * 2 + 1);
216 fprintf (writer->
fp,
";username:%s", buf);
218 fprintf (writer->
fp,
"\n");
228 gdb::unique_xmalloc_ptr<char> buf;
234 buf.reset ((
char *)
xmalloc (strlen (utsv->
name) * 2 + 1));
235 bin2hex ((gdb_byte *) (utsv->
name), buf.get (), strlen (utsv->
name));
238 fprintf (writer->
fp,
"tsv %x:%s:%x:%s\n",
240 utsv->
builtin, buf != NULL ? buf.get () :
"");
243#define MAX_TRACE_UPLOAD 2000
256 fprintf (writer->
fp,
"tp T%x:%s:%c:%x:%x",
263 ":X%x,%s", (
unsigned int) strlen (utp->
cond.get ()) / 2,
265 fprintf (writer->
fp,
"\n");
266 for (
const auto &act : utp->
actions)
267 fprintf (writer->
fp,
"tp A%x:%s:%s\n",
268 utp->
number, phex_nz (utp->
addr, sizeof (utp->
addr)), act.get ());
270 fprintf (writer->
fp,
"tp S%x:%s:%s\n",
271 utp->
number, phex_nz (utp->
addr, sizeof (utp->
addr)), act.get ());
277 fprintf (writer->
fp,
"tp Z%s\n", buf);
284 fprintf (writer->
fp,
"tp Z%s\n", buf);
290 fprintf (writer->
fp,
"tp Z%s\n", buf);
292 fprintf (writer->
fp,
"tp V%x:%s:%x:%s\n",
308 gdb::optional<std::string> tdesc
314 const char *ptr = tdesc->c_str ();
319 const char *next = strchr (ptr,
'\n');
322 fprintf (writer->
fp,
"tdesc %.*s\n", (
int) (next - ptr), ptr);
326 else if (*ptr !=
'\0')
329 fprintf (writer->
fp,
"tdesc %s\n", ptr);
344 fprintf (writer->
fp,
"\n");
357 if (fwrite (buf, len, 1, writer->
fp) < 1)
358 perror_with_name (writer->
pathname);
372 if (fwrite (&gotten, 4, 1, writer->
fp) < 1)
373 perror_with_name (writer->
pathname);
414#define TRACE_HEADER_SIZE 8
445 else if (gotten <
size)
446 error (_(
"Premature end of file while reading trace file"));
466 error (_(
"No trace file specified."));
468 gdb::unique_xmalloc_ptr<char> filename (tilde_expand (arg));
469 if (!IS_ABSOLUTE_PATH (filename.get ()))
470 filename = make_unique_xstrdup (gdb_abspath (filename.get ()).c_str ());
474 scratch_chan = gdb_open_cloexec (filename.get (),
flags, 0).release ();
475 if (scratch_chan < 0)
476 perror_with_name (filename.get ());
493 if (!(header[0] == 0x7f
494 && (startswith (header + 1,
"TRACE0\n"))))
495 error (_(
"File is not a valid trace file."));
533 error (_(
"Excessively long lines in trace file"));
545 error (_(
"No register block size recorded in trace file"));
547 catch (
const gdb_exception &ex)
560 warning (_(
"No traceframes present in this file."));
580 const char *p = line;
582 if (startswith (p,
"R "))
587 else if (startswith (p,
"status "))
589 p += strlen (
"status ");
592 else if (startswith (p,
"tp "))
597 else if (startswith (p,
"tsv "))
599 p += strlen (
"tsv ");
602 else if (startswith (p,
"tdesc "))
604 p += strlen (
"tdesc ");
608 warning (_(
"Ignoring trace file definition \"%s\""), line);
682 CORE_ADDR addr1, CORE_ADDR addr2,
int *tpp)
685 int tfnum = 0, found = 0;
686 unsigned int data_size;
688 off_t offset, tframe_offset;
702 tframe_offset = offset;
712 ((gdb_byte *) &data_size, 4,
741 if (addr1 <= tfaddr && tfaddr <= addr2)
746 if (!(addr1 <= tfaddr && tfaddr <= addr2))
750 internal_error (_(
"unknown tfind type"));
811 mlen = (
unsigned short)
816 pos += (8 + 2 + mlen);
823 error (_(
"Unknown block type '%c' (0x%x) in trace frame"),
841 return blocktype == type_wanted;
852 int offset, regn, regsize,
dummy;
868 regn, &
dummy, &offset))
882 else if (regno == -1)
895 gdb_byte *readbuf,
const gdb_byte *writebuf,
896 ULONGEST offset, ULONGEST len,
897 ULONGEST *xfered_len)
899 if (strcmp (annex,
"target.xml"))
903 error (_(
"tfile_xfer_partial: tdesc is read-only"));
914 memcpy (readbuf,
trace_tdesc.c_str () + offset, len);
922 const char *annex, gdb_byte *readbuf,
923 const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
924 ULONGEST *xfered_len)
929 offset, len, xfered_len);
934 error (_(
"tfile_xfer_partial: trace file is read-only"));
942 ULONGEST low_addr_available = 0;
956 mlen = (
unsigned short)
963 if (maddr <= offset && offset < (maddr + mlen))
965 amt = (maddr + mlen) - offset;
976 if (offset < maddr && maddr < (offset + len))
977 if (low_addr_available == 0 || low_addr_available > maddr)
978 low_addr_available = maddr;
981 pos += (8 + 2 + mlen);
987 if (offset < low_addr_available)
988 len = std::min (len, low_addr_available - offset);
1056 unsigned short mlen;
1063 mlen = (
unsigned short)
1068 info->memory.emplace_back (maddr, mlen);
1076 info->tvars.push_back (vnum);
1084 warning (_(
"Unhandled trace block type (%d) '%c ' "
1085 "while building trace frame info."),
1086 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
void get_tracepoint_status(tracepoint *tp, struct uploaded_tp *utp) 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 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(struct 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)
bool has_locations() const
bp_location & first_loc()
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
struct trace_file_writer * tfile_trace_file_writer_new(void)
static int tfile_target_save(struct trace_file_writer *self, const char *filename)
static int traceframe_walk_blocks(gdb::function_view< bool(char)> callback, int pos)
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 gdb::unique_xmalloc_ptr< char > trace_filename
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 void tfile_interp_line(const char *line, struct uploaded_tp **utpp, struct uploaded_tsv **utsvp)
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 std::string trace_tdesc
static const struct trace_file_write_ops tfile_write_ops
static void tfile_dtor(struct trace_file_writer *self)
static void tfile_start(struct trace_file_writer *self, const char *filename)
void _initialize_tracefile_tfile()
static tfile_target tfile_ops
static bool build_traceframe_info(char blocktype, struct traceframe_info *info)
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 gdb_printf(struct ui_file *stream, const char *format,...)
gdb::optional< std::string > target_fetch_description_xml(struct target_ops *ops)