1 /* Branch trace support for GDB, the GNU debugger.
3 Copyright (C) 2013 Free Software Foundation, Inc.
5 Contributed by Intel Corp. <markus.t.metzger@intel.com>
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 #include "gdbthread.h"
24 #include "exceptions.h"
31 #include "filenames.h"
33 /* Print a record debug message. Use do ... while (0) to avoid ambiguities
34 when used in if statements. */
36 #define DEBUG(msg, args...) \
39 if (record_debug != 0) \
40 fprintf_unfiltered (gdb_stdlog, \
41 "[btrace] " msg "\n", ##args); \
45 #define DEBUG_FTRACE(msg, args...) DEBUG ("[ftrace] " msg, ##args)
47 /* Initialize the instruction iterator. */
50 btrace_init_insn_iterator (struct btrace_thread_info
*btinfo
)
52 DEBUG ("init insn iterator");
54 btinfo
->insn_iterator
.begin
= 1;
55 btinfo
->insn_iterator
.end
= 0;
58 /* Initialize the function iterator. */
61 btrace_init_func_iterator (struct btrace_thread_info
*btinfo
)
63 DEBUG ("init func iterator");
65 btinfo
->func_iterator
.begin
= 1;
66 btinfo
->func_iterator
.end
= 0;
69 /* Compute the instruction trace from the block trace. */
71 static VEC (btrace_inst_s
) *
72 compute_itrace (VEC (btrace_block_s
) *btrace
)
74 VEC (btrace_inst_s
) *itrace
;
75 struct gdbarch
*gdbarch
;
78 DEBUG ("compute itrace");
81 gdbarch
= target_gdbarch ();
82 b
= VEC_length (btrace_block_s
, btrace
);
86 btrace_block_s
*block
;
89 block
= VEC_index (btrace_block_s
, btrace
, b
);
92 /* Add instructions for this block. */
98 /* We should hit the end of the block. Warn if we went too far. */
101 warning (_("Recorded trace may be corrupted."));
105 inst
= VEC_safe_push (btrace_inst_s
, itrace
, NULL
);
108 /* We're done once we pushed the instruction at the end. */
109 if (block
->end
== pc
)
112 size
= gdb_insn_length (gdbarch
, pc
);
114 /* Make sure we terminate if we fail to compute the size. */
117 warning (_("Recorded trace may be incomplete."));
128 /* Return the function name of a recorded function segment for printing.
129 This function never returns NULL. */
132 ftrace_print_function_name (struct btrace_func
*bfun
)
134 struct minimal_symbol
*msym
;
141 return SYMBOL_PRINT_NAME (sym
);
144 return SYMBOL_PRINT_NAME (msym
);
149 /* Return the file name of a recorded function segment for printing.
150 This function never returns NULL. */
153 ftrace_print_filename (struct btrace_func
*bfun
)
156 const char *filename
;
161 filename
= symtab_to_filename_for_display (sym
->symtab
);
163 filename
= "<unknown>";
168 /* Print an ftrace debug status message. */
171 ftrace_debug (struct btrace_func
*bfun
, const char *prefix
)
173 DEBUG_FTRACE ("%s: fun = %s, file = %s, lines = [%d; %d], insn = [%u; %u]",
174 prefix
, ftrace_print_function_name (bfun
),
175 ftrace_print_filename (bfun
), bfun
->lbegin
, bfun
->lend
,
176 bfun
->ibegin
, bfun
->iend
);
179 /* Initialize a recorded function segment. */
182 ftrace_init_func (struct btrace_func
*bfun
, struct minimal_symbol
*mfun
,
183 struct symbol
*fun
, unsigned int idx
)
187 bfun
->lbegin
= INT_MAX
;
193 /* Check whether the function has changed. */
196 ftrace_function_switched (struct btrace_func
*bfun
,
197 struct minimal_symbol
*mfun
, struct symbol
*fun
)
199 struct minimal_symbol
*msym
;
202 /* The function changed if we did not have one before. */
209 /* If the minimal symbol changed, we certainly switched functions. */
210 if (mfun
!= NULL
&& msym
!= NULL
211 && strcmp (SYMBOL_LINKAGE_NAME (mfun
), SYMBOL_LINKAGE_NAME (msym
)) != 0)
214 /* If the symbol changed, we certainly switched functions. */
215 if (fun
!= NULL
&& sym
!= NULL
)
217 const char *bfname
, *fname
;
219 /* Check the function name. */
220 if (strcmp (SYMBOL_LINKAGE_NAME (fun
), SYMBOL_LINKAGE_NAME (sym
)) != 0)
223 /* Check the location of those functions, as well. */
224 bfname
= symtab_to_fullname (sym
->symtab
);
225 fname
= symtab_to_fullname (fun
->symtab
);
226 if (filename_cmp (fname
, bfname
) != 0)
233 /* Check if we should skip this file when generating the function call
234 history. We would want to do that if, say, a macro that is defined
235 in another file is expanded in this function. */
238 ftrace_skip_file (struct btrace_func
*bfun
, const char *filename
)
246 bfile
= symtab_to_fullname (sym
->symtab
);
250 if (filename
== NULL
)
253 return (filename_cmp (bfile
, filename
) != 0);
256 /* Compute the function trace from the instruction trace. */
258 static VEC (btrace_func_s
) *
259 compute_ftrace (VEC (btrace_inst_s
) *itrace
)
261 VEC (btrace_func_s
) *ftrace
;
262 struct btrace_inst
*binst
;
263 struct btrace_func
*bfun
;
266 DEBUG ("compute ftrace");
271 for (idx
= 0; VEC_iterate (btrace_inst_s
, itrace
, idx
, binst
); ++idx
)
273 struct symtab_and_line sal
;
274 struct minimal_symbol
*mfun
;
276 const char *filename
;
281 /* Try to determine the function we're in. We use both types of symbols
282 to avoid surprises when we sometimes get a full symbol and sometimes
283 only a minimal symbol. */
284 fun
= find_pc_function (pc
);
285 mfun
= lookup_minimal_symbol_by_pc (pc
);
287 if (fun
== NULL
&& mfun
== NULL
)
289 DEBUG_FTRACE ("no symbol at %u, pc=%s", idx
,
290 core_addr_to_string_nz (pc
));
294 /* If we're switching functions, we start over. */
295 if (ftrace_function_switched (bfun
, mfun
, fun
))
297 bfun
= VEC_safe_push (btrace_func_s
, ftrace
, NULL
);
299 ftrace_init_func (bfun
, mfun
, fun
, idx
);
300 ftrace_debug (bfun
, "init");
303 /* Update the instruction range. */
305 ftrace_debug (bfun
, "update insns");
307 /* Let's see if we have source correlation, as well. */
308 sal
= find_pc_line (pc
, 0);
309 if (sal
.symtab
== NULL
|| sal
.line
== 0)
311 DEBUG_FTRACE ("no lines at %u, pc=%s", idx
,
312 core_addr_to_string_nz (pc
));
316 /* Check if we switched files. This could happen if, say, a macro that
317 is defined in another file is expanded here. */
318 filename
= symtab_to_fullname (sal
.symtab
);
319 if (ftrace_skip_file (bfun
, filename
))
321 DEBUG_FTRACE ("ignoring file at %u, pc=%s, file=%s", idx
,
322 core_addr_to_string_nz (pc
), filename
);
326 /* Update the line range. */
327 bfun
->lbegin
= min (bfun
->lbegin
, sal
.line
);
328 bfun
->lend
= max (bfun
->lend
, sal
.line
);
329 ftrace_debug (bfun
, "update lines");
338 btrace_enable (struct thread_info
*tp
)
340 if (tp
->btrace
.target
!= NULL
)
343 if (!target_supports_btrace ())
344 error (_("Target does not support branch tracing."));
346 DEBUG ("enable thread %d (%s)", tp
->num
, target_pid_to_str (tp
->ptid
));
348 tp
->btrace
.target
= target_enable_btrace (tp
->ptid
);
354 btrace_disable (struct thread_info
*tp
)
356 struct btrace_thread_info
*btp
= &tp
->btrace
;
359 if (btp
->target
== NULL
)
362 DEBUG ("disable thread %d (%s)", tp
->num
, target_pid_to_str (tp
->ptid
));
364 target_disable_btrace (btp
->target
);
373 btrace_teardown (struct thread_info
*tp
)
375 struct btrace_thread_info
*btp
= &tp
->btrace
;
378 if (btp
->target
== NULL
)
381 DEBUG ("teardown thread %d (%s)", tp
->num
, target_pid_to_str (tp
->ptid
));
383 target_teardown_btrace (btp
->target
);
392 btrace_fetch (struct thread_info
*tp
)
394 struct btrace_thread_info
*btinfo
;
395 VEC (btrace_block_s
) *btrace
;
397 DEBUG ("fetch thread %d (%s)", tp
->num
, target_pid_to_str (tp
->ptid
));
399 btinfo
= &tp
->btrace
;
400 if (btinfo
->target
== NULL
)
403 btrace
= target_read_btrace (btinfo
->target
, btrace_read_new
);
404 if (VEC_empty (btrace_block_s
, btrace
))
409 btinfo
->btrace
= btrace
;
410 btinfo
->itrace
= compute_itrace (btinfo
->btrace
);
411 btinfo
->ftrace
= compute_ftrace (btinfo
->itrace
);
413 /* Initialize branch trace iterators. */
414 btrace_init_insn_iterator (btinfo
);
415 btrace_init_func_iterator (btinfo
);
421 btrace_clear (struct thread_info
*tp
)
423 struct btrace_thread_info
*btinfo
;
425 DEBUG ("clear thread %d (%s)", tp
->num
, target_pid_to_str (tp
->ptid
));
427 btinfo
= &tp
->btrace
;
429 VEC_free (btrace_block_s
, btinfo
->btrace
);
430 VEC_free (btrace_inst_s
, btinfo
->itrace
);
431 VEC_free (btrace_func_s
, btinfo
->ftrace
);
433 btinfo
->btrace
= NULL
;
434 btinfo
->itrace
= NULL
;
435 btinfo
->ftrace
= NULL
;
441 btrace_free_objfile (struct objfile
*objfile
)
443 struct thread_info
*tp
;
445 DEBUG ("free objfile");
This page took 0.040575 seconds and 5 git commands to generate.