- kill Bad nodes from the keep-alive list: these arise from the new
[libfirm] / ir / debug / debugger.c
index cc9acde..91bfc23 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
+ * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
  *
  * This file is part of libFirm.
  *
 #include "config.h"
 #endif
 
+#include "firm_config.h"
+
 #ifdef DEBUG_libfirm
 
 #ifdef _WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 
-#define strncasecmp strnicmp
 #endif
 
 #ifdef HAVE_STDLIB_H
@@ -60,7 +61,9 @@
 #include "entity_t.h"
 #include "irprintf.h"
 #include "irdump.h"
+#include "iredges_t.h"
 #include "debug.h"
+#include "error.h"
 
 #ifdef _WIN32
 /* Break into the debugger. The Win32 way. */
@@ -433,9 +436,9 @@ static const char *reason_str(bp_reasons_t reason)
        case BP_ON_REMIRG:   return "removing IRG";
        case BP_ON_NEW_ENT:  return "entity creation";
        case BP_ON_NEW_TYPE: return "type creation";
-       default:             assert(0);
+       case BP_MAX_REASON:  break;
        }
-       return "unknown";
+       panic("unsupported reason");
 }  /* reason_str */
 
 /**
@@ -585,24 +588,24 @@ static void bp_activate(unsigned bp, int active)
  */
 static void show_commands(void) {
        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 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"
-               ".showtype nr|name      show content of the type nr or name\n"
-               ".showent nr|name       show content of the entity nr or name\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"
-               ".irgname name          prints address and graph number of a method given by its name\n"
-               ".irgldname ldname      prints address and graph number of a method given by its ldname\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 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"
+               "showtype nr|name      show content of the type nr or name\n"
+               "showent nr|name       show content of the entity nr or name\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"
+               "irgname name          prints address and graph number of a method given by its name\n"
+               "irgldname ldname      prints address and graph number of a method given by its ldname\n"
+               "help                  list all commands\n"
                );
 }  /* show_commands */
 
