doxygen docu added
[libfirm] / ir / debug / debugger.c
index bcdc386..9d84c95 100644 (file)
 #include "debug.h"
 
 #ifdef _WIN32
-/** Break into the debugger. The Win32 way. */
-static void firm_debug_break(void) {
+/* Break into the debugger. The Win32 way. */
+void firm_debug_break(void) {
   DebugBreak();
 }
 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64))
-/** Break into the debugger. The ia32/x86_64 way under GCC. */
-static void firm_debug_break(void) {
+/* Break into the debugger. The ia32/x86_64 way under GCC. */
+void firm_debug_break(void) {
   __asm__ __volatile__("int3");
 }
 #else
-/** Break into the debugger. Poor Unix way. */
-static void firm_debug_break(void) {
+/* Break into the debugger. Poor Unix way. */
+void firm_debug_break(void) {
   raise(SIGINT);
 }
 #endif /* _WIN32 */
 
 /** supported breakpoint kinds */
 typedef enum {
-  BP_NODE  = 'n',   /**< break on node number. */
+  BP_NR  = 'n',   /**< break on node number. */
   BP_IDENT = 'i'    /**< break on ident. */
 } bp_kind;
 
@@ -86,14 +86,14 @@ typedef struct _breakpoint {
   struct _breakpoint *next; /**< link to the next one */
 } breakpoint;
 
-/** A node number breakpoint. */
+/** A number breakpoint. */
 typedef struct {
   breakpoint   bp;       /**< the breakpoint data */
   long         nr;       /**< the node number */
-} bp_node_t;
+} bp_nr_t;
 
 /** calculate the hash value for a node breakpoint */
-#define HASH_NODE_BP(key) (((key).nr << 2) ^ (key).bp.reason)
+#define HASH_NR_BP(key) (((key).nr << 2) ^ (key).bp.reason)
 
 /** A ident breakpoint. */
 typedef struct {
@@ -105,7 +105,7 @@ typedef struct {
 #define HASH_IDENT_BP(key) (HASH_PTR((key).id) ^ (key).bp.reason)
 
 /** The set containing the breakpoints on node numbers. */
-static set *bp_node_numbers;
+static set *bp_numbers;
 
 /** The set containing the breakpoints on idents. */
 static set *bp_idents;
@@ -125,15 +125,106 @@ static hook_entry_t debugger_hooks[hook_last];
 /** number of active breakpoints to maintain hooks. */
 static unsigned num_active_bp[BP_MAX_REASON];
 
+/**
+ * The debug message buffer
+ */
+static char firm_dbg_msg_buf[2048];
+
+/**
+ * If set, the debug extension writes all output to the
+ * firm_dbg_msg_buf buffer
+ */
+static int redir_output = 0;
+
+/**
+ * Is set to one, if the debug extension is active
+ */
+static int is_active = 0;
+
 /** hook the hook h with function fkt. */
 #define HOOK(h, fkt) \
-  debugger_hooks[h].hook._##h = fkt; register_hook(h, &debugger_hooks[h])
+do {                                    \
+  debugger_hooks[h].hook._##h = fkt;    \
+  register_hook(h, &debugger_hooks[h]); \
+} while(0)
 
 /** unhook the hook h */
-#define UNHOOK(h)   unregister_hook(h, &debugger_hooks[h])
+#define UNHOOK(h) \
+do {                                      \
+  unregister_hook(h, &debugger_hooks[h]); \
+  debugger_hooks[h].hook._##h = NULL;     \
+} while(0)
 
 /** returns non-zero if a entry hook h is used */
-#define IS_HOOKED(h) (debugger_hooks[h].next != NULL)
+#define IS_HOOKED(h) (debugger_hooks[h].hook._##h != NULL)
+
+/* some macros needed to create the info string */
+#define _DBG_VERSION(major, minor)  #major "." #minor
+#define DBG_VERSION(major, minor)   _DBG_VERSION(major, minor)
+#define API_VERSION(major, minor)   "API:" DBG_VERSION(major, minor)
+
+/* the API version: change if needed */
+#define FIRM_DBG_MAJOR  1
+#define FIRM_DBG_MINOR  0
+
+/** for automatic detection of the debug extension */
+static const char *firm_debug_info_string =
+  API_VERSION(FIRM_DBG_MAJOR, FIRM_DBG_MINOR)
+  ;
+
+/**
+ * Returns non-zero, if the debug extension is active
+ */
+int firm_debug_active(void) {
+  return is_active;
+}
+
+/**
+ * reset the debug text buffer
+ */
+static void reset_dbg_buf(void) {
+  firm_dbg_msg_buf[0] = '\0';
+}
+
+/**
+ * Add text to the debug text buffer
+ */
+static void add_to_dbg_buf(const char *buf) {
+  strncat(firm_dbg_msg_buf, buf, sizeof(firm_dbg_msg_buf));
+}
+
+/**
+ * Return the content of the debug text buffer.
+ *
+ * To be called from the debugger.
+ */
+const char *firm_debug_text(void) {
+  return firm_dbg_msg_buf;
+}
+
+/**
+ * debug output
+ */
+static void dbg_printf(const char *fmt, ...)
+{
+  char buf[1024];
+
+  va_list args;
+  va_start(args, fmt);
+
+  if (fmt[0] != '+')
+    reset_dbg_buf();
+  else
+    ++fmt;
+
+  ir_vsnprintf(buf, sizeof(buf), fmt, args);
+  va_end(args);
+
+  if (redir_output)
+    add_to_dbg_buf(buf);
+  else
+    puts(buf);
+}
 
 /**
  * A new node is created.
@@ -144,14 +235,14 @@ static unsigned num_active_bp[BP_MAX_REASON];
  */
 static void dbg_new_node(void *ctx, ir_graph *irg, ir_node *node)
 {
-  bp_node_t key, *elem;
+  bp_nr_t key, *elem;
 
   key.nr        = get_irn_node_nr(node);
   key.bp.reason = BP_ON_NEW_NODE;
 
-  elem = set_find(bp_node_numbers, &key, sizeof(key), HASH_NODE_BP(key));
+  elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
   if (elem && elem->bp.active) {
-    ir_printf("Firm BP %u reached, %+F created\n", elem->bp.bpnr, node);
+    dbg_printf("Firm BP %u reached, %+F created\n", elem->bp.bpnr, node);
     firm_debug_break();
   }
 }
@@ -165,14 +256,14 @@ static void dbg_new_node(void *ctx, ir_graph *irg, ir_node *node)
  */
 static void dbg_replace(void *ctx, ir_node *old, ir_node *nw)
 {
-  bp_node_t key, *elem;
+  bp_nr_t key, *elem;
 
   key.nr        = get_irn_node_nr(old);
   key.bp.reason = BP_ON_REPLACE;
 
-  elem = set_find(bp_node_numbers, &key, sizeof(key), HASH_NODE_BP(key));
+  elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
   if (elem && elem->bp.active) {
-    ir_printf("Firm BP %u reached, %+F will be replaced by %+F\n", elem->bp.bpnr, old, nw);
+    dbg_printf("Firm BP %u reached, %+F will be replaced by %+F\n", elem->bp.bpnr, old, nw);
     firm_debug_break();
   }
 }
@@ -185,14 +276,14 @@ static void dbg_replace(void *ctx, ir_node *old, ir_node *nw)
  */
 static void dbg_lower(void *ctx, ir_node *node)
 {
-  bp_node_t key, *elem;
+  bp_nr_t key, *elem;
 
   key.nr        = get_irn_node_nr(node);
   key.bp.reason = BP_ON_LOWER;
 
-  elem = set_find(bp_node_numbers, &key, sizeof(key), HASH_NODE_BP(key));
+  elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
   if (elem && elem->bp.active) {
-    ir_printf("Firm BP %u reached, %+F will be lowered\n", elem->bp.bpnr, node);
+    dbg_printf("Firm BP %u reached, %+F will be lowered\n", elem->bp.bpnr, node);
     firm_debug_break();
   }
 }
@@ -205,19 +296,32 @@ static void dbg_lower(void *ctx, ir_node *node)
  */
 static void dbg_free_graph(void *ctx, ir_graph *irg)
 {
-  bp_ident_t key, *elem;
-  entity *ent = get_irg_entity(irg);
+  {
+    bp_nr_t key, *elem;
+    key.nr        = get_irg_graph_nr(irg);
+    key.bp.reason = BP_ON_REMIRG;
+
+    elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
+    if (elem && elem->bp.active) {
+      ir_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, irg);
+      firm_debug_break();
+    }
+  }
+  {
+    bp_ident_t key, *elem;
+    entity *ent = get_irg_entity(irg);
 
-  if (! ent)
-    return;
+    if (! ent)
+      return;
 
-  key.id        = get_entity_ident(ent);
-  key.bp.reason = BP_ON_REMIRG;
+    key.id        = get_entity_ident(ent);
+    key.bp.reason = BP_ON_REMIRG;
 
-  elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
-  if (elem && elem->bp.active) {
-    ir_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, ent);
-    firm_debug_break();
+    elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
+    if (elem && elem->bp.active) {
+      dbg_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, ent);
+      firm_debug_break();
+    }
   }
 }
 
@@ -229,15 +333,29 @@ static void dbg_free_graph(void *ctx, ir_graph *irg)
  */
 static void dbg_new_entity(void *ctx, entity *ent)
 {
-  bp_ident_t key, *elem;
+  {
+    bp_ident_t key, *elem;
 
-  key.id        = get_entity_ident(ent);
-  key.bp.reason = BP_ON_NEW_ENT;
+    key.id        = get_entity_ident(ent);
+    key.bp.reason = BP_ON_NEW_ENT;
 
-  elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
-  if (elem && elem->bp.active) {
-    ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
-    firm_debug_break();
+    elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
+    if (elem && elem->bp.active) {
+      ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
+      firm_debug_break();
+    }
+  }
+  {
+    bp_nr_t key, *elem;
+
+    key.nr        = get_entity_nr(ent);
+    key.bp.reason = BP_ON_NEW_ENT;
+
+    elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
+    if (elem && elem->bp.active) {
+      dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
+      firm_debug_break();
+    }
   }
 }
 
@@ -247,17 +365,31 @@ static void dbg_new_entity(void *ctx, entity *ent)
  * @param ctx   the hook context
  * @param tp    the newly created type
  */
-static void dbg_new_type(void *ctx, type *tp)
+static void dbg_new_type(void *ctx, ir_type *tp)
 {
-  bp_ident_t key, *elem;
+  {
+    bp_nr_t key, *elem;
 
-  key.id        = get_type_ident(tp);
-  key.bp.reason = BP_ON_NEW_TYPE;
+    key.nr        = get_type_nr(tp);
+    key.bp.reason = BP_ON_NEW_TYPE;
 
-  elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
-  if (elem && elem->bp.active) {
-    ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
-    firm_debug_break();
+    elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
+    if (elem && elem->bp.active) {
+      ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
+      firm_debug_break();
+    }
+  }
+  {
+    bp_ident_t key, *elem;
+
+    key.id        = get_type_ident(tp);
+    key.bp.reason = BP_ON_NEW_TYPE;
+
+    elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
+    if (elem && elem->bp.active) {
+      dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
+      firm_debug_break();
+    }
   }
 }
 
@@ -279,12 +411,12 @@ static const char *reason_str(bp_reasons_t reason)
 }
 
 /**
- * Compare two node number breakpoints
+ * Compare two number breakpoints
  */
-static int cmp_node_bp(const void *elt, const void *key, size_t size)
+static int cmp_nr_bp(const void *elt, const void *key, size_t size)
 {
-  const bp_node_t *e1 = elt;
-  const bp_node_t *e2 = key;
+  const bp_nr_t *e1 = elt;
+  const bp_nr_t *e2 = key;
 
   return (e1->nr - e2->nr) | (e1->bp.reason - e2->bp.reason);
 }
@@ -344,19 +476,19 @@ static void update_hooks(breakpoint *bp)
 }
 
 /**
- * Break if node nr is reached.
+ * Break if nr is reached.
  */
-static void break_on_node(long nr, bp_reasons_t reason)
+static void break_on_nr(long nr, bp_reasons_t reason)
 {
-  bp_node_t key, *elem;
+  bp_nr_t key, *elem;
 
-  key.bp.kind   = BP_NODE;
+  key.bp.kind   = BP_NR;
   key.bp.bpnr   = 0;
   key.bp.active = 1;
   key.bp.reason = reason;
   key.nr        = nr;
 
-  elem = set_insert(bp_node_numbers, &key, sizeof(key), HASH_NODE_BP(key));
+  elem = set_insert(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
 
   if (elem->bp.bpnr == 0) {
     /* new break point */
@@ -364,7 +496,7 @@ static void break_on_node(long nr, bp_reasons_t reason)
     elem->bp.next = bp_list;
     bp_list = &elem->bp;
 
-    printf("Firm BP %u: %s of Node %ld\n", elem->bp.bpnr, reason_str(reason), nr);
+    dbg_printf("Firm BP %u: %s of Nr %ld\n", elem->bp.bpnr, reason_str(reason), nr);
 
     update_hooks(&elem->bp);
   }
@@ -390,7 +522,7 @@ static void break_on_ident(const char *name, bp_reasons_t reason) {
     elem->bp.next = bp_list;
     bp_list = &elem->bp;
 
-    printf("Firm BP %u: %s of ident \"%s\"\n", elem->bp.bpnr, reason_str(reason), name);
+    dbg_printf("Firm BP %u: %s of ident \"%s\"\n", elem->bp.bpnr, reason_str(reason), name);
 
     update_hooks(&elem->bp);
   }
@@ -410,11 +542,11 @@ static void bp_activate(unsigned bp, int active)
         update_hooks(p);
       }
 
-      printf("Firm BP %u is now %s\n", bp, active ? "enabled" : "disabled");
+      dbg_printf("Firm BP %u is now %s\n", bp, active ? "enabled" : "disabled");
       return;
     }
   }
