2 * Copyright (C) 1995-2008 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
32 #define WIN32_LEAN_AND_MEAN
50 #include "irgraph_t.h"
54 #include "iredges_t.h"
59 /* Break into the debugger. The Win32 way. */
60 void firm_debug_break(void) {
63 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64))
64 /* Break into the debugger. The ia32/x86_64 way under GCC. */
65 void firm_debug_break(void) {
66 __asm__ __volatile__("int3");
69 /* Break into the debugger. Poor Unix way. */
70 void firm_debug_break(void) {
75 /** supported breakpoint kinds */
77 BP_NR = 'n', /**< break on node number. */
78 BP_IDENT = 'i' /**< break on ident. */
82 * Reasons for node number breakpoints.
84 typedef enum _bp_reasons_t {
85 BP_ON_NEW_NODE, /**< break if node with number is created */
86 BP_ON_REPLACE, /**< break if node with number is replaced */
87 BP_ON_LOWER, /**< break if node with number is lowered */
88 BP_ON_REMIRG, /**< break if an IRG is removed */
89 BP_ON_NEW_ENT, /**< break if a new entity is created */
90 BP_ON_NEW_TYPE, /**< break if a new type is created */
95 typedef struct _breakpoint {
96 bp_kind kind; /**< the kind of this break point */
97 unsigned bpnr; /**< break point number */
98 int active; /**< non-zero, if this break point is active */
99 bp_reasons_t reason; /**< reason for the breakpoint */
100 struct _breakpoint *next; /**< link to the next one */
103 /** A number breakpoint. */
105 breakpoint bp; /**< the breakpoint data */
106 long nr; /**< the node number */
109 /** Calculate the hash value for a node breakpoint. */
110 #define HASH_NR_BP(key) (((key).nr << 2) ^ (key).bp.reason)
112 /** An ident breakpoint. */
114 breakpoint bp; /**< the breakpoint data */
115 ident *id; /**< the ident */
118 /** Calculate the hash value for an ident breakpoint. */
119 #define HASH_IDENT_BP(key) (HASH_PTR((key).id) ^ (key).bp.reason)
121 /** The set containing the breakpoints on node numbers. */
122 static set *bp_numbers;
124 /** The set containing the breakpoints on idents. */
125 static set *bp_idents;
127 /**< the list of all breakpoints */
128 static breakpoint *bp_list;
130 /** number of the current break point */
131 static unsigned bp_num = 0;
133 /** set if break on init command was issued. */
134 static int break_on_init = 0;
136 /** the hook entries for the Firm debugger module. */
137 static hook_entry_t debugger_hooks[hook_last];
139 /** number of active breakpoints to maintain hooks. */
140 static unsigned num_active_bp[BP_MAX_REASON];
143 * The debug message buffer
145 static char firm_dbg_msg_buf[2048];
148 * If set, the debug extension writes all output to the
149 * firm_dbg_msg_buf buffer
151 static int redir_output = 0;
154 * Is set to one, if the debug extension is active
156 static int is_active = 0;
158 /** hook the hook h with function fkt. */
159 #define HOOK(h, fkt) \
161 debugger_hooks[h].hook._##h = fkt; \
162 register_hook(h, &debugger_hooks[h]); \
165 /** unhook the hook h */
168 unregister_hook(h, &debugger_hooks[h]); \
169 debugger_hooks[h].hook._##h = NULL; \
172 /** returns non-zero if a entry hook h is used */
173 #define IS_HOOKED(h) (debugger_hooks[h].hook._##h != NULL)
175 /* some macros needed to create the info string */
176 #define _DBG_VERSION(major, minor) #major "." #minor
177 #define DBG_VERSION(major, minor) _DBG_VERSION(major, minor)
178 #define API_VERSION(major, minor) "API:" DBG_VERSION(major, minor)
180 /* the API version: change if needed */
181 #define FIRM_DBG_MAJOR 1
182 #define FIRM_DBG_MINOR 0
184 /** for automatic detection of the debug extension */
185 static const char firm_debug_info_string[] =
186 API_VERSION(FIRM_DBG_MAJOR, FIRM_DBG_MINOR);
189 * Returns non-zero, if the debug extension is active
191 int firm_debug_active(void) {
193 } /* firm_debug_active */
196 * Reset the debug text buffer.
198 static void reset_dbg_buf(void) {
199 firm_dbg_msg_buf[0] = '\0';
200 } /* reset_dbg_buf */
203 * Add text to the debug text buffer.
205 static void add_to_dbg_buf(const char *buf) {
206 strncat(firm_dbg_msg_buf, buf, sizeof(firm_dbg_msg_buf));
207 } /* add_to_dbg_buf */
210 * Return the content of the debug text buffer.
212 * To be called from the debugger.
214 const char *firm_debug_text(void) {
215 firm_dbg_msg_buf[sizeof(firm_dbg_msg_buf) - 1] = '\0';
216 return firm_dbg_msg_buf;
217 } /* firm_debug_text */
222 static void dbg_printf(const char *fmt, ...)
234 ir_vsnprintf(buf, sizeof(buf), fmt, args);
244 * A new node is created.
246 * @param ctx the hook context
247 * @param irg the IR graph on which the node is created
248 * @param node the new IR node that was created
250 static void dbg_new_node(void *ctx, ir_graph *irg, ir_node *node)
256 key.nr = get_irn_node_nr(node);
257 key.bp.reason = BP_ON_NEW_NODE;
259 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
260 if (elem && elem->bp.active) {
261 dbg_printf("Firm BP %u reached, %+F created\n", elem->bp.bpnr, node);
267 * A node is replaced.
269 * @param ctx the hook context
270 * @param old the IR node the is replaced
271 * @param nw the new IR node that will replace old
273 static void dbg_replace(void *ctx, ir_node *old, ir_node *nw)
278 key.nr = get_irn_node_nr(old);
279 key.bp.reason = BP_ON_REPLACE;
281 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
282 if (elem && elem->bp.active) {
283 dbg_printf("Firm BP %u reached, %+F will be replaced by %+F\n", elem->bp.bpnr, old, nw);
289 * A new node is lowered.
291 * @param ctx the hook context
292 * @param node the new IR node that will be lowered
294 static void dbg_lower(void *ctx, ir_node *node)
299 key.nr = get_irn_node_nr(node);
300 key.bp.reason = BP_ON_LOWER;
302 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
303 if (elem && elem->bp.active) {
304 dbg_printf("Firm BP %u reached, %+F will be lowered\n", elem->bp.bpnr, node);
310 * A graph will be deleted.
312 * @param ctx the hook context
313 * @param irg the IR graph that will be deleted
315 static void dbg_free_graph(void *ctx, ir_graph *irg)
320 key.nr = get_irg_graph_nr(irg);
321 key.bp.reason = BP_ON_REMIRG;
323 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
324 if (elem && elem->bp.active) {
325 ir_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, irg);
330 bp_ident_t key, *elem;
331 ir_entity *ent = get_irg_entity(irg);
336 key.id = get_entity_ident(ent);
337 key.bp.reason = BP_ON_REMIRG;
339 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
340 if (elem && elem->bp.active) {
341 dbg_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, ent);
345 } /* dbg_free_graph */
348 * An entity was created.
350 * @param ctx the hook context
351 * @param ent the newly created entity
353 static void dbg_new_entity(void *ctx, ir_entity *ent)
357 bp_ident_t key, *elem;
359 key.id = get_entity_ident(ent);
360 key.bp.reason = BP_ON_NEW_ENT;
362 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
363 if (elem && elem->bp.active) {
364 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
371 key.nr = get_entity_nr(ent);
372 key.bp.reason = BP_ON_NEW_ENT;
374 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
375 if (elem && elem->bp.active) {
376 dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
380 } /* dbg_new_entity */
383 * A type was created.
385 * @param ctx the hook context
386 * @param tp the newly created type
388 static void dbg_new_type(void *ctx, ir_type *tp)
394 key.nr = get_type_nr(tp);
395 key.bp.reason = BP_ON_NEW_TYPE;
397 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
398 if (elem && elem->bp.active) {
399 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
406 * Return the reason string.
408 static const char *reason_str(bp_reasons_t reason)
411 case BP_ON_NEW_NODE: return "node creation";
412 case BP_ON_REPLACE: return "node replace";
413 case BP_ON_LOWER: return "node lowering";
414 case BP_ON_REMIRG: return "removing IRG";
415 case BP_ON_NEW_ENT: return "entity creation";
416 case BP_ON_NEW_TYPE: return "type creation";
417 case BP_MAX_REASON: break;
419 panic("unsupported reason");
423 * Compare two number breakpoints.
425 static int cmp_nr_bp(const void *elt, const void *key, size_t size)
427 const bp_nr_t *e1 = elt;
428 const bp_nr_t *e2 = key;
431 return (e1->nr - e2->nr) | (e1->bp.reason - e2->bp.reason);
435 * Compare two ident breakpoints.
437 static int cmp_ident_bp(const void *elt, const void *key, size_t size)
439 const bp_ident_t *e1 = elt;
440 const bp_ident_t *e2 = key;
443 return (e1->id != e2->id) | (e1->bp.reason - e2->bp.reason);
449 static void update_hooks(breakpoint *bp)
451 #define CASE_ON(a, b) case a: if (! IS_HOOKED(hook_##b)) HOOK(hook_##b, dbg_##b); break
452 #define CASE_OFF(a, b) case a: if (IS_HOOKED(hook_##b)) UNHOOK(hook_##b); break
455 ++num_active_bp[bp->reason];
457 --num_active_bp[bp->reason];
459 if (num_active_bp[bp->reason] > 0) {
460 /* register the hooks on demand */
461 switch (bp->reason) {
462 CASE_ON(BP_ON_NEW_NODE, new_node);
463 CASE_ON(BP_ON_REPLACE, replace);
464 CASE_ON(BP_ON_LOWER, lower);
465 CASE_ON(BP_ON_REMIRG, free_graph);
466 CASE_ON(BP_ON_NEW_ENT, new_entity);
467 CASE_ON(BP_ON_NEW_TYPE, new_type);
473 /* unregister the hook on demand */
474 switch (bp->reason) {
475 CASE_OFF(BP_ON_NEW_NODE, new_node);
476 CASE_OFF(BP_ON_REPLACE, replace);
477 CASE_OFF(BP_ON_LOWER, lower);
478 CASE_OFF(BP_ON_REMIRG, free_graph);
479 CASE_OFF(BP_ON_NEW_ENT, new_entity);
480 CASE_OFF(BP_ON_NEW_TYPE, new_type);
490 * Break if nr is reached.
492 static void break_on_nr(long nr, bp_reasons_t reason)
499 key.bp.reason = reason;
502 elem = set_insert(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
504 if (elem->bp.bpnr == 0) {
505 /* new break point */
506 elem->bp.bpnr = ++bp_num;
507 elem->bp.next = bp_list;
510 dbg_printf("Firm BP %u: %s of Nr %ld\n", elem->bp.bpnr, reason_str(reason), nr);
512 update_hooks(&elem->bp);
517 * Break if ident name is reached.
519 static void break_on_ident(const char *name, bp_reasons_t reason) {
520 bp_ident_t key, *elem;
522 key.bp.kind = BP_IDENT;
525 key.bp.reason = reason;
526 key.id = new_id_from_str(name);
528 elem = set_insert(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
530 if (elem->bp.bpnr == 0) {
531 /* new break point */
532 elem->bp.bpnr = ++bp_num;
533 elem->bp.next = bp_list;
536 dbg_printf("Firm BP %u: %s of ident \"%s\"\n", elem->bp.bpnr, reason_str(reason), name);
538 update_hooks(&elem->bp);
540 } /* break_on_ident */
543 * Sets/resets the active flag of breakpoint bp.
545 static void bp_activate(unsigned bp, int active)
549 for (p = bp_list; p; p = p->next) {
551 if (p->active != active) {
556 dbg_printf("Firm BP %u is now %s\n", bp, active ? "enabled" : "disabled");
560 dbg_printf("Error: Firm BP %u not exists.\n", bp);
565 * Show a list of supported commands
567 static void show_commands(void) {
568 dbg_printf("Internal Firm debugger extension $Revision$ 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 "help list all commands\n"
588 } /* show_commands */
591 * Shows all Firm breakpoints.
593 static void show_bp(void) {
599 dbg_printf("Firm Breakpoints:");
600 for (p = bp_list; p; p = p->next) {
602 dbg_printf("+\n BP %u: ", p->bpnr);
606 node_p = (bp_nr_t *)p;
607 dbg_printf("%s of Nr %ld ", reason_str(p->reason), node_p->nr);
611 ident_p = (bp_ident_t *)p;
612 dbg_printf("+%s of ident \"%s\" ", reason_str(p->reason), get_id_str(ident_p->id));
616 dbg_printf(p->active ? "+enabled" : "+disabled");
618 dbg_printf(have_one ? "+\n" : "+ NONE\n");
622 * firm_dbg_register() expects that the name is stored persistent.
623 * So we need this little helper function
625 static firm_dbg_module_t *dbg_register(const char *name) {
626 ident *id = new_id_from_str(name);
628 return firm_dbg_register(get_id_str(id));
632 * Sets the debug mask of module name to lvl
634 static void set_dbg_level(const char *name, unsigned lvl)
636 firm_dbg_module_t *module = dbg_register(name);
638 if (firm_dbg_get_mask(module) != lvl) {
639 firm_dbg_set_mask(module, lvl);
641 dbg_printf("Setting debug mask of module %s to %u\n", name, lvl);
643 } /* set_dbg_level */
646 * Redirects the debug output of module name to fname
648 static void set_dbg_outfile(const char *name, const char *fname)
650 firm_dbg_module_t *module = dbg_register(name);
651 FILE *f = fopen(fname, "w");
658 firm_dbg_set_file(module, f);
659 dbg_printf("Redirecting debug output of module %s to file %s\n", name, fname);
660 } /* set_dbg_outfile */
663 * Show info about a firm thing.
665 static void show_firm_object(void *firm_thing) {
668 if (firm_thing == NULL) {
669 fprintf(f, "<NULL>\n");
672 switch (get_kind(firm_thing)) {
674 fprintf(f, "BAD: (%p)\n", firm_thing);
677 dump_entity_to_file(f, firm_thing, dump_verbosity_max);
680 dump_type_to_file(f, firm_thing, dump_verbosity_max);
688 case k_ir_compound_graph_path:
694 fprintf(f, "Cannot identify thing at (%p).\n", firm_thing);
696 } /* show_firm_object */
699 * Find a firm type by its number.
701 static ir_type *find_type_nr(long nr) {
702 int i, n = get_irp_n_types();
705 for (i = 0; i < n; ++i) {
706 tp = get_irp_type(i);
707 if (get_type_nr(tp) == nr)
710 tp = get_glob_type();
711 if (get_type_nr(tp) == nr)
717 * Find a firm type by its name.
719 static ir_type *find_type_name(const char *name) {
720 int i, n = get_irp_n_types();
723 for (i = 0; i < n; ++i) {
724 tp = get_irp_type(i);
725 if (!is_compound_type(tp))
728 if (strcmp(get_compound_name(tp), name) == 0)
731 tp = get_glob_type();
732 if (strcmp(get_compound_name(tp), name) == 0)
735 } /* find_type_name */
737 /** The environment for the entity search functions. */
738 typedef struct find_env {
740 long nr; /**< the number that is searched for */
741 const char *name; /**< the name that is searched for */
743 ir_entity *res; /**< the result */
747 * Type-walker: Find an entity with given number.
749 static void check_ent_nr(type_or_ent tore, void *ctx) {
750 find_env_t *env = ctx;
752 if (is_entity(tore.ent)) {
753 if (get_entity_nr(tore.ent) == env->u.nr) {
760 * Type-walker: Find an entity with given name.
762 static void check_ent_name(type_or_ent tore, void *ctx) {
763 find_env_t *env = ctx;
765 if (is_entity(tore.ent))
766 if (strcmp(get_entity_name(tore.ent), env->u.name) == 0) {
769 } /* check_ent_name */
772 * Find a firm entity by its number.
774 static ir_entity *find_entity_nr(long nr) {
779 type_walk(check_ent_nr, NULL, &env);
781 } /* find_entity_nr */
784 * Find a firm entity by its name.
786 static ir_entity *find_entity_name(const char *name) {
791 type_walk(check_ent_name, NULL, &env);
793 } /* find_entity_name */
796 * Search methods for a name.
798 static void show_by_name(type_or_ent tore, void *env) {
799 ident *id = (ident *)env;
801 if (is_entity(tore.ent)) {
802 ir_entity *ent = tore.ent;
804 if (is_method_entity(ent)) {
805 if (get_entity_ident(ent) == id) {
806 ir_type *owner = get_entity_owner(ent);
807 ir_graph *irg = get_entity_irg(ent);
809 if (owner != get_glob_type()) {
810 printf("%s::%s", get_compound_name(owner), get_id_str(id));
812 printf("%s", get_id_str(id));
815 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
824 * Search methods for a ldname.
826 static void show_by_ldname(type_or_ent tore, void *env) {
827 ident *id = (ident *)env;
829 if (is_entity(tore.ent)) {
830 ir_entity *ent = tore.ent;
832 if (is_method_entity(ent)) {
833 if (get_entity_ld_ident(ent) == id) {
834 ir_type *owner = get_entity_owner(ent);
835 ir_graph *irg = get_entity_irg(ent);
837 if (owner != get_glob_type()) {
838 printf("%s::%s", get_compound_name(owner), get_id_str(id));
840 printf("%s", get_id_str(id));
843 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
849 } /* show_by_ldname */
852 * prints the address and graph number of all irgs with given name
854 static void irg_name(const char *name) {
855 ident *id = new_id_from_str(name);
857 type_walk(show_by_name, NULL, (void *)id);
861 * prints the address and graph number of all irgs with given ld_name
863 static void irg_ld_name(const char *name) {
864 ident *id = new_id_from_str(name);
866 type_walk(show_by_ldname, NULL, (void *)id);
894 static const char *reserved[] = {
918 static struct lexer {
919 int has_token; /**< set if a token is cached. */
920 unsigned cur_token; /**< current token. */
921 unsigned number; /**< current token attribute. */
922 const char *s; /**< current token attribute. */
923 unsigned len; /**< current token attribute. */
925 const char *curr_pos;
927 const char *tok_start;
931 * Initialize the lexer.
933 static void init_lexer(const char *input) {
935 lexer.curr_pos = input;
936 lexer.end_pos = input + strlen(input);
941 * Get the next char from the input.
943 static char next_char(void) {
944 if (lexer.curr_pos >= lexer.end_pos)
946 return *lexer.curr_pos++;
949 #define unput() if (lexer.curr_pos < lexer.end_pos) --lexer.curr_pos
952 #define MIN(a, b) (a) < (b) ? (a) : (b)
957 static unsigned get_token(void) {
961 /* skip white space */
964 } while (c != '\0' && isspace(c));
966 lexer.tok_start = lexer.curr_pos - 1;
967 if (c == '.' || isalpha(c)) {
968 /* command begins here */
970 const char* tok_start;
975 } while (isgraph(c));
978 tok_start = lexer.tok_start;
979 if (*tok_start == '.') {
983 for (i = sizeof(reserved)/sizeof(reserved[0]) - 1; i >= 0; --i) {
984 if (strncasecmp(tok_start, reserved[i], len) == 0 && reserved[i][len] == '\0')
989 lexer.s = lexer.tok_start;
990 lexer.len = lexer.curr_pos - lexer.s;
991 return tok_identifier;
992 } else if (isdigit(c) || c == '-') {
996 /* we support negative numbers as well, so one can easily set all bits with -1 */
1005 if (c == 'x' || c == 'X') {
1012 number = (number << 4) | (c - '0');
1014 number = (number << 4) | (toupper(c) - 'A' + 10);
1017 lexer.number = number;
1024 number = number * 10 + (c - '0');
1028 lexer.number = sign ? 0 - number : number;
1037 * High level function to use from debugger interface
1039 * See show_commands() for supported commands.
1041 void firm_debug(const char *cmd) {
1042 char name[1024], fname[1024];
1050 token = get_token();
1057 token = get_token();
1058 if (token != tok_number)
1060 break_on_nr(lexer.number, BP_ON_NEW_NODE);
1064 token = get_token();
1065 if (token != tok_number)
1067 break_on_nr(lexer.number, BP_ON_REPLACE);
1071 token = get_token();
1072 if (token != tok_number)
1074 break_on_nr(lexer.number, BP_ON_LOWER);
1078 token = get_token();
1080 if (token == tok_number)
1081 break_on_nr(lexer.number, BP_ON_REMIRG);
1082 else if (token == tok_identifier) {
1083 len = MIN(lexer.len, 1023);
1084 strncpy(name, lexer.s, len);
1086 break_on_ident(name, BP_ON_REMIRG);
1092 token = get_token();
1094 if (token == tok_number)
1095 break_on_nr(lexer.number, BP_ON_NEW_ENT);
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_NEW_ENT);
1106 token = get_token();
1108 if (token == tok_number)
1109 break_on_nr(lexer.number, BP_ON_NEW_TYPE);
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_TYPE);
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);
1214 token = get_token();
1215 if (token != tok_identifier)
1217 len = MIN(lexer.len, 1023);
1218 strncpy(name, lexer.s, len);
1223 token = get_token();
1224 if (token != tok_identifier)
1226 len = MIN(lexer.len, 1023);
1227 strncpy(name, lexer.s, len);
1239 printf("Error: before %s\n", lexer.tok_start);
1244 token = get_token();
1245 if (token == tok_eof)
1254 /* creates the debugger tables */
1255 void firm_init_debugger(void)
1259 bp_numbers = new_set(cmp_nr_bp, 8);
1260 bp_idents = new_set(cmp_ident_bp, 8);
1262 env = getenv("FIRMDBG");
1271 } /* firm_init_debugger */
1274 * A gdb helper function to print firm objects.
1276 const char *gdb_node_helper(void *firm_object) {
1277 static char buf[1024];
1278 ir_snprintf(buf, sizeof(buf), "%+F", firm_object);
1283 * A gdb helper function to print tarvals.
1285 const char *gdb_tarval_helper(void *tv_object) {
1286 static char buf[1024];
1287 ir_snprintf(buf, sizeof(buf), "%+T", tv_object);
1291 const char *gdb_out_edge_helper(const ir_node *node) {
1292 static char buf[4*1024];
1295 size_t len = sizeof(buf);
1296 const ir_edge_t *edge;
1297 foreach_out_edge(node, edge) {
1298 ir_node *n = get_edge_src_irn(edge);
1300 ir_snprintf(b, len, "%+F ", n);
1311 /* some picky compiler do not allow empty files */
1312 static int __attribute__((unused)) _firm_only_that_you_can_compile_with_NDEBUG_defined;
1317 * @page debugger The Firm debugger extension
1319 * Firm contains a debugger extension. This allows to set debugger breakpoints
1320 * an various events.
1321 * The extension uses a text interface which can be accessed from most debuggers.
1322 * More than one command can be given separated by ';'.
1324 * @section sec_cmd Supported commands
1326 * Historically all debugger commands start with a dot. This isn't needed in newer
1327 * versions, but still supported, ie the commands ".init" and "init" are equal.
1328 * The following commands are currently supported:
1332 * Break immediately after the debugger extension was initialized.
1333 * Typically this command is used in the environment to stop the execution
1334 * of a Firm compiler right after the initialization, like this:
1336 * $export FIRMDBG=".init"
1340 * Break if a new IR-node with node number nr was created.
1341 * Typically used to find the place where wrong nodes are created.
1345 * Break before IR-node with node number nr is replaced by another node.
1349 * Break before IR-node with node number nr is lowered.
1353 * Break if the irg with graph number nr is deleted.
1357 * Break if the irg of entity name is deleted.
1361 * Break if the entity with number nr was created.
1365 * Break if the entity name was created.
1369 * Break if the type with number nr was created.
1373 * Break if the type name was created.
1377 * Show all Firm internal breakpoints.
1381 * Enables breakpoint nr.
1385 * Disables breakpoint nr.
1389 * Show the content of entity nr.
1393 * Show the content of entity name.
1397 * Show the content of type nr.
1401 * Show the content of type name.
1403 * @b setmask name msk
1405 * Sets the debug module name to mask msk.
1407 * @b setlvl name lvl
1409 * Sets the debug module name to level lvl.
1411 * @b setoutfile name file
1413 * Redirects debug output of module name to file.
1417 * Prints address and graph number of a method given by its name.
1421 * Prints address and graph number of a method given by its linker name.
1425 * List all commands.
1428 * The Firm debugger extension can be accessed using the function firm_debug().
1429 * The following example shows how to set a creation breakpoint in GDB when
1430 * node 2101 is created.
1432 * -# set FIRMDBG="init"
1433 * -# start gdb with your compiler
1434 * -# after gdb breaks, issue
1436 * call firm_debug("create 2101")
1438 * On the console the following text should be issued:
1440 * Firm BP 1: creation of Node 2101
1443 * @section gdb_macro GDB macro
1445 * Add the following to your .gdbinit file:
1448 # define firm "cmd" Firm debugger extension
1451 call firm_debug($arg0)
1455 * Then, all Firm debugger extension commands can be accessed in the gdb
1456 * console using the firm prefix, eg.:
1458 * firm "create 2101"