@@ -762,26 +765,25 @@ typedef struct find_env {
 /**
  * Type-walker: Find an entity with given number.
  */
-static void check_ent_nr(type_or_ent *tore, void *ctx) {
-       ir_entity *ent = (ir_entity *)tore;
+static void check_ent_nr(type_or_ent tore, void *ctx) {
        find_env_t *env = ctx;
 
-       if (is_entity(ent))
-               if (get_entity_nr(ent) == env->u.nr) {
-                       env->res = ent;
+       if (is_entity(tore.ent)) {
+               if (get_entity_nr(tore.ent) == env->u.nr) {
+                       env->res = tore.ent;
                }
+       }
 }  /* check_ent_nr */
 
 /**
  * Type-walker: Find an entity with given name.
  */
-static void check_ent_name(type_or_ent *tore, void *ctx) {
-       ir_entity *ent = (ir_entity *)tore;
+static void check_ent_name(type_or_ent tore, void *ctx) {
        find_env_t *env = ctx;
 
-       if (is_entity(ent))
-               if (strcmp(get_entity_name(ent), env->u.name) == 0) {
-                       env->res = ent;
+       if (is_entity(tore.ent))
+               if (strcmp(get_entity_name(tore.ent), env->u.name) == 0) {
+                       env->res = tore.ent;
                }
 }  /* check_ent_name */
 
@@ -812,11 +814,11 @@ static ir_entity *find_entity_name(const char *name) {
 /**
  * Search methods for a name.
  */
-static void show_by_name(type_or_ent *tore, void *env) {
+static void show_by_name(type_or_ent tore, void *env) {
        ident *id = (ident *)env;
 
-       if (is_entity(tore)) {
-               ir_entity *ent = (ir_entity *)tore;
+       if (is_entity(tore.ent)) {
+               ir_entity *ent = tore.ent;
 
                if (is_method_entity(ent)) {
                        if (get_entity_ident(ent) == id) {
@@ -840,11 +842,11 @@ static void show_by_name(type_or_ent *tore, void *env) {
 /**
  * Search methods for a ldname.
  */
-static void show_by_ldname(type_or_ent *tore, void *env) {
+static void show_by_ldname(type_or_ent tore, void *env) {
        ident *id = (ident *)env;
 
-       if (is_entity(tore)) {
-               ir_entity *ent = (ir_entity *)tore;
+       if (is_entity(tore.ent)) {
+               ir_entity *ent = tore.ent;
 
                if (is_method_entity(ent)) {
                        if (get_entity_ld_ident(ent) == id) {
@@ -981,32 +983,29 @@ static unsigned get_token(void) {
        } while (c != '\0' && isspace(c));
 
        lexer.tok_start = lexer.curr_pos - 1;
-       if (c == '.') {
+       if (c == '.' || isalpha(c)) {
                /* command begins here */
-               int len = 0;
+               int         len = 0;
+               const char* tok_start;
 
                do {
                        c = next_char();
                        ++len;
-               } while (isalpha(c));
+               } while (isgraph(c));
                unput();
 
-               --len;
+               tok_start = lexer.tok_start;
+               if (*tok_start == '.') {
+                       ++tok_start;
+                       --len;
+               }
                for (i = sizeof(reserved)/sizeof(reserved[0]) - 1; i >= 0; --i) {
-                       if (strncasecmp(lexer.tok_start + 1, reserved[i], len) == 0 && reserved[i][len] == '\0')
-                               break;
+                       if (strncasecmp(tok_start, reserved[i], len) == 0 && reserved[i][len] == '\0')
+                               return 256 + i;
                }
-               if (i >= 0)
-                       return 256 + i;
-               return tok_error;
-       } else if (isalpha(c)) {
-               /* identifier */
-               lexer.s = lexer.curr_pos - 1;
 
-               do {
-                       c = next_char();
-               } while (isgraph(c));
-               unput();
+               /* identifier */
+               lexer.s   = lexer.tok_start;
                lexer.len = lexer.curr_pos - lexer.s;
                return tok_identifier;
        } else if (isdigit(c) || c == '-') {
@@ -1056,9 +1055,7 @@ static unsigned get_token(void) {
 /**
  * High level function to use from debugger interface
  *
- * Supported commands:
- *  .create nr    break if node nr was created
- *  .help         list all commands
+ * See show_commands() for supported commands.
  */
 void firm_debug(const char *cmd) {
        char name[1024], fname[1024];
@@ -1297,14 +1294,41 @@ void firm_init_debugger(void)
  */
 const char *gdb_node_helper(void *firm_object) {
        static char buf[1024];
-       ir_snprintf(buf, sizeof(buf), "%+F\n", firm_object);
+       ir_snprintf(buf, sizeof(buf), "%+F", firm_object);
+       return buf;
+}
+
+/**
+ * A gdb helper function to print tarvals.
+ */
+const char *gdb_tarval_helper(void *tv_object) {
+       static char buf[1024];
+       ir_snprintf(buf, sizeof(buf), "%+T", tv_object);
+       return buf;
+}
+
+const char *gdb_out_edge_helper(const ir_node *node) {
+       static char buf[4*1024];
+       char *b = buf;
+       size_t l;
+       size_t len = sizeof(buf);
+       const ir_edge_t *edge;
+       foreach_out_edge(node, edge) {
+               ir_node *n = get_edge_src_irn(edge);
+
+               ir_snprintf(b, len, "%+F  ", n);
+               l = strlen(b);
+               len -= l;
+               b += l;
+       }
+
        return buf;
 }
 
 #else
 
 /* some picky compiler do not allow empty files */
-static int _firm_only_that_you_can_compile_with_NDEBUG_defined;
+static int __attribute__((unused)) _firm_only_that_you_can_compile_with_NDEBUG_defined;
 
 #endif /* NDEBUG */
 
@@ -1318,9 +1342,11 @@ static int _firm_only_that_you_can_compile_with_NDEBUG_defined;
  *
  * @section sec_cmd Supported commands
  *
+ * Historically all debugger commands start with a dot.  This isn't needed in newer
+ * versions, but still supported, ie the commands ".init" and "init" are equal.
  * The following commands are currently supported:
  *
- * @b .init
+ * @b init
  *
  * Break immediately after the debugger extension was initialized.
  * Typically this command is used in the environment to stop the execution
@@ -1328,92 +1354,92 @@ static int _firm_only_that_you_can_compile_with_NDEBUG_defined;
  *
  * $export FIRMDBG=".init"
  *
- * @b .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.
  *
- * @b .replace nr
+ * @b replace nr
  *
  * Break before IR-node with node number nr is replaced by another node.
  *
- * @b .lower nr
+ * @b lower nr
  *
  * Break before IR-node with node number nr is lowered.
  *
- * @b .remirg nr
+ * @b remirg nr
  *
  * Break if the irg with graph number nr is deleted.
  *
- * @b .remirg name
+ * @b remirg name
  *
  * Break if the irg of entity name is deleted.
  *
- * @b .newent nr
+ * @b newent nr
  *
  * Break if the entity with number nr was created.
  *
- * @b .newent name
+ * @b newent name
  *
  * Break if the entity name was created.
  *
- * @b .newtype nr
+ * @b newtype nr
  *
  * Break if the type with number nr was created.
  *
- * @b .newtype name
+ * @b newtype name
  *
  * Break if the type name was created.
  *
- * @b .bp
+ * @b bp
  *
  * Show all Firm internal breakpoints.
  *
- * @b .enable nr
+ * @b enable nr
  *
  * Enables breakpoint nr.
  *
- * @b .disable nr
+ * @b disable nr
  *
  * Disables breakpoint nr.
  *
- * @b .showent nr
+ * @b showent nr
  *
  * Show the content of entity nr.
  *
- * @b .showent name
+ * @b showent name
  *
  * Show the content of entity name.
  *
- * @b .showtype nr
+ * @b showtype nr
  *
  * Show the content of type nr.
  *
- * @b .showtype name
+ * @b showtype name
  *
  * Show the content of type name.
  *
- * @b .setmask name msk
+ * @b setmask name msk
  *
  * Sets the debug module name to mask msk.
  *
- * @b .setlvl name lvl
+ * @b setlvl name lvl
  *
  * Sets the debug module name to level lvl.
  *
- * @b .setoutfile name file
+ * @b setoutfile name file
  *
  * Redirects debug output of module name to file.
  *
- * @b .irgname name
+ * @b irgname name
  *
  * Prints address and graph number of a method given by its name.
  *
- * @b .irgldname name
+ * @b irgldname name
  *
  * Prints address and graph number of a method given by its linker name.
  *
- * @b .help
+ * @b help
  *
  * List all commands.
  *
@@ -1422,11 +1448,11 @@ static int _firm_only_that_you_can_compile_with_NDEBUG_defined;
  * The following example shows how to set a creation breakpoint in GDB when
  * node 2101 is created.
  *
- * -# set FIRMDBG=".init"
+ * -# set FIRMDBG="init"
  * -# start gdb with your compiler
  * -# after gdb breaks, issue
  *
- * call firm_debug(".create 2101")
+ * call firm_debug("create 2101")
  *
  * On the console the following text should be issued:
  *
@@ -1448,7 +1474,7 @@ static int _firm_only_that_you_can_compile_with_NDEBUG_defined;
  * Then, all Firm debugger extension commands can be accessed in the gdb
  * console using the firm prefix, eg.:
  *
- * firm ".create 2101"
+ * firm "create 2101"
  *
- * firm ".help"
+ * firm "help"
  */