-  printf("Error: Firm BP %u not exists.\n", bp);
+  dbg_printf("Error: Firm BP %u not exists.\n", bp);
 }
 
 
@@ -422,18 +554,19 @@ static void bp_activate(unsigned bp, int active)
  * Show a list of supported commands
  */
 static void show_commands(void) {
-  printf("Internal Firm debugger extension $Revision$ commands:\n"
+  dbg_printf("Internal Firm debugger extension $Revision$ commands:\n"
     ".init                  break after initialization\n"
     ".create nr             break if node nr was created\n"
     ".replace nr            break if node nr is replaced by another node\n"
     ".lower nr              break before node nr is lowered\n"
-    ".remirg name           break if the irg of entity name is deleted\n"
-    ".newent name           break if the entity name was created\n"
-    ".newtype name          break if the type name was created\n"
+    ".remirg nr|name        break if the irg of nr or entity name is deleted\n"
+    ".newent nr|name        break if the entity nr or name was created\n"
+    ".newtype nr|name       break if the type nr or name was created\n"
     ".bp                    show all breakpoints\n"
     ".enable nr             enable breakpoint nr\n"
     ".disable nr            disable breakpoint nr\n"
-    ".setmask name lvl      sets the debug module name to level lvl\n"
+    ".setmask name msk      sets the debug module name to mask msk\n"
+    ".setlvl  name lvl      sets the debug module name to level lvl\n"
     ".setoutfile name file  redirects debug output of module name to file\n"
     ".help                  list all commands\n"
   );
@@ -444,26 +577,40 @@ static void show_commands(void) {
  */
 static void show_bp(void) {
   breakpoint *p;
-  bp_node_t  *node_p;
+  bp_nr_t  *node_p;
   bp_ident_t *ident_p;
+  int have_one = 0;
 
+  dbg_printf("Firm Breakpoints:");
   for (p = bp_list; p; p = p->next) {
-    printf("Firm BP %u: ", p->bpnr);
+    have_one = 1;
+    dbg_printf("+\n  BP %u: ", p->bpnr);
 
     switch (p->kind) {
-    case BP_NODE:
-      node_p = (bp_node_t *)p;
-      printf("%s of node %ld ", reason_str(p->reason), node_p->nr);
+    case BP_NR:
+      node_p = (bp_nr_t *)p;
+      dbg_printf("%s of Nr %ld ", reason_str(p->reason), node_p->nr);
       break;
 
     case BP_IDENT:
       ident_p = (bp_ident_t *)p;
-      printf("%s of ident \"%s\" ", reason_str(p->reason), get_id_str(ident_p->id));
+      dbg_printf("+%s of ident \"%s\" ", reason_str(p->reason), get_id_str(ident_p->id));
       break;
     }
 
-    printf(p->active ? "enabled\n" : "disabled\n");
+    dbg_printf(p->active ? "+enabled" : "+disabled");
   }
+  dbg_printf(have_one ? "+\n" : "+ NONE\n");
+}
+
+/**
+ * firm_dbg_register() expects that the name is stored persistent.
+ * So we need this little helper function
+ */
+static firm_dbg_module_t *dbg_register(const char *name) {
+  ident *id = new_id_from_str(name);
+
+  return firm_dbg_register(get_id_str(id));
 }
 
 /**
@@ -471,11 +618,11 @@ static void show_bp(void) {
  */
 static void set_dbg_level(const char *name, unsigned lvl)
 {
-  firm_dbg_module_t *module = firm_dbg_register(name);
+  firm_dbg_module_t *module = dbg_register(name);
 
   firm_dbg_set_mask(module, lvl);
 
-  printf("Setting debug mask of module %s to %u\n", name, lvl);
+  dbg_printf("Setting debug mask of module %s to %u\n", name, lvl);
 }
 
 /**
@@ -483,7 +630,7 @@ static void set_dbg_level(const char *name, unsigned lvl)
  */
 static void set_dbg_outfile(const char *name, const char *fname)
 {
-  firm_dbg_module_t *module = firm_dbg_register(name);
+  firm_dbg_module_t *module = dbg_register(name);
   FILE *f = fopen(fname, "w");
 
   if (! f) {
@@ -492,7 +639,7 @@ static void set_dbg_outfile(const char *name, const char *fname)
   }
 
   firm_dbg_set_file(module, f);
-  printf("Redirecting debug output of module %s to file %s\n", name, fname);
+  dbg_printf("Redirecting debug output of module %s to file %s\n", name, fname);
 }
 
 /**
@@ -502,7 +649,7 @@ static void set_dbg_outfile(const char *name, const char *fname)
  *  .create nr    break if node nr was created
  *  .help         list all commands
  */
-void firm_break(const char *cmd) {
+void firm_debug(const char *cmd) {
   long nr;
   unsigned bp;
   char name[1024], fname[1024];
@@ -511,20 +658,29 @@ void firm_break(const char *cmd) {
   while (isspace(*cmd)) ++cmd;
 
   if (sscanf(cmd, ".create %ld\n", &nr) == 1) {
-    break_on_node(nr, BP_ON_NEW_NODE);
+    break_on_nr(nr, BP_ON_NEW_NODE);
   }
   else if (sscanf(cmd, ".replace %ld\n", &nr) == 1) {
-    break_on_node(nr, BP_ON_REPLACE);
+    break_on_nr(nr, BP_ON_REPLACE);
   }
   else if (sscanf(cmd, ".lower %ld\n", &nr) == 1) {
-    break_on_node(nr, BP_ON_LOWER);
+    break_on_nr(nr, BP_ON_LOWER);
+  }
+  else if (sscanf(cmd, ".remirg %ld\n", &nr) == 1) {
+    break_on_nr(nr, BP_ON_REMIRG);
   }
   else if (sscanf(cmd, ".remirg %s\n", name) == 1) {
     break_on_ident(name, BP_ON_REMIRG);
   }
+  else if (sscanf(cmd, ".newent %ld\n", &nr) == 1) {
+    break_on_nr(nr, BP_ON_NEW_ENT);
+  }
   else if (sscanf(cmd, ".newent %s\n", name) == 1) {
     break_on_ident(name, BP_ON_NEW_ENT);
   }
+  else if (sscanf(cmd, ".newtype %ld\n", &nr) == 1) {
+    break_on_nr(nr, BP_ON_NEW_TYPE);
+  }
   else if (sscanf(cmd, ".newtype %s\n", name) == 1) {
     break_on_ident(name, BP_ON_NEW_TYPE);
   }
@@ -538,6 +694,8 @@ void firm_break(const char *cmd) {
     bp_activate(bp, 0);
   else if (sscanf(cmd, ".setmask %s %u\n", name, &lvl) == 2)
     set_dbg_level(name, lvl);
+  else if (sscanf(cmd, ".setlvl %s %u\n", name, &lvl) == 2)
+    set_dbg_level(name, (1 << lvl) - 1);
   else if (sscanf(cmd, ".setoutfile %s %s\n", name, fname) == 2)
     set_dbg_outfile(name, fname);
   else {
@@ -550,18 +708,25 @@ void firm_init_debugger(void)
 {
   char *env;
 
-  bp_node_numbers = new_set(cmp_node_bp, 8);
-  bp_idents       = new_set(cmp_ident_bp, 8);
+  bp_numbers = new_set(cmp_nr_bp, 8);
+  bp_idents  = new_set(cmp_ident_bp, 8);
 
   env = getenv("FIRMDBG");
 
+  is_active = 1;
+
   if (env)
-    firm_break(env);
+    firm_debug(env);
 
   if (break_on_init)
     firm_debug_break();
 }
 
+#else
+
+/* some picky compiler do not allow empty files */
+static int _firm_only_that_you_can_compile_with_NDEBUG_defined;
+
 #endif /* NDEBUG */
 
 /**
@@ -569,12 +734,11 @@ void firm_init_debugger(void)
  *
  * Firm contains a debugger extension. This allows to set debugger breakpoints
  * an various events.
- * The extension uses a text interface which can be access in the debugger.
+ * The extension uses a text interface which can be accessed from most debuggers.
  *
  * @section sec_cmd Supported commands
  *
  * The following commands are currently supported:
- *
  * @b .init
  *
  * Break immediately after the debugger extension was initialized.
@@ -597,14 +761,26 @@ void firm_init_debugger(void)
  *
  * Break before IR-node with node number nr is lowered.
  *
+ * @b .remirg nr
+ *
+ * Break if the irg with graph number nr is deleted.
+ *
  * @b .remirg name
  *
  * Break if the irg of entity name is deleted.
  *
+ * @b .newent nr
+ *
+ * Break if the entity with number nr was created.
+ *
  * @b .newent name
  *
  * Break if the entity name was created.
  *
+ * @b .newtype nr
+ *
+ * Break if the type with number nr was created.
+ *
  * @b .newtype name
  *
  * Break if the type name was created.
@@ -621,20 +797,24 @@ void firm_init_debugger(void)
  *
  * Disables breakpoint nr.
  *
- * @b .setmask name lvl
+ * @b .setmask name msk
+ *
+ * Sets the debug module name to mask msk.
+ *
+ * @b .setlvl name lvl
  *
  * Sets the debug module name to level lvl.
  *
  * @b .setoutfile name file
  *
- * Redirects debug output of module name to file\.
+ * Redirects debug output of module name to file.
  *
  * @b .help
  *
  * List all commands.
  *
  *
- * The Firm debugger extension can be accessed using the function firm_break().
+ * The Firm debugger extension can be accessed using the function firm_debug().
  * The following example shows how to set a creation breakpoint in GDB when
  * node 2101 is created.
  *
@@ -657,7 +837,7 @@ void firm_init_debugger(void)
  # define firm "cmd"  Firm debugger extension
  #
  define firm
- p firm_break($arg0)
+ p firm_debug($arg0)
  end
  * @endcode
  *