pub unsafe extern "C" fn dr_register_trace_event(
func: Option<unsafe extern "C" fn(drcontext: *mut c_void, tag: *mut c_void, trace: *mut instrlist_t, translating: bool_) -> dr_emit_flags_t>,
)Expand description
Registers a callback function for the trace event. DR calls \p func before inserting a new trace into the code cache. DR may call \p func again if it needs to translate from code cache addresses back to application addresses, which happens on faulting instructions as well as in certain situations involving suspended threads or forcibly relocated threads. The \p translating parameter distinguishes the two types of calls and behaves identically to the same parameter in the basic block callback: see #dr_register_bb_event() for further details.
Traces are not built if the -disable_traces runtime option is specified.
- \p drcontext is a pointer to the input program’s machine context. Clients should not inspect or modify the context; it is provided as an opaque pointer (i.e., void *) to be passed to API routines that require access to this internal data.
- \p tag is a unique identifier for the trace fragment.
- \p trace is a pointer to the list of instructions that comprise the trace.
- \p translating indicates whether this callback is for trace creation (false) or is for fault address recreation (true). This is further explained below.
The callback function should return a #dr_emit_flags_t flag.
The user is free to inspect and modify the non-control-flow instructions in the trace before it executes, with certain restrictions that include those for basic blocks (see dr_register_bb_event()). Additional restrictions unique to traces also apply:
- The sequence of blocks composing the trace cannot be changed once the trace is created. Instead, modify the component blocks by changing the block continuation addresses in the basic block callbacks (called with \p for_trace set to true) as the trace is being built.
- The (application) control flow instruction (if any) terminating each component block cannot be changed.
- Application control flow instructions cannot be added.
- The parameter to a system call, normally kept in the eax register, cannot be changed.
- A system call or interrupt instruction cannot be added.
- If both a floating-point state save instruction (fnstenv, fnsave, fxsave, xsave, or xsaveopt) and a prior regular floating-point instruction are present, the regular instruction cannot be removed.
If hitting a size limit due to extensive instrumentation, reduce the -max_trace_bbs option to start with a smaller trace.
The basic block restrictions on modifying application source code apply to traces as well. If the user wishes to change which basic blocks comprise the trace, either the #dr_register_end_trace_event() should be used or the \p for_trace basic block callbacks should modify their continuation addresses via direct jumps.
All of the comments for #dr_register_bb_event() regarding transparent fault handling and state translation apply to the trace callback as well. Please read those comments carefully.
\note As each basic block is added to a new trace, the basic block callback (see #dr_register_bb_event()) is called with its \p for_trace parameter set to true. In order to preserve basic block instrumentation inside of traces, a client need only act identically with respect to the \p for_trace parameter; it can ignore the trace event if its goal is to place instrumentation on all code.
\note Certain control flow modifications applied to a basic block can prevent it from becoming part of a trace: e.g., adding additional application control transfers.
\note If multiple clients are present, the instruction list for a trace passed to earlier-registered clients will contain the instrumentation and modifications put in place by later-registered clients; similarly for each constituent basic block.
\note Traces can be deleted due to hitting capacity limits or cache consistency events (when the source application code of a trace is modified). In that case, the client will see a new trace callback if a new trace containing that code is created again after deletion. The deletion event (#dr_register_delete_event()) will be raised at deletion time.