/******************************************************************************* * Copyright (c) 2007, 2015 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v1.0 which accompany this distribution. * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * You may elect to redistribute this code under either of these licenses. * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ /* * This module implements Breakpoints service. * The service maintains a list of breakpoints. * Each breakpoint consists of one or more conditions that determine * when a program's execution should be interrupted. */ #ifndef D_breakpoints #define D_breakpoints #include #include typedef struct BreakpointInfo BreakpointInfo; typedef struct BreakpointAttribute BreakpointAttribute; struct BreakpointAttribute { BreakpointAttribute * next; char * name; /* Attribute name */ char * value; /* Attribute value as JSON string */ }; #if SERVICE_Breakpoints /* * Breakpoint attribute names. * Clients may define additional attributes. */ #define BREAKPOINT_ID "ID" #define BREAKPOINT_ENABLED "Enabled" #define BREAKPOINT_TYPE "BreakpointType" #define BREAKPOINT_CONTEXTNAMES "ContextNames" #define BREAKPOINT_CONTEXTIDS "ContextIds" #define BREAKPOINT_EXECUTABLEPATHS "ExecPaths" #define BREAKPOINT_LOCATION "Location" #define BREAKPOINT_SIZE "Size" #define BREAKPOINT_ACCESSMODE "AccessMode" #define BREAKPOINT_FILE "File" #define BREAKPOINT_LINE "Line" #define BREAKPOINT_COLUMN "Column" #define BREAKPOINT_PATTERN "MaskValue" #define BREAKPOINT_MASK "Mask" #define BREAKPOINT_STOP_GROUP "StopGroup" #define BREAKPOINT_IGNORECOUNT "IgnoreCount" #define BREAKPOINT_TIME "Time" #define BREAKPOINT_SCALE "TimeScale" #define BREAKPOINT_UNITS "TimeUnits" #define BREAKPOINT_CONDITION "Condition" #define BREAKPOINT_TEMPORARY "Temporary" #define BREAKPOINT_EVENT_TYPE "EventType" #define BREAKPOINT_EVENT_ARGS "EventArgs" #define BREAKPOINT_CLIENT_DATA "ClientData" #define BREAKPOINT_CONTEXT_QUERY "ContextQuery" #define BREAKPOINT_SERVICE "Service" #define BREAKPOINT_SKIP_PROLOGUE "SkipPrologue" #define BREAKPOINT_LINE_OFFSET "LineOffset" /* Breakpoints event listener */ typedef struct BreakpointsEventListener { void (*breakpoint_created)(BreakpointInfo *, void *); void (*breakpoint_changed)(BreakpointInfo *, void *); void (*breakpoint_deleted)(BreakpointInfo *, void *); void (*breakpoint_status_changed)(BreakpointInfo *, void *); } BreakpointsEventListener; /* * Add a listener for Breakpoints service events. */ extern void add_breakpoint_event_listener(BreakpointsEventListener * listener, void * args); /* * Remove a listener of Breakpoints service events. */ extern void rem_breakpoint_event_listener(BreakpointsEventListener * listener); /* * Iterate all breakpoints known to the Breakpoints service, * including breakpoints that are created by other (remote) clients. */ typedef void IterateBreakpointsCallBack(BreakpointInfo *, void *); extern void iterate_breakpoints(IterateBreakpointsCallBack * callback, void * args); /* * Get breakpoint attributes. */ extern BreakpointAttribute * get_breakpoint_attributes(BreakpointInfo * bp); /* * Create new breakpoint with given attributes. * Attributes must include, at least, BREAKPOINT_ID. * If a breakpoint with such ID already exists, it will be modified to match * new attributes instead of creating a new one. * Caller should allocate attributes using myalloc.h functions. * Breakpoints service will free attributes memory using loc_free(). */ extern BreakpointInfo * create_breakpoint(BreakpointAttribute * attrs); /* * Change breakpoint attributes to given attributes. * Caller should allocate attributes using myalloc.h functions. * Breakpoints service will free attributes memory using loc_free(). * The function compares existing attributes with new ones, * and calls listeners only if attributes are different. */ extern void change_breakpoint_attributes(BreakpointInfo * bp, BreakpointAttribute * attrs); /* * Return breakpoint status information as a JSON string. * Clients should dispose the string using loc_free(). */ extern char * get_breakpoint_status(BreakpointInfo * bp); /* * Delete a breakpoint. * If other (remote) client also created a breakpoint with same ID, * the breakpoint will be deleted when both clients have requested it to be deleted. */ extern void delete_breakpoint(BreakpointInfo * bp); /* * Iterate all breakpoints that are linked to context breakpoint 'cb' in the breakpoint address space * associated with executable context 'ctx'. Breakpoint address space is the context returned by * context_get_group(ctx, CONTEXT_GROUP_BREAKPOINT). * Single 'cb' can be linked to multiple breakpoints if those breakpoint locations are evaluated * to same address in same address space. Single breakpoint can be linked to multiple CBs if the * breakpoint scope spawns multiple address spaces. */ typedef void IterateCBLinksCallBack(BreakpointInfo *, void *); extern void iterate_context_breakpoint_links(Context * ctx, ContextBreakpoint * cb, IterateCBLinksCallBack * callback, void * args); /* * The function is called by Run Control service every time a context is stopped by a breakpoint. * The function evaluates breakpoint condition and calls suspend_debug_context() if the condition is true. */ extern void evaluate_breakpoint(Context * ctx); /* * When a context is stopped by breakpoint, it is necessary to disable * the breakpoint temporarily before the context can be resumed. * This function function removes break instruction, then does single step * over breakpoint location, then restores break instruction. * Return 0 if it is OK to resume context from current state, * return 1 if context needs to step over a breakpoint. */ extern int skip_breakpoint(Context * ctx, int single_step); /* * Return 1 if the context is stepping over a software breakpoint, * Return 0 otherwise. */ extern int is_skipping_breakpoint(Context * ctx); /* Return 1 if break instruction is planted at given address in the context memory */ extern int is_breakpoint_address(Context * ctx, ContextAddress address); /* Clone all planted breakpoints when a process forks */ extern void clone_breakpoints_on_process_fork(Context * parent, Context * child); /* Invalidate all planted breakpoints when a process calls exec() */ extern void invalidate_breakpoints_on_process_exec(Context * prs); /* * Unplant all breakpoints in a process (e.g. before detaching). * Return -1 and set errno if cannot remove some of the breakpoints. * Return 0 on success. */ extern int unplant_breakpoints(Context * ctx); /* * Check if memory data buffer contains planted break instructions and remove them. * Return -1 and set errno if the check cannot be done. */ extern int check_breakpoints_on_memory_read(Context * ctx, ContextAddress address, void * buf, size_t size); /* * Check if data is about to be written over planted break instructions and adjust the data and breakpoint backing storage * Return -1 and set errno if the check cannot be done. * Return 0 on success. */ extern int check_breakpoints_on_memory_write(Context * ctx, ContextAddress address, void * buf, size_t size); /* Evenpoint callback. It is called when context is suspended by eventpoint, right before "context_stopped" event */ typedef void EventPointCallBack(Context *, void *); /* Create, plant and return eventpoint. Eventpoints are breakpoints that are created by agent to control execution of debugee. * Eventpoint are not exposed through "Breakpoints" TCF service, they are handled by the agent itself. * 'attrs' are disposed by the Breakpoints service using loc_free(). */ extern BreakpointInfo * create_eventpoint(const char * location, Context * ctx, EventPointCallBack * callback, void * callback_args); extern BreakpointInfo * create_eventpoint_ext(BreakpointAttribute * attrs, Context * ctx, EventPointCallBack * callback, void * callback_args); /* Unplant and destroy eventpoint */ extern void destroy_eventpoint(BreakpointInfo * eventpoint); extern void ini_breakpoints_service(Protocol *, TCFBroadcastGroup *); #else /* SERVICE_Breakpoints */ #define skip_breakpoint(ctx, single_step) 0 #define is_breakpoint_address(ctx, address) 0 #define clone_breakpoints_on_process_fork(parent, child) 0 #define unplant_breakpoints(ctx) 0 #define check_breakpoints_on_memory_read(ctx, address, buf, size) 0 #define check_breakpoints_on_memory_write(ctx, address, buf, size) 0 #define create_eventpoint(location, ctx, callback, callback_args) 0 #endif /* SERVICE_Breakpoints */ #endif /* D_breakpoints */