3 * File name: ir/debug/debugger.c
4 * Purpose: Helper function for integerated debug support
9 * Copyright: (c) 2001-2005 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
19 #define WIN32_LEAN_AND_MEAN
37 /** Break into the debugger */
38 static void firm_debug_break(void) {
44 /** Break into the debugger */
45 static void firm_debug_break(void) {
51 /** supported breakpoint kinds */
53 BP_CREATION = 0 /**< break on creation. */
57 typedef struct _breakpoint {
58 bp_kind kind; /**< the kind of this break point */
59 unsigned bpnr; /**< break point number */
60 int active; /**< non-zero, if this break point is active */
61 struct _breakpoint *next; /**< link to the next one */
64 /** A creation breakpoint. */
66 breakpoint bp; /**< the breakpoint data */
67 long nr; /**< the node number */
70 /** The set containing the creation breakpoints. */
71 static set *bp_creations;
73 /**< the list of all breakpoints */
74 static breakpoint *bp_list;
76 /** number of the current break point */
77 static unsigned bp_num = 0;
79 /** set if break on init command was issued. */
80 static int break_on_init = 0;
83 * Compare two creation breakpoints
85 static int cmp_create_bp(const void *elt, const void *key, size_t size)
87 const bp_create_t *e1 = elt;
88 const bp_create_t *e2 = key;
90 return e1->nr - e2->nr;
94 * Break if node nr is created.
96 static void break_on_creation(long nr)
98 bp_create_t key, *elem;
100 key.bp.kind = BP_CREATION;
105 elem = set_insert(bp_creations, &key, sizeof(key), nr);
107 if (elem->bp.bpnr == 0) {
108 /* new break point */
109 elem->bp.bpnr = ++bp_num;
110 elem->bp.next = bp_list;
113 printf("Firm BP %u: creation of Node %ld\n", elem->bp.bpnr, nr);
118 * Sets/resets the active flag of breakpoint bp.
120 static void bp_activate(unsigned bp, int active)
124 for (p = bp_list; p; p = p->next) {
128 printf("Firm BP %u is now %s\n", bp, active ? "enabled" : "disabled");
132 printf("Error: Firm BP %u not exists.\n", bp);
137 * Show a list of supported commands
139 static void show_commands(void) {
140 printf("Internal Firm debugger extension commands:\n"
141 ".init break after initialization\n"
142 ".create nr break if node nr was created\n"
143 ".bp show all breakpoints\n"
144 ".enable nr enable breakpoint nr\n"
145 ".disable nr disable breakpoint nr\n"
146 ".help list all commands\n"
151 * Shows all Firm breakpoints.
153 static void show_bp(void) {
156 for (p = bp_list; p; p = p->next) {
157 printf("Firm BP %u ", p->bpnr);
161 printf("creation of node %ld ", ((bp_create_t *)p)->nr);
165 printf(p->active ? "enabled\n" : "disabled\n");
170 * High level function to use from debugger interface
172 * Supported commands:
173 * .create nr break if node nr was created
174 * .help list all commands
176 void firm_break(const char *cmd) {
180 while (isspace(*cmd)) ++cmd;
182 if (sscanf(cmd, ".create %ld\n", &nr) == 1) {
183 break_on_creation(nr);
185 else if (strcmp(cmd, ".init") == 0)
187 else if (strcmp(cmd, ".bp") == 0)
189 else if (sscanf(cmd, ".enable %u", &bp) == 1)
191 else if (sscanf(cmd, ".disable %u", &bp) == 1)
198 /** the hook entries for the Firm debugger module */
199 static hook_entry_t debugger_hooks[hook_last];
202 * A new node is created.
204 * @param ctx the hook context
205 * @param irg the IR graph on which the node is created
206 * @param node the new IR node that was created
208 static void dbg_new_node(void *ctx, ir_graph *irg, ir_node *node)
210 bp_create_t key, *elem;
212 key.nr = get_irn_node_nr(node);
214 elem = set_find(bp_creations, &key, sizeof(key), key.nr);
215 if (elem && elem->bp.active) {
216 ir_printf("Firm BP %u reached, %+F created\n", elem->bp.bpnr, node);
221 #define HOOK(h, fkt) \
222 debugger_hooks[h].hook._##h = fkt; register_hook(h, &debugger_hooks[h])
224 /* creates the debugger tables */
225 void firm_init_debugger(void)
229 bp_creations = new_set(cmp_create_bp, 8);
231 /* register the hooks */
232 HOOK(hook_new_node, dbg_new_node);
234 env = getenv("FIRMDBG");
246 * @page debugger The Firm debugger extension.
248 * Firm contains a debugger extension. This allows to set debugger breakpoints
250 * The extension uses a text interface which can be access in the debugger.
252 * The following commands are currently supported:
256 * Break immediately after the debugger extension was initialized.
257 * Typically this command is used in the environment to stop the execution
258 * of a Firm compiler right after the initialization, like this:
260 * $export FIRMDBG=".init"
265 * Break if a new IR-node with node number nr was created.
266 * Typically used to find the place where wrong nodes are created.
270 * Show all Firm internal breakpoints.
274 * Enables breakpoint nr.
278 * Disables breakpoint nr.
285 * The Firm debugger extension is access using the function firm_break().
286 * The following example shows how to set a creating breakpoint in GDB when
287 * node 2101 is created.
289 * 1.) set FRIMDBG=".init"
290 * 2.) start gdb with your compiler
291 * 3.) after gdb breaks, issue
293 * p firm_debug(".create 2101")
295 * On the console the following text should be issued:
297 * Firm BP 1: creation of Node 2101