2 * Copyright (C) 1995-2010 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief Helper function for integrated debug support
23 * @author Michael Beck
31 #define WIN32_LEAN_AND_MEAN
49 #include "irgraph_t.h"
53 #include "iredges_t.h"
59 /* Break into the debugger. The Win32 way. */
60 void firm_debug_break(void)
64 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64))
65 /* Break into the debugger. The ia32/x86_64 way under GCC. */
66 void firm_debug_break(void)
68 __asm__ __volatile__("int3");
71 /* Break into the debugger. Poor Unix way. */
72 void firm_debug_break(void)
78 /** supported breakpoint kinds */
80 BP_NR = 'n', /**< break on node number. */
81 BP_IDENT = 'i' /**< break on ident. */
85 * Reasons for node number breakpoints.
87 typedef enum bp_reasons_t {
88 BP_ON_NEW_THING, /**< break if node, entity or type with number is created */
89 BP_ON_REPLACE, /**< break if node with number is replaced */
90 BP_ON_LOWER, /**< break if node with number is lowered */
91 BP_ON_REMIRG, /**< break if an IRG is removed */
92 BP_ON_NEW_ENT, /**< break if a new entity is created */
97 typedef struct breakpoint {
98 bp_kind kind; /**< the kind of this break point */
99 unsigned bpnr; /**< break point number */
100 int active; /**< non-zero, if this break point is active */
101 bp_reasons_t reason; /**< reason for the breakpoint */
102 struct breakpoint *next; /**< link to the next one */
105 /** A number breakpoint. */
107 breakpoint bp; /**< the breakpoint data */
108 long nr; /**< the node number */
111 /** Calculate the hash value for a node breakpoint. */
112 #define HASH_NR_BP(key) (((key).nr << 2) ^ (key).bp.reason)
114 /** An ident breakpoint. */
116 breakpoint bp; /**< the breakpoint data */
117 ident *id; /**< the ident */
120 /** Calculate the hash value for an ident breakpoint. */
121 #define HASH_IDENT_BP(key) (hash_ptr((key).id) ^ (key).bp.reason)
123 /** The set containing the breakpoints on node numbers. */
124 static set *bp_numbers;
126 /** The set containing the breakpoints on idents. */
127 static set *bp_idents;
129 /**< the list of all breakpoints */
130 static breakpoint *bp_list;
132 /** number of the current break point */
133 static unsigned bp_num = 0;
135 /** set if break on init command was issued. */
136 static int break_on_init = 0;
138 /** the hook entries for the Firm debugger module. */
139 static hook_entry_t debugger_hooks[hook_last];
141 /** number of active breakpoints to maintain hooks. */
142 static unsigned num_active_bp[BP_MAX_REASON];
145 * The debug message buffer
147 static char firm_dbg_msg_buf[2048];
150 * If set, the debug extension writes all output to the
151 * firm_dbg_msg_buf buffer
153 static int redir_output = 0;
156 * Is set to one, if the debug extension is active
158 static int is_active = 0;
160 /** hook the hook h with function fkt. */
161 #define HOOK(h, fkt) \
163 debugger_hooks[h].hook._##h = fkt; \
164 register_hook(h, &debugger_hooks[h]); \
167 /** unhook the hook h */
170 unregister_hook(h, &debugger_hooks[h]); \
171 debugger_hooks[h].hook._##h = NULL; \
174 /** returns non-zero if a entry hook h is used */
175 #define IS_HOOKED(h) (debugger_hooks[h].hook._##h != NULL)
177 /* some macros needed to create the info string */
178 #define _DBG_VERSION(major, minor) #major "." #minor
179 #define DBG_VERSION(major, minor) _DBG_VERSION(major, minor)
180 #define API_VERSION(major, minor) "API:" DBG_VERSION(major, minor)
182 /* the API version: change if needed */
183 #define FIRM_DBG_MAJOR 1
184 #define FIRM_DBG_MINOR 0
186 /** for automatic detection of the debug extension */
187 static const char __attribute__((used)) firm_debug_info_string[] =
188 API_VERSION(FIRM_DBG_MAJOR, FIRM_DBG_MINOR);
190 int firm_debug_active(void)
196 * Reset the debug text buffer.
198 static void reset_dbg_buf(void)
200 firm_dbg_msg_buf[0] = '\0';
203 const char *firm_debug_text(void)
205 firm_dbg_msg_buf[sizeof(firm_dbg_msg_buf) - 1] = '\0';
206 return firm_dbg_msg_buf;
212 static void dbg_printf(const char *fmt, ...)
222 size_t const cur = strlen(firm_dbg_msg_buf);
223 ir_vsnprintf(firm_dbg_msg_buf + cur, sizeof(firm_dbg_msg_buf) - cur, fmt, args);
225 ir_vprintf(fmt, args);
231 * A new node is created.
233 * @param ctx the hook context
234 * @param irg the IR graph on which the node is created
235 * @param node the new IR node that was created
237 static void dbg_new_node(void *ctx, ir_graph *irg, ir_node *node)
243 key.nr = get_irn_node_nr(node);
244 key.bp.reason = BP_ON_NEW_THING;
246 elem = set_find(bp_nr_t, bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
247 if (elem && elem->bp.active) {
248 dbg_printf("Firm BP %u reached, %+F created\n", elem->bp.bpnr, node);
254 * A node is replaced.
256 * @param ctx the hook context
257 * @param old the IR node the is replaced
258 * @param nw the new IR node that will replace old
260 static void dbg_replace(void *ctx, ir_node *old, ir_node *nw)
265 key.nr = get_irn_node_nr(old);
266 key.bp.reason = BP_ON_REPLACE;
268 elem = set_find(bp_nr_t, bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
269 if (elem && elem->bp.active) {
270 dbg_printf("Firm BP %u reached, %+F will be replaced by %+F\n", elem->bp.bpnr, old, nw);
276 * A new node is lowered.
278 * @param ctx the hook context
279 * @param node the new IR node that will be lowered
281 static void dbg_lower(void *ctx, ir_node *node)
286 key.nr = get_irn_node_nr(node);
287 key.bp.reason = BP_ON_LOWER;
289 elem = set_find(bp_nr_t, bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
290 if (elem && elem->bp.active) {
291 dbg_printf("Firm BP %u reached, %+F will be lowered\n", elem->bp.bpnr, node);
297 * A graph will be deleted.
299 * @param ctx the hook context
300 * @param irg the IR graph that will be deleted
302 static void dbg_free_graph(void *ctx, ir_graph *irg)
307 key.nr = get_irg_graph_nr(irg);
308 key.bp.reason = BP_ON_REMIRG;
310 elem = set_find(bp_nr_t, bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
311 if (elem && elem->bp.active) {
312 ir_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, irg);
317 bp_ident_t key, *elem;
318 ir_entity *ent = get_irg_entity(irg);
323 key.id = get_entity_ident(ent);
324 key.bp.reason = BP_ON_REMIRG;
326 elem = set_find(bp_ident_t, bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
327 if (elem && elem->bp.active) {
328 dbg_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, ent);
335 * An entity was created.
337 * @param ctx the hook context
338 * @param ent the newly created entity
340 static void dbg_new_entity(void *ctx, ir_entity *ent)
344 bp_ident_t key, *elem;
346 key.id = get_entity_ident(ent);
347 key.bp.reason = BP_ON_NEW_ENT;
349 elem = set_find(bp_ident_t, bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
350 if (elem && elem->bp.active) {
351 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
358 key.nr = get_entity_nr(ent);
359 key.bp.reason = BP_ON_NEW_THING;
361 elem = set_find(bp_nr_t, bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
362 if (elem && elem->bp.active) {
363 dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
370 * A type was created.
372 * @param ctx the hook context
373 * @param tp the newly created type
375 static void dbg_new_type(void *ctx, ir_type *tp)
381 key.nr = get_type_nr(tp);
382 key.bp.reason = BP_ON_NEW_THING;
384 elem = set_find(bp_nr_t, bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
385 if (elem && elem->bp.active) {
386 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
393 * Return the reason string.
395 static const char *reason_str(bp_reasons_t reason)
398 case BP_ON_NEW_THING: return "node, entity or type creation";
399 case BP_ON_REPLACE: return "node replace";
400 case BP_ON_LOWER: return "node lowering";
401 case BP_ON_REMIRG: return "removing IRG";
402 case BP_ON_NEW_ENT: return "entity creation";
403 case BP_MAX_REASON: break;
405 panic("unsupported reason");
409 * Compare two number breakpoints.
411 static int cmp_nr_bp(const void *elt, const void *key, size_t size)
413 const bp_nr_t *e1 = (const bp_nr_t*)elt;
414 const bp_nr_t *e2 = (const bp_nr_t*)key;
417 return (e1->nr - e2->nr) | (e1->bp.reason - e2->bp.reason);
421 * Compare two ident breakpoints.
423 static int cmp_ident_bp(const void *elt, const void *key, size_t size)
425 const bp_ident_t *e1 = (const bp_ident_t*)elt;
426 const bp_ident_t *e2 = (const bp_ident_t*)key;
429 return (e1->id != e2->id) | (e1->bp.reason - e2->bp.reason);
435 static void update_hooks(breakpoint *bp)
437 #define CASE_ON(a, hook, handler) case a: if (! IS_HOOKED(hook)) HOOK(hook, handler); break
438 #define CASE_OFF(a, hook) case a: if (IS_HOOKED(hook)) UNHOOK(hook); break
441 ++num_active_bp[bp->reason];
443 --num_active_bp[bp->reason];
445 if (num_active_bp[bp->reason] > 0) {
446 /* register the hooks on demand */
447 switch (bp->reason) {
448 CASE_ON(BP_ON_REPLACE, hook_replace, dbg_replace);
449 CASE_ON(BP_ON_LOWER, hook_lower, dbg_lower);
450 CASE_ON(BP_ON_REMIRG, hook_free_graph, dbg_free_graph);
451 CASE_ON(BP_ON_NEW_ENT, hook_new_entity, dbg_new_entity);
452 case BP_ON_NEW_THING:
453 if (!IS_HOOKED(hook_new_node))
454 HOOK(hook_new_node, dbg_new_node);
455 if (!IS_HOOKED(hook_new_type))
456 HOOK(hook_new_type, dbg_new_type);
457 if (!IS_HOOKED(hook_new_entity))
458 HOOK(hook_new_entity, dbg_new_entity);
465 /* unregister the hook on demand */
466 switch (bp->reason) {
467 CASE_OFF(BP_ON_REPLACE, hook_replace);
468 CASE_OFF(BP_ON_LOWER, hook_lower);
469 CASE_OFF(BP_ON_REMIRG, hook_free_graph);
470 CASE_OFF(BP_ON_NEW_ENT, hook_new_entity);
471 case BP_ON_NEW_THING:
472 if (IS_HOOKED(hook_new_node))
473 UNHOOK(hook_new_node);
474 if (IS_HOOKED(hook_new_type))
475 UNHOOK(hook_new_type);
476 if (IS_HOOKED(hook_new_entity))
477 UNHOOK(hook_new_entity);
488 * Break if nr is reached.
490 static void break_on_nr(long nr, bp_reasons_t reason)
497 key.bp.reason = reason;
500 elem = set_insert(bp_nr_t, bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
502 if (elem->bp.bpnr == 0) {
503 /* new break point */
504 elem->bp.bpnr = ++bp_num;
505 elem->bp.next = bp_list;
508 dbg_printf("Firm BP %u: %s of Nr %ld\n", elem->bp.bpnr, reason_str(reason), nr);
510 update_hooks(&elem->bp);
515 * Break if ident name is reached.
517 static void break_on_ident(const char *name, bp_reasons_t reason)
519 bp_ident_t key, *elem;
521 key.bp.kind = BP_IDENT;
524 key.bp.reason = reason;
525 key.id = new_id_from_str(name);
527 elem = set_insert(bp_ident_t, bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
529 if (elem->bp.bpnr == 0) {
530 /* new break point */
531 elem->bp.bpnr = ++bp_num;
532 elem->bp.next = bp_list;
535 dbg_printf("Firm BP %u: %s of ident \"%s\"\n", elem->bp.bpnr, reason_str(reason), name);
537 update_hooks(&elem->bp);
542 * Sets/resets the active flag of breakpoint bp.
544 static void bp_activate(unsigned bp, int active)
548 for (p = bp_list; p; p = p->next) {
550 if (p->active != active) {
555 dbg_printf("Firm BP %u is now %s\n", bp, active ? "enabled" : "disabled");
559 dbg_printf("Error: Firm BP %u not exists.\n", bp);
564 * Show a list of supported commands
566 static void show_commands(void)
568 dbg_printf("Internal Firm debugger extension commands:\n"
569 "init break after initialization\n"
570 "create nr break if node nr was created\n"
571 "replace nr break if node nr is replaced by another node\n"
572 "lower nr break before node nr is lowered\n"
573 "remirg nr|name break if the irg of nr or entity name is deleted\n"
574 "newent nr|name break if the entity nr or name was created\n"
575 "newtype nr|name break if the type nr or name was created\n"
576 "bp show all breakpoints\n"
577 "enable nr enable breakpoint nr\n"
578 "disable nr disable breakpoint nr\n"
579 "showtype nr|name show content of the type nr or name\n"
580 "showent nr|name show content of the entity nr or name\n"
581 "setmask name msk sets the debug module name to mask msk\n"
582 "setlvl name lvl sets the debug module name to level lvl\n"
583 "setoutfile name file redirects debug output of module name to file\n"
584 "irgname name prints address and graph number of a method given by its name\n"
585 "irgldname ldname prints address and graph number of a method given by its ldname\n"
586 "initialnodenr n|rand set initial node number to n or random number\n"
587 "help list all commands\n"
592 * Shows all Firm breakpoints.
594 static void show_bp(void)
601 dbg_printf("Firm Breakpoints:");
602 for (p = bp_list; p; p = p->next) {
604 dbg_printf("+\n BP %u: ", p->bpnr);
608 node_p = (bp_nr_t *)p;
609 dbg_printf("%s of Nr %ld ", reason_str(p->reason), node_p->nr);
613 ident_p = (bp_ident_t *)p;
614 dbg_printf("+%s of ident \"%s\" ", reason_str(p->reason), get_id_str(ident_p->id));
618 dbg_printf(p->active ? "+enabled" : "+disabled");
620 dbg_printf(have_one ? "+\n" : "+ NONE\n");
624 * firm_dbg_register() expects that the name is stored persistent.
625 * So we need this little helper function
627 static firm_dbg_module_t *dbg_register(const char *name)
629 ident *id = new_id_from_str(name);
631 return firm_dbg_register(get_id_str(id));
635 * Sets the debug mask of module name to lvl
637 static void set_dbg_level(const char *name, unsigned lvl)
639 firm_dbg_module_t *module = dbg_register(name);
641 if (firm_dbg_get_mask(module) != lvl) {
642 firm_dbg_set_mask(module, lvl);
644 dbg_printf("Setting debug mask of module %s to %u\n", name, lvl);
649 * Redirects the debug output of module name to fname
651 static void set_dbg_outfile(const char *name, const char *fname)
653 firm_dbg_module_t *module = dbg_register(name);
654 FILE *f = fopen(fname, "w");
661 firm_dbg_set_file(module, f);
662 dbg_printf("Redirecting debug output of module %s to file %s\n", name, fname);
666 * Show info about a firm thing.
668 static void show_firm_object(void *firm_thing)
672 if (firm_thing == NULL) {
673 fprintf(f, "<NULL>\n");
676 switch (get_kind(firm_thing)) {
678 fprintf(f, "BAD: (%p)\n", firm_thing);
681 dump_entity_to_file(f, (ir_entity*)firm_thing);
684 dump_type_to_file(f, (ir_type*)firm_thing);
696 fprintf(f, "Cannot identify thing at (%p).\n", firm_thing);
701 * Find a firm type by its number.
703 static ir_type *find_type_nr(long nr)
705 int i, n = get_irp_n_types();
708 for (i = 0; i < n; ++i) {
709 tp = get_irp_type(i);
710 if (get_type_nr(tp) == nr)
713 tp = get_glob_type();
714 if (get_type_nr(tp) == nr)
720 * Find a firm type by its name.
722 static ir_type *find_type_name(const char *name)
724 int i, n = get_irp_n_types();
727 for (i = 0; i < n; ++i) {
728 tp = get_irp_type(i);
729 if (!is_compound_type(tp))
732 if (strcmp(get_compound_name(tp), name) == 0)
735 tp = get_glob_type();
736 if (strcmp(get_compound_name(tp), name) == 0)
741 /** The environment for the entity search functions. */
742 typedef struct find_env {
744 long nr; /**< the number that is searched for */
745 const char *name; /**< the name that is searched for */
747 ir_entity *res; /**< the result */
751 * Type-walker: Find an entity with given number.
753 static void check_ent_nr(type_or_ent tore, void *ctx)
755 find_env_t *env = (find_env_t*)ctx;
757 if (is_entity(tore.ent)) {
758 if (get_entity_nr(tore.ent) == env->u.nr) {
765 * Type-walker: Find an entity with given name.
767 static void check_ent_name(type_or_ent tore, void *ctx)
769 find_env_t *env = (find_env_t*)ctx;
771 if (is_entity(tore.ent))
772 if (strcmp(get_entity_name(tore.ent), env->u.name) == 0) {
778 * Find a firm entity by its number.
780 static ir_entity *find_entity_nr(long nr)
786 type_walk(check_ent_nr, NULL, &env);
791 * Find a firm entity by its name.
793 static ir_entity *find_entity_name(const char *name)
799 type_walk(check_ent_name, NULL, &env);
804 * Search methods for a name.
806 static void show_by_name(type_or_ent tore, void *env)
808 ident *id = (ident *)env;
810 if (is_entity(tore.ent)) {
811 ir_entity *ent = tore.ent;
813 if (is_method_entity(ent)) {
814 if (get_entity_ident(ent) == id) {
815 ir_type *owner = get_entity_owner(ent);
816 ir_graph *irg = get_entity_irg(ent);
818 if (owner != get_glob_type()) {
819 printf("%s::%s", get_compound_name(owner), get_id_str(id));
821 printf("%s", get_id_str(id));
824 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
833 * Search methods for a ldname.
835 static void show_by_ldname(type_or_ent tore, void *env)
837 ident *id = (ident *)env;
839 if (is_entity(tore.ent)) {
840 ir_entity *ent = tore.ent;
842 if (is_method_entity(ent)) {
843 if (get_entity_ld_ident(ent) == id) {
844 ir_type *owner = get_entity_owner(ent);
845 ir_graph *irg = get_entity_irg(ent);
847 if (owner != get_glob_type()) {
848 printf("%s::%s", get_compound_name(owner), get_id_str(id));
850 printf("%s", get_id_str(id));
853 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
862 * prints the address and graph number of all irgs with given name
864 static void irg_name(const char *name)
866 ident *id = new_id_from_str(name);
868 type_walk(show_by_name, NULL, (void *)id);
872 * prints the address and graph number of all irgs with given ld_name
874 static void irg_ld_name(const char *name)
876 ident *id = new_id_from_str(name);
878 type_walk(show_by_ldname, NULL, (void *)id);
883 tok_bp = first_token,
908 static const char *reserved[] = {
933 static struct lexer {
934 int has_token; /**< set if a token is cached. */
935 unsigned cur_token; /**< current token. */
936 unsigned number; /**< current token attribute. */
937 const char *s; /**< current token attribute. */
938 size_t len; /**< current token attribute. */
940 const char *curr_pos;
942 const char *tok_start;
946 * Initialize the lexer.
948 static void init_lexer(const char *input)
951 lexer.curr_pos = input;
952 lexer.end_pos = input + strlen(input);
957 * Get the next char from the input.
959 static char next_char(void)
961 if (lexer.curr_pos >= lexer.end_pos)
963 return *lexer.curr_pos++;
966 #define unput() if (lexer.curr_pos < lexer.end_pos) --lexer.curr_pos
969 #define MIN(a, b) (a) < (b) ? (a) : (b)
974 static unsigned get_token(void)
979 /* skip white space */
982 } while (c != '\0' && isspace((unsigned char)c));
984 lexer.tok_start = lexer.curr_pos - 1;
985 if (c == '.' || isalpha((unsigned char)c)) {
986 /* command begins here */
988 const char* tok_start;
993 } while (isgraph((unsigned char)c));
996 tok_start = lexer.tok_start;
997 if (*tok_start == '.') {
1001 for (i = ARRAY_SIZE(reserved); i-- != 0;) {
1002 if (strncasecmp(tok_start, reserved[i], len) == 0 && reserved[i][len] == '\0')
1003 return first_token + i;
1007 lexer.s = lexer.tok_start;
1008 lexer.len = lexer.curr_pos - lexer.s;
1009 return tok_identifier;
1010 } else if (isdigit((unsigned char)c) || c == '-') {
1011 unsigned number = 0;
1014 /* we support negative numbers as well, so one can easily set all bits with -1 */
1023 if (c == 'x' || c == 'X') {
1027 if (! isxdigit((unsigned char)c))
1029 if (isdigit((unsigned char)c))
1030 number = (number << 4) | (c - '0');
1032 number = (number << 4) | (toupper((unsigned char)c) - 'A' + 10);
1035 lexer.number = number;
1040 if (! isdigit((unsigned char)c))
1042 number = number * 10 + (c - '0');
1046 lexer.number = sign ? 0 - number : number;
1054 void firm_debug(const char *cmd)
1056 char name[1024], fname[1024];
1064 token = get_token();
1071 token = get_token();
1072 if (token != tok_number)
1074 break_on_nr(lexer.number, BP_ON_NEW_THING);
1078 token = get_token();
1079 if (token != tok_number)
1081 break_on_nr(lexer.number, BP_ON_REPLACE);
1085 token = get_token();
1086 if (token != tok_number)
1088 break_on_nr(lexer.number, BP_ON_LOWER);
1092 token = get_token();
1094 if (token == tok_number)
1095 break_on_nr(lexer.number, BP_ON_REMIRG);
1096 else if (token == tok_identifier) {
1097 len = MIN(lexer.len, 1023);
1098 strncpy(name, lexer.s, len);
1100 break_on_ident(name, BP_ON_REMIRG);
1106 token = get_token();
1108 if (token == tok_number)
1109 break_on_nr(lexer.number, BP_ON_NEW_THING);
1110 else if (token == tok_identifier) {
1111 len = MIN(lexer.len, 1023);
1112 strncpy(name, lexer.s, len);
1114 break_on_ident(name, BP_ON_NEW_ENT);
1120 token = get_token();
1122 if (token == tok_number)
1123 show_firm_object(find_type_nr(lexer.number));
1124 else if (token == tok_identifier) {
1125 len = MIN(lexer.len, 1023);
1126 strncpy(name, lexer.s, len);
1128 show_firm_object(find_type_name(name));
1134 token = get_token();
1136 if (token == tok_number)
1137 show_firm_object(find_entity_nr(lexer.number));
1138 else if (token == tok_identifier) {
1139 len = MIN(lexer.len, 1023);
1140 strncpy(name, lexer.s, len);
1142 show_firm_object(find_entity_name(name));
1156 token = get_token();
1157 if (token != tok_number)
1159 bp_activate(lexer.number, 1);
1163 token = get_token();
1164 if (token != tok_number)
1166 bp_activate(lexer.number, 0);
1170 token = get_token();
1171 if (token != tok_identifier)
1173 len = MIN(lexer.len, 1023);
1174 strncpy(name, lexer.s, len);
1177 token = get_token();
1178 if (token != tok_number)
1180 set_dbg_level(name, lexer.number);
1184 token = get_token();
1185 if (token != tok_identifier)
1187 len = MIN(lexer.len, 1023);
1188 strncpy(name, lexer.s, len);
1191 token = get_token();
1192 if (token != tok_number)
1194 set_dbg_level(name, (1 << lexer.number) - 1);
1197 case tok_setoutfile:
1198 token = get_token();
1199 if (token != tok_identifier)
1201 len = MIN(lexer.len, 1023);
1202 strncpy(name, lexer.s, len);
1205 token = get_token();
1206 if (token != tok_identifier)
1208 len = MIN(lexer.len, 1023);
1209 strncpy(fname, lexer.s, len);
1211 set_dbg_outfile(name, fname);
1215 token = get_token();
1216 if (token != tok_identifier)
1218 len = MIN(lexer.len, 1023);
1219 strncpy(name, lexer.s, len);
1224 case tok_initialnodenr:
1225 token = get_token();
1226 if (token == tok_number) {
1227 dbg_printf("Setting initial node number to %u\n", lexer.number);
1228 irp->max_node_nr = lexer.number;
1229 } else if (token == tok_identifier && !strcmp(lexer.s, "rand")) {
1230 dbg_printf("Randomizing initial node number\n");
1232 irp->max_node_nr += rand() % 6666;
1238 token = get_token();
1239 if (token != tok_identifier)
1241 len = MIN(lexer.len, 1023);
1242 strncpy(name, lexer.s, len);
1247 case tok_dumpfilter:
1248 token = get_token();
1249 if (token != tok_identifier)
1251 len = MIN(lexer.len, 1023);
1252 strncpy(name, lexer.s, len);
1254 ir_set_dump_filter(name);
1264 printf("Error: before %s\n", lexer.tok_start);
1269 token = get_token();
1270 if (token == tok_eof)
1279 void firm_init_debugger(void)
1283 bp_numbers = new_set(cmp_nr_bp, 8);
1284 bp_idents = new_set(cmp_ident_bp, 8);
1286 env = getenv("FIRMDBG");
1297 void firm_finish_debugger(void)
1299 del_set(bp_numbers);
1304 * A gdb helper function to print firm objects.
1306 const char *gdb_node_helper(void *firm_object)
1308 static char buf[1024];
1309 ir_snprintf(buf, sizeof(buf), "%+F", firm_object);
1313 const char *gdb_tarval_helper(void *tv_object)
1315 static char buf[1024];
1316 ir_snprintf(buf, sizeof(buf), "%+T", tv_object);
1320 const char *gdb_out_edge_helper(const ir_node *node)
1322 static char buf[4*1024];
1325 size_t len = sizeof(buf);
1326 foreach_out_edge(node, edge) {
1327 ir_node *n = get_edge_src_irn(edge);
1329 ir_snprintf(b, len, "%+F ", n);
1340 /* some picky compiler do not allow empty files */
1341 static int __attribute__((unused)) _firm_only_that_you_can_compile_with_NDEBUG_defined;
1346 * @page debugger The Firm debugger extension
1348 * Firm contains a debugger extension. This allows to set debugger breakpoints
1349 * an various events.
1350 * The extension uses a text interface which can be accessed from most debuggers.
1351 * More than one command can be given separated by ';'.
1353 * @section sec_cmd Supported commands
1355 * Historically all debugger commands start with a dot. This isn't needed in newer
1356 * versions, but still supported, ie the commands ".init" and "init" are equal.
1357 * The following commands are currently supported:
1361 * Break immediately after the debugger extension was initialized.
1362 * Typically this command is used in the environment to stop the execution
1363 * of a Firm compiler right after the initialization, like this:
1365 * $export FIRMDBG=".init"
1369 * Break if a new IR-node with node number nr was created.
1370 * Typically used to find the place where wrong nodes are created.
1374 * Break before IR-node with node number nr is replaced by another node.
1378 * Break before IR-node with node number nr is lowered.
1382 * Break if the irg with graph number nr is deleted.
1386 * Break if the irg of entity name is deleted.
1390 * Break if the entity with number nr was created.
1394 * Break if the entity name was created.
1398 * Break if the type with number nr was created.
1402 * Break if the type name was created.
1406 * Show all Firm internal breakpoints.
1410 * Enables breakpoint nr.
1414 * Disables breakpoint nr.
1418 * Show the content of entity nr.
1422 * Show the content of entity name.
1426 * Show the content of type nr.
1430 * Show the content of type name.
1432 * @b setmask name msk
1434 * Sets the debug module name to mask msk.
1436 * @b setlvl name lvl
1438 * Sets the debug module name to level lvl.
1440 * @b setoutfile name file
1442 * Redirects debug output of module name to file.
1446 * Prints address and graph number of a method given by its name.
1450 * Prints address and graph number of a method given by its linker name.
1454 * List all commands.
1457 * The Firm debugger extension can be accessed using the function firm_debug().
1458 * The following example shows how to set a creation breakpoint in GDB when
1459 * node 2101 is created.
1461 * -# set FIRMDBG="init"
1462 * -# start gdb with your compiler
1463 * -# after gdb breaks, issue
1465 * call firm_debug("create 2101")
1467 * On the console the following text should be issued:
1469 * Firm BP 1: creation of Node 2101
1472 * @section gdb_macro GDB macro
1474 * Add the following to your .gdbinit file:
1477 # define firm "cmd" Firm debugger extension
1480 call firm_debug($arg0)
1484 * Then, all Firm debugger extension commands can be accessed in the gdb
1485 * console using the firm prefix, eg.:
1487 * firm "create 2101"