firm_seqno_enter_id() added, to speed up ident calculation
[libfirm] / ir / debug / debugger.c
index 4429767..3ecba2a 100644 (file)
@@ -423,18 +423,19 @@ static void bp_activate(unsigned bp, int active)
  */
 static void show_commands(void) {
   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"
-    ".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"
-    ".help              list all 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"
+    ".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"
+    ".setoutfile name file  redirects debug output of module name to file\n"
+    ".help                  list all commands\n"
   );
 }
 
@@ -465,18 +466,45 @@ static void show_bp(void) {
   }
 }
 
+/**
+ * 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));
+}
+
 /**
  * Sets the debug mask of module name to lvl
  */
 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);
 }
 
+/**
+ * Redirects the debug output of module name to fname
+ */
+static void set_dbg_outfile(const char *name, const char *fname)
+{
+  firm_dbg_module_t *module = dbg_register(name);
+  FILE *f = fopen(fname, "w");
+
+  if (! f) {
+    perror(fname);
+    return;
+  }
+
+  firm_dbg_set_file(module, f);
+  printf("Redirecting debug output of module %s to file %s\n", name, fname);
+}
+
 /**
  * High level function to use from debugger interface
  *
@@ -484,10 +512,10 @@ static void set_dbg_level(const char *name, unsigned lvl)
  *  .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];
+  char name[1024], fname[1024];
   unsigned lvl;
 
   while (isspace(*cmd)) ++cmd;
@@ -520,6 +548,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, ".setoutfile %s %s\n", name, fname) == 2)
+    set_dbg_outfile(name, fname);
   else {
     show_commands();
   }
@@ -536,7 +566,7 @@ void firm_init_debugger(void)
   env = getenv("FIRMDBG");
 
   if (env)
-    firm_break(env);
+    firm_debug(env);
 
   if (break_on_init)
     firm_debug_break();
@@ -545,15 +575,17 @@ void firm_init_debugger(void)
 #endif /* NDEBUG */
 
 /**
- * @page debugger   The Firm debugger extension.
+ * @page debugger   The Firm debugger extension
  *
  * 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:
  *
- * .init
+ * @b .init
  *
  * Break immediately after the debugger extension was initialized.
  * Typically this command is used in the environment to stop the execution
@@ -562,63 +594,86 @@ void firm_init_debugger(void)
  * $export FIRMDBG=".init"
  *
  *
- * .create nr
+ * @b .create nr
  *
  * Break if a new IR-node with node number nr was created.
  * Typically used to find the place where wrong nodes are created.
  *
- * .replace nr
+ * @b .replace nr
  *
  * Break before IR-node with node number nr is replaced by another node.
  *
- * .lower nr
+ * @b .lower nr
  *
  * Break before IR-node with node number nr is lowered.
  *
- * .remirg name
+ * @b .remirg name
  *
  * Break if the irg of entity name is deleted.
  *
- * .newent name
+ * @b .newent name
  *
  * Break if the entity name was created.
  *
- * .newtype name
+ * @b .newtype name
  *
  * Break if the type name was created.
  *
- * .bp
+ * @b .bp
  *
  * Show all Firm internal breakpoints.
  *
- * .enable nr
+ * @b .enable nr
  *
  * Enables breakpoint nr.
  *
- * .disable nr
+ * @b .disable nr
  *
  * Disables breakpoint nr.
  *
- * .setmask name lvl
+ * @b .setmask name lvl
  *
  * Sets the debug module name to level lvl.
  *
- * .help
+ * @b .setoutfile name 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.
  *
- * 1.) set FIRMDBG=".init"
- * 2.) start gdb with your compiler
- * 3.) after gdb breaks, issue
+ * -# set FIRMDBG=".init"
+ * -# start gdb with your compiler
+ * -# after gdb breaks, issue
  *
  * p firm_debug(".create 2101")
  *
  * On the console the following text should be issued:
  *
  * Firm BP 1: creation of Node 2101
+ *
+ *
+ * @section gdb_macro GDB macro
+ *
+ * Add the following to your .gdbinit file:
+ * @code
+ #
+ # define firm "cmd"  Firm debugger extension
+ #
+ define firm
+ p firm_debug($arg0)
+ end
+ * @endcode
+ *
+ * Then, all Firm debugger extension commands can be access in the gdb
+ * console using the firm prefix, eg.:
+ *
+ * firm ".create 2101"
+ * firm ".help"
  */