1 /* Trace file support in GDB.
3 Copyright (C) 1997-2014 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/>. */
21 #include "tracefile.h"
28 #define TRACE_WRITE_R_BLOCK(writer, buf, size) \
29 writer->ops->frame_ops->write_r_block ((writer), (buf), (size))
30 #define TRACE_WRITE_M_BLOCK_HEADER(writer, addr, size) \
31 writer->ops->frame_ops->write_m_block_header ((writer), (addr), \
33 #define TRACE_WRITE_M_BLOCK_MEMORY(writer, buf, size) \
34 writer->ops->frame_ops->write_m_block_memory ((writer), (buf), \
36 #define TRACE_WRITE_V_BLOCK(writer, num, val) \
37 writer->ops->frame_ops->write_v_block ((writer), (num), (val))
39 /* Free trace file writer. */
42 trace_file_writer_xfree (void *arg)
44 struct trace_file_writer *writer = arg;
46 writer->ops->dtor (writer);
50 /* Save tracepoint data to file named FILENAME through WRITER. WRITER
51 determines the trace file format. If TARGET_DOES_SAVE is non-zero,
52 the save is performed on the target, otherwise GDB obtains all trace
53 data and saves it locally. */
56 trace_save (const char *filename, struct trace_file_writer *writer,
59 struct trace_status *ts = current_trace_status ();
61 struct uploaded_tp *uploaded_tps = NULL, *utp;
62 struct uploaded_tsv *uploaded_tsvs = NULL, *utsv;
65 #define MAX_TRACE_UPLOAD 2000
66 gdb_byte buf[MAX_TRACE_UPLOAD];
68 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
70 /* If the target is to save the data to a file on its own, then just
71 send the command and be done with it. */
74 if (!writer->ops->target_save (writer, filename))
75 error (_("Target failed to save trace data to '%s'."),
80 /* Get the trace status first before opening the file, so if the
81 target is losing, we can get out without touching files. */
82 status = target_get_trace_status (ts);
84 writer->ops->start (writer, filename);
86 writer->ops->write_header (writer);
88 /* Write descriptive info. */
90 /* Write out the size of a register block. */
91 writer->ops->write_regblock_type (writer, trace_regblock_size);
93 /* Write out status of the tracing run (aka "tstatus" info). */
94 writer->ops->write_status (writer, ts);
96 /* Note that we want to upload tracepoints and save those, rather
97 than simply writing out the local ones, because the user may have
98 changed tracepoints in GDB in preparation for a future tracing
99 run, or maybe just mass-deleted all types of breakpoints as part
100 of cleaning up. So as not to contaminate the session, leave the
101 data in its uploaded form, don't make into real tracepoints. */
103 /* Get trace state variables first, they may be checked when parsing
104 uploaded commands. */
106 target_upload_trace_state_variables (&uploaded_tsvs);
108 for (utsv = uploaded_tsvs; utsv; utsv = utsv->next)
109 writer->ops->write_uploaded_tsv (writer, utsv);
111 free_uploaded_tsvs (&uploaded_tsvs);
113 target_upload_tracepoints (&uploaded_tps);
115 for (utp = uploaded_tps; utp; utp = utp->next)
116 target_get_tracepoint_status (NULL, utp);
118 for (utp = uploaded_tps; utp; utp = utp->next)
119 writer->ops->write_uploaded_tp (writer, utp);
121 free_uploaded_tps (&uploaded_tps);
123 /* Mark the end of the definition section. */
124 writer->ops->write_definition_end (writer);
126 /* Get and write the trace data proper. */
131 /* The writer supports writing the contents of trace buffer
132 directly to trace file. Don't parse the contents of trace
134 if (writer->ops->write_trace_buffer != NULL)
136 /* We ask for big blocks, in the hopes of efficiency, but
137 will take less if the target has packet size limitations
139 gotten = target_get_raw_trace_data (buf, offset,
142 error (_("Failure to get requested trace buffer data"));
143 /* No more data is forthcoming, we're done. */
147 writer->ops->write_trace_buffer (writer, buf, gotten);
155 /* Parse the trace buffers according to how data are stored
156 in trace buffer in GDBserver. */
158 gotten = target_get_raw_trace_data (buf, offset, 6);
163 /* Read the first six bytes in, which is the tracepoint
164 number and trace frame size. */
166 extract_unsigned_integer (&buf[0], 2, byte_order);
169 extract_unsigned_integer (&buf[2], 4, byte_order);
171 writer->ops->frame_ops->start (writer, tp_num);
180 for (block = 0; block < tf_size; )
184 /* We'll fetch one block each time, in order to
185 handle the extremely large 'M' block. We first
186 fetch one byte to get the type of the block. */
187 gotten = target_get_raw_trace_data (buf, offset, 1);
189 error (_("Failure to get requested trace buffer data"));
200 = target_get_raw_trace_data (buf, offset,
201 trace_regblock_size);
202 if (gotten < trace_regblock_size)
203 error (_("Failure to get requested trace"
206 TRACE_WRITE_R_BLOCK (writer, buf,
207 trace_regblock_size);
216 t = target_get_raw_trace_data (buf,offset, 10);
218 error (_("Failure to get requested trace"
226 extract_unsigned_integer (buf, 8,
228 mlen = (unsigned short)
229 extract_unsigned_integer (&buf[8], 2,
232 TRACE_WRITE_M_BLOCK_HEADER (writer, addr,
235 /* The memory contents in 'M' block may be
236 very large. Fetch the data from the target
237 and write them into file one by one. */
238 for (j = 0; j < mlen; )
240 unsigned int read_length;
242 if (mlen - j > MAX_TRACE_UPLOAD)
243 read_length = MAX_TRACE_UPLOAD;
245 read_length = mlen - j;
247 t = target_get_raw_trace_data (buf,
251 error (_("Failure to get requested"
252 " trace buffer data"));
254 TRACE_WRITE_M_BLOCK_MEMORY (writer, buf,
258 gotten += read_length;
269 = target_get_raw_trace_data (buf, offset,
272 error (_("Failure to get requested"
273 " trace buffer data"));
275 vnum = (int) extract_signed_integer (buf,
279 = extract_signed_integer (&buf[4], 8,
282 TRACE_WRITE_V_BLOCK (writer, vnum, val);
286 error (_("Unknown block type '%c' (0x%x) in"
288 block_type, block_type);
298 writer->ops->frame_ops->end (writer);
302 writer->ops->end (writer);
306 trace_save_command (char *args, int from_tty)
308 int target_does_save = 0;
310 char *filename = NULL;
311 struct cleanup *back_to;
312 int generate_ctf = 0;
313 struct trace_file_writer *writer = NULL;
316 error_no_arg (_("file in which to save trace data"));
318 argv = gdb_buildargv (args);
319 back_to = make_cleanup_freeargv (argv);
321 for (; *argv; ++argv)
323 if (strcmp (*argv, "-r") == 0)
324 target_does_save = 1;
325 if (strcmp (*argv, "-ctf") == 0)
327 else if (**argv == '-')
328 error (_("unknown option `%s'"), *argv);
334 error_no_arg (_("file in which to save trace data"));
337 writer = ctf_trace_file_writer_new ();
339 writer = tfile_trace_file_writer_new ();
341 make_cleanup (trace_file_writer_xfree, writer);
343 trace_save (filename, writer, target_does_save);
346 printf_filtered (_("Trace data saved to %s '%s'.\n"),
347 generate_ctf ? "directory" : "file", filename);
349 do_cleanups (back_to);
352 /* Save the trace data to file FILENAME of tfile format. */
355 trace_save_tfile (const char *filename, int target_does_save)
357 struct trace_file_writer *writer;
358 struct cleanup *back_to;
360 writer = tfile_trace_file_writer_new ();
361 back_to = make_cleanup (trace_file_writer_xfree, writer);
362 trace_save (filename, writer, target_does_save);
363 do_cleanups (back_to);
366 /* Save the trace data to dir DIRNAME of ctf format. */
369 trace_save_ctf (const char *dirname, int target_does_save)
371 struct trace_file_writer *writer;
372 struct cleanup *back_to;
374 writer = ctf_trace_file_writer_new ();
375 back_to = make_cleanup (trace_file_writer_xfree, writer);
377 trace_save (dirname, writer, target_does_save);
378 do_cleanups (back_to);
381 /* Fetch register data from tracefile, shared for both tfile and
385 tracefile_fetch_registers (struct regcache *regcache, int regno)
387 struct gdbarch *gdbarch = get_regcache_arch (regcache);
390 /* We get here if no register data has been found. Mark registers
392 for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
393 regcache_raw_supply (regcache, regn, NULL);
395 /* We can often usefully guess that the PC is going to be the same
396 as the address of the tracepoint. */
397 pc_regno = gdbarch_pc_regnum (gdbarch);
399 /* XXX This guessing code below only works if the PC register isn't
400 a pseudo-register. The value of a pseudo-register isn't stored
401 in the (non-readonly) regcache -- instead it's recomputed
402 (probably from some other cached raw register) whenever the
403 register is read. This guesswork should probably move to some
405 if (pc_regno < 0 || pc_regno >= gdbarch_num_regs (gdbarch))
408 if (regno == -1 || regno == pc_regno)
410 struct tracepoint *tp = get_tracepoint (get_tracepoint_number ());
413 if (tp && tp->base.loc)
415 /* But don't try to guess if tracepoint is multi-location... */
416 if (tp->base.loc->next)
418 warning (_("Tracepoint %d has multiple "
419 "locations, cannot infer $pc"),
423 /* ... or does while-stepping. */
424 if (tp->step_count > 0)
426 warning (_("Tracepoint %d does while-stepping, "
432 regs = alloca (register_size (gdbarch, pc_regno));
433 store_unsigned_integer (regs, register_size (gdbarch, pc_regno),
434 gdbarch_byte_order (gdbarch),
435 tp->base.loc->address);
436 regcache_raw_supply (regcache, pc_regno, regs);
441 /* This is the implementation of target_ops method to_has_all_memory. */
444 tracefile_has_all_memory (struct target_ops *ops)
449 /* This is the implementation of target_ops method to_has_memory. */
452 tracefile_has_memory (struct target_ops *ops)
457 /* This is the implementation of target_ops method to_has_stack.
458 The target has a stack when GDB has already selected one trace
462 tracefile_has_stack (struct target_ops *ops)
464 return get_traceframe_number () != -1;
467 /* This is the implementation of target_ops method to_has_registers.
468 The target has registers when GDB has already selected one trace
472 tracefile_has_registers (struct target_ops *ops)
474 return get_traceframe_number () != -1;
477 /* This is the implementation of target_ops method to_thread_alive.
478 tracefile has one thread faked by GDB. */
481 tracefile_thread_alive (struct target_ops *ops, ptid_t ptid)
486 /* This is the implementation of target_ops method to_get_trace_status.
487 The trace status for a file is that tracing can never be run. */
490 tracefile_get_trace_status (struct target_ops *self, struct trace_status *ts)
492 /* Other bits of trace status were collected as part of opening the
493 trace files, so nothing to do here. */
498 /* Initialize OPS for tracefile related targets. */
501 init_tracefile_ops (struct target_ops *ops)
503 ops->to_stratum = process_stratum;
504 ops->to_get_trace_status = tracefile_get_trace_status;
505 ops->to_has_all_memory = tracefile_has_all_memory;
506 ops->to_has_memory = tracefile_has_memory;
507 ops->to_has_stack = tracefile_has_stack;
508 ops->to_has_registers = tracefile_has_registers;
509 ops->to_thread_alive = tracefile_thread_alive;
510 ops->to_magic = OPS_MAGIC;
513 extern initialize_file_ftype _initialize_tracefile;
516 _initialize_tracefile (void)
518 add_com ("tsave", class_trace, trace_save_command, _("\
519 Save the trace data to a file.\n\
520 Use the '-ctf' option to save the data to CTF format.\n\
521 Use the '-r' option to direct the target to save directly to the file,\n\
522 using its own filesystem."));