3bca0609cda693030ade6b562d53fd37d31cb051
[libfirm] / ir / debug / debugger.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/debug/debugger.c
4  * Purpose:     Helper function for integerated debug support
5  * Author:      Michael Beck
6  * Modified by:
7  * Created:     2005
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 2001-2005 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12 #ifdef HAVE_CONFIG_H
13 #include "config.h"
14 #endif
15
16 #ifndef NDEBUG
17
18 #ifdef _WIN32
19 #define WIN32_LEAN_AND_MEAN
20 #include <windows.h>
21 #endif
22
23 #ifdef HAVE_STDLIB_H
24 #include <stdlib.h>
25 #endif
26
27 #include <stdio.h>
28 #include <signal.h>
29
30 #ifdef HAVE_STRING_H
31 #include <string.h>
32 #endif
33
34 #include <ctype.h>
35
36 #include "set.h"
37 #include "ident.h"
38 #include "irhooks.h"
39 #include "irgraph_t.h"
40 #include "entity_t.h"
41 #include "irprintf.h"
42 #include "debug.h"
43
44 #ifdef _WIN32
45 /** Break into the debugger. The Win32 way. */
46 static void firm_debug_break(void) {
47   DebugBreak();
48 }
49 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64))
50 /** Break into the debugger. The ia32/x86_64 way under GCC. */
51 static void firm_debug_break(void) {
52   __asm__ __volatile__("int3");
53 }
54 #else
55 /** Break into the debugger. Poor Unix way. */
56 static void firm_debug_break(void) {
57   raise(SIGINT);
58 }
59 #endif /* _WIN32 */
60
61 /** supported breakpoint kinds */
62 typedef enum {
63   BP_NR  = 'n',   /**< break on node number. */
64   BP_IDENT = 'i'    /**< break on ident. */
65 } bp_kind;
66
67 /**
68  * Reasons for node number breakpoints.
69  */
70 typedef enum _bp_reasons_t {
71   BP_ON_NEW_NODE,    /**< break if node with number is created */
72   BP_ON_REPLACE,     /**< break if node with number is replaced */
73   BP_ON_LOWER,       /**< break if node with number is lowered */
74   BP_ON_REMIRG,      /**< break if an IRG is removed */
75   BP_ON_NEW_ENT,     /**< break if a new entity is created */
76   BP_ON_NEW_TYPE,    /**< break if a new type is created */
77   BP_MAX_REASON
78 } bp_reasons_t;
79
80 /** A breakpoint. */
81 typedef struct _breakpoint {
82   bp_kind      kind;        /**< the kind of this break point */
83   unsigned     bpnr;        /**< break point number */
84   int          active;      /**< non-zero, if this break point is active */
85   bp_reasons_t reason;      /**< reason for the breakpoint */
86   struct _breakpoint *next; /**< link to the next one */
87 } breakpoint;
88
89 /** A number breakpoint. */
90 typedef struct {
91   breakpoint   bp;       /**< the breakpoint data */
92   long         nr;       /**< the node number */
93 } bp_nr_t;
94
95 /** calculate the hash value for a node breakpoint */
96 #define HASH_NR_BP(key) (((key).nr << 2) ^ (key).bp.reason)
97
98 /** A ident breakpoint. */
99 typedef struct {
100   breakpoint   bp;       /**< the breakpoint data */
101   ident        *id;      /**< the ident */
102 } bp_ident_t;
103
104 /** calculate the hash value for an ident breakpoint */
105 #define HASH_IDENT_BP(key) (HASH_PTR((key).id) ^ (key).bp.reason)
106
107 /** The set containing the breakpoints on node numbers. */
108 static set *bp_numbers;
109
110 /** The set containing the breakpoints on idents. */
111 static set *bp_idents;
112
113 /**< the list of all breakpoints */
114 static breakpoint *bp_list;
115
116 /** number of the current break point */
117 static unsigned bp_num = 0;
118
119 /** set if break on init command was issued. */
120 static int break_on_init = 0;
121
122 /** the hook entries for the Firm debugger module. */
123 static hook_entry_t debugger_hooks[hook_last];
124
125 /** number of active breakpoints to maintain hooks. */
126 static unsigned num_active_bp[BP_MAX_REASON];
127
128 /**
129  * The debug message buffer
130  */
131 static char firm_dbg_msg_buf[2048];
132
133 /**
134  * If set, the debug extension writes all output to the
135  * firm_dbg_msg_buf buffer
136  */
137 static int redir_output = 0;
138
139 /**
140  * Is set to one, if the debug extension is active
141  */
142 static int is_active = 0;
143
144 /** hook the hook h with function fkt. */
145 #define HOOK(h, fkt) \
146   debugger_hooks[h].hook._##h = fkt; register_hook(h, &debugger_hooks[h])
147
148 /** unhook the hook h */
149 #define UNHOOK(h)   unregister_hook(h, &debugger_hooks[h])
150
151 /** returns non-zero if a entry hook h is used */
152 #define IS_HOOKED(h) (debugger_hooks[h].next != NULL)
153
154 /* some macros needed to create the info string */
155 #define _DBG_VERSION(major, minor)  #major "." #minor
156 #define DBG_VERSION(major, minor)   _DBG_VERSION(major, minor)
157 #define API_VERSION(major, minor)   "API:" DBG_VERSION(major, minor)
158
159 /* the API version: change if needed */
160 #define FIRM_DBG_MAJOR  1
161 #define FIRM_DBG_MINOR  0
162
163 /** for automatic detection of the debug extension */
164 static const char *firm_debug_info_string =
165   API_VERSION(FIRM_DBG_MAJOR, FIRM_DBG_MINOR)
166   ;
167
168 /**
169  * Returns non-zero, if the debug extension is active
170  */
171 int firm_debug_active(void) {
172   return is_active;
173 }
174
175 /**
176  * reset the debug text buffer
177  */
178 static void reset_dbg_buf(void) {
179   firm_dbg_msg_buf[0] = '\0';
180 }
181
182 /**
183  * Add text to the debug text buffer
184  */
185 static void add_to_dbg_buf(const char *buf) {
186   strncat(firm_dbg_msg_buf, buf, sizeof(firm_dbg_msg_buf));
187 }
188
189 /**
190  * Return the content of the debug text buffer.
191  *
192  * To be called from the debugger.
193  */
194 const char *firm_debug_text(void) {
195   return firm_dbg_msg_buf;
196 }
197
198 /**
199  * debug output
200  */
201 static void dbg_printf(const char *fmt, ...)
202 {
203   char buf[1024];
204
205   va_list args;
206   va_start(args, fmt);
207
208   if (fmt[0] != '+')
209     reset_dbg_buf();
210   else
211     ++fmt;
212
213   ir_vsnprintf(buf, sizeof(buf), fmt, args);
214   va_end(args);
215
216   if (redir_output)
217     add_to_dbg_buf(buf);
218   else
219     puts(buf);
220 }
221
222 /**
223  * A new node is created.
224  *
225  * @param ctx   the hook context
226  * @param irg   the IR graph on which the node is created
227  * @param node  the new IR node that was created
228  */
229 static void dbg_new_node(void *ctx, ir_graph *irg, ir_node *node)
230 {
231   bp_nr_t key, *elem;
232
233   key.nr        = get_irn_node_nr(node);
234   key.bp.reason = BP_ON_NEW_NODE;
235
236   elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
237   if (elem && elem->bp.active) {
238     dbg_printf("Firm BP %u reached, %+F created\n", elem->bp.bpnr, node);
239     firm_debug_break();
240   }
241 }
242
243 /**
244  * A node is replaced.
245  *
246  * @param ctx   the hook context
247  * @param old   the IR node the is replaced
248  * @param nw    the new IR node that will replace old
249  */
250 static void dbg_replace(void *ctx, ir_node *old, ir_node *nw)
251 {
252   bp_nr_t key, *elem;
253
254   key.nr        = get_irn_node_nr(old);
255   key.bp.reason = BP_ON_REPLACE;
256
257   elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
258   if (elem && elem->bp.active) {
259     dbg_printf("Firm BP %u reached, %+F will be replaced by %+F\n", elem->bp.bpnr, old, nw);
260     firm_debug_break();
261   }
262 }
263
264 /**
265  * A new node is lowered.
266  *
267  * @param ctx   the hook context
268  * @param node  the new IR node that will be lowered
269  */
270 static void dbg_lower(void *ctx, ir_node *node)
271 {
272   bp_nr_t key, *elem;
273
274   key.nr        = get_irn_node_nr(node);
275   key.bp.reason = BP_ON_LOWER;
276
277   elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
278   if (elem && elem->bp.active) {
279     dbg_printf("Firm BP %u reached, %+F will be lowered\n", elem->bp.bpnr, node);
280     firm_debug_break();
281   }
282 }
283
284 /**
285  * A graph will be deleted.
286  *
287  * @param ctx   the hook context
288  * @param irg   the IR graph that will be deleted
289  */
290 static void dbg_free_graph(void *ctx, ir_graph *irg)
291 {
292   {
293     bp_nr_t key, *elem;
294     key.nr        = get_irg_graph_nr(irg);
295     key.bp.reason = BP_ON_REMIRG;
296
297     elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
298     if (elem && elem->bp.active) {
299       ir_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, irg);
300       firm_debug_break();
301     }
302   }
303   {
304     bp_ident_t key, *elem;
305     entity *ent = get_irg_entity(irg);
306
307     if (! ent)
308       return;
309
310     key.id        = get_entity_ident(ent);
311     key.bp.reason = BP_ON_REMIRG;
312
313     elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
314     if (elem && elem->bp.active) {
315       dbg_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, ent);
316       firm_debug_break();
317     }
318   }
319 }
320
321 /**
322  * An entity was created.
323  *
324  * @param ctx   the hook context
325  * @param ent   the newly created entity
326  */
327 static void dbg_new_entity(void *ctx, entity *ent)
328 {
329   {
330     bp_ident_t key, *elem;
331
332     key.id        = get_entity_ident(ent);
333     key.bp.reason = BP_ON_NEW_ENT;
334
335     elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
336     if (elem && elem->bp.active) {
337       ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
338       firm_debug_break();
339     }
340   }
341   {
342     bp_nr_t key, *elem;
343
344     key.nr        = get_entity_nr(ent);
345     key.bp.reason = BP_ON_NEW_ENT;
346
347     elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
348     if (elem && elem->bp.active) {
349       dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
350       firm_debug_break();
351     }
352   }
353 }
354
355 /**
356  * A type was created.
357  *
358  * @param ctx   the hook context
359  * @param tp    the newly created type
360  */
361 static void dbg_new_type(void *ctx, ir_type *tp)
362 {
363   {
364     bp_nr_t key, *elem;
365
366     key.nr        = get_type_nr(tp);
367     key.bp.reason = BP_ON_NEW_TYPE;
368
369     elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
370     if (elem && elem->bp.active) {
371       ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
372       firm_debug_break();
373     }
374   }
375   {
376     bp_ident_t key, *elem;
377
378     key.id        = get_type_ident(tp);
379     key.bp.reason = BP_ON_NEW_TYPE;
380
381     elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
382     if (elem && elem->bp.active) {
383       dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
384       firm_debug_break();
385     }
386   }
387 }
388
389 /**
390  * return the reason string.
391  */
392 static const char *reason_str(bp_reasons_t reason)
393 {
394   switch (reason) {
395   case BP_ON_NEW_NODE: return "node creation";
396   case BP_ON_REPLACE:  return "node replace";
397   case BP_ON_LOWER:    return "node lowering";
398   case BP_ON_REMIRG:   return "removing IRG";
399   case BP_ON_NEW_ENT:  return "entity creation";
400   case BP_ON_NEW_TYPE: return "type creation";
401   default:             assert(0);
402   }
403   return "unknown";
404 }
405
406 /**
407  * Compare two number breakpoints
408  */
409 static int cmp_nr_bp(const void *elt, const void *key, size_t size)
410 {
411   const bp_nr_t *e1 = elt;
412   const bp_nr_t *e2 = key;
413
414   return (e1->nr - e2->nr) | (e1->bp.reason - e2->bp.reason);
415 }
416
417 /**
418  * Compare two ident breakpoints
419  */
420 static int cmp_ident_bp(const void *elt, const void *key, size_t size)
421 {
422   const bp_ident_t *e1 = elt;
423   const bp_ident_t *e2 = key;
424
425   return (e1->id != e2->id) | (e1->bp.reason - e2->bp.reason);
426 }
427
428 /**
429  * update the hooks
430  */
431 static void update_hooks(breakpoint *bp)
432 {
433 #define CASE_ON(a, b)  case a: if (! IS_HOOKED(hook_##b)) HOOK(hook_##b, dbg_##b); break
434 #define CASE_OFF(a, b) case a: if (IS_HOOKED(hook_##b)) UNHOOK(hook_##b); break
435
436   if (bp->active)
437     ++num_active_bp[bp->reason];
438   else
439     --num_active_bp[bp->reason];
440
441   if (num_active_bp[bp->reason] > 0) {
442     /* register the hooks on demand */
443     switch (bp->reason) {
444     CASE_ON(BP_ON_NEW_NODE, new_node);
445     CASE_ON(BP_ON_REPLACE, replace);
446     CASE_ON(BP_ON_LOWER, lower);
447     CASE_ON(BP_ON_REMIRG, free_graph);
448     CASE_ON(BP_ON_NEW_ENT, new_entity);
449     CASE_ON(BP_ON_NEW_TYPE, new_type);
450     default:
451       ;
452     }
453   }
454   else {
455     /* unregister the hook on demand */
456     switch (bp->reason) {
457     CASE_OFF(BP_ON_NEW_NODE, new_node);
458     CASE_OFF(BP_ON_REPLACE, replace);
459     CASE_OFF(BP_ON_LOWER, lower);
460     CASE_OFF(BP_ON_REMIRG, free_graph);
461     CASE_OFF(BP_ON_NEW_ENT, new_entity);
462     CASE_OFF(BP_ON_NEW_TYPE, new_type);
463     default:
464       ;
465     }
466   }
467 #undef CASE_ON
468 #undef CASE_OFF
469 }
470
471 /**
472  * Break if nr is reached.
473  */
474 static void break_on_nr(long nr, bp_reasons_t reason)
475 {
476   bp_nr_t key, *elem;
477
478   key.bp.kind   = BP_NR;
479   key.bp.bpnr   = 0;
480   key.bp.active = 1;
481   key.bp.reason = reason;
482   key.nr        = nr;
483
484   elem = set_insert(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
485
486   if (elem->bp.bpnr == 0) {
487     /* new break point */
488     elem->bp.bpnr = ++bp_num;
489     elem->bp.next = bp_list;
490     bp_list = &elem->bp;
491
492     dbg_printf("Firm BP %u: %s of Nr %ld\n", elem->bp.bpnr, reason_str(reason), nr);
493
494     update_hooks(&elem->bp);
495   }
496 }
497
498 /**
499  * Break if ident name is reached.
500  */
501 static void break_on_ident(const char *name, bp_reasons_t reason) {
502   bp_ident_t key, *elem;
503
504   key.bp.kind   = BP_IDENT;
505   key.bp.bpnr   = 0;
506   key.bp.active = 1;
507   key.bp.reason = reason;
508   key.id        = new_id_from_str(name);
509
510   elem = set_insert(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
511
512   if (elem->bp.bpnr == 0) {
513     /* new break point */
514     elem->bp.bpnr = ++bp_num;
515     elem->bp.next = bp_list;
516     bp_list = &elem->bp;
517
518     dbg_printf("Firm BP %u: %s of ident \"%s\"\n", elem->bp.bpnr, reason_str(reason), name);
519
520     update_hooks(&elem->bp);
521   }
522 }
523
524 /**
525  * Sets/resets the active flag of breakpoint bp.
526  */
527 static void bp_activate(unsigned bp, int active)
528 {
529   breakpoint *p;
530
531   for (p = bp_list; p; p = p->next) {
532     if (p->bpnr == bp) {
533       if (p->active != active) {
534         p->active = active;
535         update_hooks(p);
536       }
537
538       dbg_printf("Firm BP %u is now %s\n", bp, active ? "enabled" : "disabled");
539       return;
540     }
541   }
542   dbg_printf("Error: Firm BP %u not exists.\n", bp);
543 }
544
545
546 /**
547  * Show a list of supported commands
548  */
549 static void show_commands(void) {
550   dbg_printf("Internal Firm debugger extension $Revision$ commands:\n"
551     ".init                  break after initialization\n"
552     ".create nr             break if node nr was created\n"
553     ".replace nr            break if node nr is replaced by another node\n"
554     ".lower nr              break before node nr is lowered\n"
555     ".remirg nr|name        break if the irg of nr or entity name is deleted\n"
556     ".newent nr|name        break if the entity nr or name was created\n"
557     ".newtype nr|name       break if the type nr or name was created\n"
558     ".bp                    show all breakpoints\n"
559     ".enable nr             enable breakpoint nr\n"
560     ".disable nr            disable breakpoint nr\n"
561     ".setmask name lvl      sets the debug module name to level lvl\n"
562     ".setoutfile name file  redirects debug output of module name to file\n"
563     ".help                  list all commands\n"
564   );
565 }
566
567 /**
568  * Shows all Firm breakpoints.
569  */
570 static void show_bp(void) {
571   breakpoint *p;
572   bp_nr_t  *node_p;
573   bp_ident_t *ident_p;
574   int have_one = 0;
575
576   dbg_printf("Firm Breakpoints:");
577   for (p = bp_list; p; p = p->next) {
578     have_one = 1;
579     dbg_printf("+\n  BP %u: ", p->bpnr);
580
581     switch (p->kind) {
582     case BP_NR:
583       node_p = (bp_nr_t *)p;
584       dbg_printf("%s of Nr %ld ", reason_str(p->reason), node_p->nr);
585       break;
586
587     case BP_IDENT:
588       ident_p = (bp_ident_t *)p;
589       dbg_printf("+%s of ident \"%s\" ", reason_str(p->reason), get_id_str(ident_p->id));
590       break;
591     }
592
593     dbg_printf(p->active ? "+enabled" : "+disabled");
594   }
595   dbg_printf(have_one ? "+\n" : "+ NONE\n");
596 }
597
598 /**
599  * firm_dbg_register() expects that the name is stored persistent.
600  * So we need this little helper function
601  */
602 static firm_dbg_module_t *dbg_register(const char *name) {
603   ident *id = new_id_from_str(name);
604
605   return firm_dbg_register(get_id_str(id));
606 }
607
608 /**
609  * Sets the debug mask of module name to lvl
610  */
611 static void set_dbg_level(const char *name, unsigned lvl)
612 {
613   firm_dbg_module_t *module = dbg_register(name);
614
615   firm_dbg_set_mask(module, lvl);
616
617   dbg_printf("Setting debug mask of module %s to %u\n", name, lvl);
618 }
619
620 /**
621  * Redirects the debug output of module name to fname
622  */
623 static void set_dbg_outfile(const char *name, const char *fname)
624 {
625   firm_dbg_module_t *module = dbg_register(name);
626   FILE *f = fopen(fname, "w");
627
628   if (! f) {
629     perror(fname);
630     return;
631   }
632
633   firm_dbg_set_file(module, f);
634   dbg_printf("Redirecting debug output of module %s to file %s\n", name, fname);
635 }
636
637 /**
638  * High level function to use from debugger interface
639  *
640  * Supported commands:
641  *  .create nr    break if node nr was created
642  *  .help         list all commands
643  */
644 void firm_debug(const char *cmd) {
645   long nr;
646   unsigned bp;
647   char name[1024], fname[1024];
648   unsigned lvl;
649
650   while (isspace(*cmd)) ++cmd;
651
652   if (sscanf(cmd, ".create %ld\n", &nr) == 1) {
653     break_on_nr(nr, BP_ON_NEW_NODE);
654   }
655   else if (sscanf(cmd, ".replace %ld\n", &nr) == 1) {
656     break_on_nr(nr, BP_ON_REPLACE);
657   }
658   else if (sscanf(cmd, ".lower %ld\n", &nr) == 1) {
659     break_on_nr(nr, BP_ON_LOWER);
660   }
661   else if (sscanf(cmd, ".remirg %ld\n", &nr) == 1) {
662     break_on_nr(nr, BP_ON_REMIRG);
663   }
664   else if (sscanf(cmd, ".remirg %s\n", name) == 1) {
665     break_on_ident(name, BP_ON_REMIRG);
666   }
667   else if (sscanf(cmd, ".newent %ld\n", &nr) == 1) {
668     break_on_nr(nr, BP_ON_NEW_ENT);
669   }
670   else if (sscanf(cmd, ".newent %s\n", name) == 1) {
671     break_on_ident(name, BP_ON_NEW_ENT);
672   }
673   else if (sscanf(cmd, ".newtype %ld\n", &nr) == 1) {
674     break_on_nr(nr, BP_ON_NEW_TYPE);
675   }
676   else if (sscanf(cmd, ".newtype %s\n", name) == 1) {
677     break_on_ident(name, BP_ON_NEW_TYPE);
678   }
679   else if (strcmp(cmd, ".init") == 0)
680     break_on_init = 1;
681   else if (strcmp(cmd, ".bp") == 0)
682     show_bp();
683   else if (sscanf(cmd, ".enable %u", &bp) == 1)
684     bp_activate(bp, 1);
685   else if (sscanf(cmd, ".disable %u", &bp) == 1)
686     bp_activate(bp, 0);
687   else if (sscanf(cmd, ".setmask %s %u\n", name, &lvl) == 2)
688     set_dbg_level(name, lvl);
689   else if (sscanf(cmd, ".setoutfile %s %s\n", name, fname) == 2)
690     set_dbg_outfile(name, fname);
691   else {
692     show_commands();
693   }
694 }
695
696 /* creates the debugger tables */
697 void firm_init_debugger(void)
698 {
699   char *env;
700
701   bp_numbers = new_set(cmp_nr_bp, 8);
702   bp_idents       = new_set(cmp_ident_bp, 8);
703
704   env = getenv("FIRMDBG");
705
706   is_active = 1;
707
708   if (env)
709     firm_debug(env);
710
711   if (break_on_init)
712     firm_debug_break();
713 }
714
715 #else
716
717 /* some picky compiler do not allow empty files */
718 static int _firm_only_that_you_can_compile_with_NDEBUG_defined;
719
720 #endif /* NDEBUG */
721
722 /**
723  * @page debugger   The Firm debugger extension
724  *
725  * Firm contains a debugger extension. This allows to set debugger breakpoints
726  * an various events.
727  * The extension uses a text interface which can be accessed from most debuggers.
728  *
729  * @section sec_cmd Supported commands
730  *
731  * The following commands are currently supported:
732  * @b .init
733  *
734  * Break immediately after the debugger extension was initialized.
735  * Typically this command is used in the environment to stop the execution
736  * of a Firm compiler right after the initialization, like this:
737  *
738  * $export FIRMDBG=".init"
739  *
740  *
741  * @b .create nr
742  *
743  * Break if a new IR-node with node number nr was created.
744  * Typically used to find the place where wrong nodes are created.
745  *
746  * @b .replace nr
747  *
748  * Break before IR-node with node number nr is replaced by another node.
749  *
750  * @b .lower nr
751  *
752  * Break before IR-node with node number nr is lowered.
753  *
754  * @b .remirg nr
755  *
756  * Break if the irg with graph number nr is deleted.
757  *
758  * @b .remirg name
759  *
760  * Break if the irg of entity name is deleted.
761  *
762  * @b .newent nr
763  *
764  * Break if the entity with number nr was created.
765  *
766  * @b .newent name
767  *
768  * Break if the entity name was created.
769  *
770  * @b .newtype nr
771  *
772  * Break if the type with number nr was created.
773  *
774  * @b .newtype name
775  *
776  * Break if the type name was created.
777  *
778  * @b .bp
779  *
780  * Show all Firm internal breakpoints.
781  *
782  * @b .enable nr
783  *
784  * Enables breakpoint nr.
785  *
786  * @b .disable nr
787  *
788  * Disables breakpoint nr.
789  *
790  * @b .setmask name lvl
791  *
792  * Sets the debug module name to level lvl.
793  *
794  * @b .setoutfile name file
795  *
796  * Redirects debug output of module name to file.
797  *
798  * @b .help
799  *
800  * List all commands.
801  *
802  *
803  * The Firm debugger extension can be accessed using the function firm_debug().
804  * The following example shows how to set a creation breakpoint in GDB when
805  * node 2101 is created.
806  *
807  * -# set FIRMDBG=".init"
808  * -# start gdb with your compiler
809  * -# after gdb breaks, issue
810  *
811  * p firm_debug(".create 2101")
812  *
813  * On the console the following text should be issued:
814  *
815  * Firm BP 1: creation of Node 2101
816  *
817  *
818  * @section gdb_macro GDB macro
819  *
820  * Add the following to your .gdbinit file:
821  * @code
822  #
823  # define firm "cmd"  Firm debugger extension
824  #
825  define firm
826  p firm_debug($arg0)
827  end
828  * @endcode
829  *
830  * Then, all Firm debugger extension commands can be access in the gdb
831  * console using the firm prefix, eg.:
832  *
833  * firm ".create 2101"
834  * firm ".help"
835  */
836
837 #ifdef __GNUC__
838 static void _firm_only_that_you_can_compile_with_NDEBUG_defined(void) __attribute__((unused));
839 #endif
840
841 static void _firm_only_that_you_can_compile_with_NDEBUG_defined(void)
842 {
843 }