*/
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"
);
}
}
}
+/**
+ * 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
*
* .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;
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();
}
env = getenv("FIRMDBG");
if (env)
- firm_break(env);
+ firm_debug(env);
if (break_on_init)
firm_debug_break();
#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
* $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"
*/