static void btrace_add_pc (struct thread_info *tp) { struct btrace_data btrace; struct btrace_block *block; struct regcache *regcache; struct cleanup *cleanup; CORE_ADDR pc; regcache = get_thread_regcache (tp->ptid); pc = regcache_read_pc (regcache); btrace_data_init (&btrace); btrace.format = BTRACE_FORMAT_BTS; btrace.variant.bts.blocks = NULL; cleanup = make_cleanup_btrace_data (&btrace); block = VEC_safe_push (btrace_block_s, btrace.variant.bts.blocks, NULL); block->begin = pc; block->end = pc; btrace_compute_ftrace (tp, &btrace); do_cleanups (cleanup); }
void btrace_fetch (struct thread_info *tp) { struct btrace_thread_info *btinfo; struct btrace_target_info *tinfo; struct btrace_data btrace; struct cleanup *cleanup; int errcode; DEBUG ("fetch thread %d (%s)", tp->num, target_pid_to_str (tp->ptid)); btinfo = &tp->btrace; tinfo = btinfo->target; if (tinfo == NULL) return; /* There's no way we could get new trace while replaying. On the other hand, delta trace would return a partial record with the current PC, which is the replay PC, not the last PC, as expected. */ if (btinfo->replay != NULL) return; btrace_data_init (&btrace); cleanup = make_cleanup_btrace_data (&btrace); /* Let's first try to extend the trace we already have. */ if (btinfo->end != NULL) { errcode = target_read_btrace (&btrace, tinfo, BTRACE_READ_DELTA); if (errcode == 0) { /* Success. Let's try to stitch the traces together. */ errcode = btrace_stitch_trace (&btrace, tp); } else { /* We failed to read delta trace. Let's try to read new trace. */ errcode = target_read_btrace (&btrace, tinfo, BTRACE_READ_NEW); /* If we got any new trace, discard what we have. */ if (errcode == 0 && !btrace_data_empty (&btrace)) btrace_clear (tp); } /* If we were not able to read the trace, we start over. */ if (errcode != 0) { btrace_clear (tp); errcode = target_read_btrace (&btrace, tinfo, BTRACE_READ_ALL); } } else errcode = target_read_btrace (&btrace, tinfo, BTRACE_READ_ALL); /* If we were not able to read the branch trace, signal an error. */ if (errcode != 0) error (_("Failed to read branch trace.")); /* Compute the trace, provided we have any. */ if (!btrace_data_empty (&btrace)) { btrace_clear_history (btinfo); btrace_compute_ftrace (tp, &btrace); } do_cleanups (cleanup); }
void btrace_data_clear (struct btrace_data *data) { btrace_data_fini (data); btrace_data_init (data); }