This interface is used to get notifications from events in the debugger. Examples of events are when certain functions, addresses or code lines are hit.
In order to be able to get notifications for symbols, the symbol file
containing the debug information must have been added using the
debug_setup
interface or in some other way.
All notifications take callback functions that are called when the debugger event occurs. The notifications will not stop the simulation, to do so SIM_break_simulation can be called in the callback.
For all functions that return an attr_value_t
, that return value
will consists of a list with two elements. The first element is an error code
of debugger_error_t
type (see debug_query
interface documentation for definition). The second element depends on the
first. If the first element is Debugger_No_Error
, meaning that
the function went well, then the second element will contain the expected
return value that is specified per function below. If the first element is
another error code, then the second element will be a string describing the
error that occurred.
notify_context_creation provides a callback when a new context that matches the context query query is created or renamed. The callback will also be triggered when a context is renamed, so if the context query matches both the name before and after the context was renamed then there will be two creation callbacks for the same context. When the callback is triggered because of a rename the updated argument of the callback will be true, otherwise if it is triggered because a new context was created the updated argument will be false.
notify_context_destruction provides a callback when a context that matches the context query query is destroyed.
The callbacks for notify_context_creation and notify_context_destruction will contain an ID to the context that was created, updated or destroyed, ctx_id, the tcf_agent object obj and some custom data.
notify_address will provide a callback when an address is hit with a certain access type for contexts matching query. The size argument specifies the width of the breakpoint for the notification, with a maximum value of 0x7fffffff. The notification can be set to notify on physical breakpoints instead of virtual, but for that to work a processor or memory space context must be covered by the query. For process related contexts physical should be false.
notify_line will provide a callback when a specific line and column in a specific source file for a context matching query is executed. The column argument can be set to 0 to not care about column.
The notification functions notify_location, notify_address and notify_line will all provide callbacks on the same format. They will pass the context ID, ctx_id, for which the access occurred. A processor, cpu, which did the access is provided. The instruction_address is the address of the instruction that performed the access. For execution callbacks the callback will occur before the instruction has run, but for read or write accesses the callback will occur after the instruction has run. The data_address will provide which data address was accesses, for execution accesses this is the same as instruction_address but for read or write accesses this is where the actual access was. And size specifies the actual size of the access that was made to trigger the notification, for execution this size is 1.
notify_activated and notify_deactivated are used to notify when a context, that matches the query, gets activated or deactivated. The callback for this will include which context, ctx_id, was (de)activated and on what processor, cpu.
For all notifications functions in this interface, on success, the returned value of a notification function will be a cancel ID which can be used to cancel the notification.
If several callbacks occur on the same cycle, then the order for which the callbacks are called is not determined. This means that a notify_activated callback for one processor can occur before a notify_deactivated callback on the same processor.
notify_callbacks_done will be called once all other callbacks that happen because of the same event are done. For example when a move to and a move from is done in the same step then this callback can be used to keep grouped notifications together that occurred at the same time. This will always be called after one or more callbacks have been called.
cancel is used to cancel a notification by providing it with a cancel ID, cid, that was returned from the notification function. When this goes well the returned value will be nil.
Errors specific to this function:
All callbacks except notify_location, notify_address, and notify_line, with execution access, will occur after the instruction triggering the callbacks has executed. For the callbacks specified here, when using execution access, the callback will occur before the instruction at that location, address or line has executed.
"*"
. A bad context query will
result in a Debugger_Incorrect_Context_Query
error.SIM_INTERFACE(debug_notification) { attr_value_t (*notify_context_creation)( conf_object_t *NOTNULL obj, const char *query, void (*cb)(cbdata_call_t data, conf_object_t *obj, const char *ctx_id, bool updated), cbdata_register_t data); attr_value_t (*notify_context_destruction)( conf_object_t *NOTNULL obj, const char *query, void (*cb)(cbdata_call_t data, conf_object_t *obj, const char *ctx_id), cbdata_register_t data); attr_value_t (*notify_location)( conf_object_t *NOTNULL obj, const char *query, const char *NOTNULL location, unsigned size, access_t access, void (*cb)(cbdata_call_t data, conf_object_t *obj, const char *ctx_id, conf_object_t *cpu, uint64 instruction_address, uint64 data_address, unsigned size), cbdata_register_t data); attr_value_t (*notify_address)( conf_object_t *NOTNULL obj, const char *query, uint64 address, unsigned size, access_t access, bool physical, void (*cb)(cbdata_call_t data, conf_object_t *obj, const char *ctx_id, conf_object_t *cpu, uint64 instruction_address, uint64 data_address, unsigned size), cbdata_register_t data); attr_value_t (*notify_line)( conf_object_t *NOTNULL obj, const char *query, const char *NOTNULL file, unsigned line, unsigned column, void (*cb)(cbdata_call_t data, conf_object_t *obj, const char *ctx_id, conf_object_t *cpu, uint64 instruction_address, uint64 data_address, unsigned size), cbdata_register_t data); attr_value_t (*notify_activated)( conf_object_t *NOTNULL obj, const char *query, void (*cb)(cbdata_call_t data, conf_object_t *obj, const char *ctx_id, conf_object_t *cpu), cbdata_register_t data); attr_value_t (*notify_deactivated)( conf_object_t *NOTNULL obj, const char *query, void (*cb)(cbdata_call_t data, conf_object_t *obj, const char *ctx_id, conf_object_t *cpu), cbdata_register_t data); attr_value_t (*notify_callbacks_done)( conf_object_t *NOTNULL obj, void (*cb)(cbdata_call_t data, conf_object_t *obj), cbdata_register_t data); attr_value_t (*cancel)(conf_object_t *NOTNULL obj, debug_cancel_id_t cid); }; #define DEBUG_NOTIFICATION_INTERFACE "debug_notification"