1 /* Skipping uninteresting files and functions while stepping.
3 Copyright (C) 2011-2017 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
26 #include "completer.h"
28 #include "cli/cli-utils.h"
29 #include "arch-utils.h"
32 #include "breakpoint.h" /* for get_sal_arch () */
34 #include "filenames.h"
36 #include "gdb_regex.h"
37 #include "common/gdb_optional.h"
43 /* Non-zero if FILE is a glob-style pattern.
44 Otherewise it is the plain file name (possibly with directories). */
47 /* The name of the file or NULL.
48 The skiplist entry owns this pointer. */
51 /* Non-zero if FUNCTION is a regexp.
52 Otherwise it is a plain function name (possibly with arguments,
54 int function_is_regexp
;
56 /* The name of the function or NULL.
57 The skiplist entry owns this pointer. */
60 /* If this is a function regexp, the compiled form. */
61 gdb::optional
<compiled_regex
> compiled_function_regexp
;
65 struct skiplist_entry
*next
;
68 static void add_skiplist_entry (struct skiplist_entry
*e
);
70 static struct skiplist_entry
*skiplist_entry_chain
;
71 static int skiplist_entry_count
;
73 #define ALL_SKIPLIST_ENTRIES(E) \
74 for (E = skiplist_entry_chain; E; E = E->next)
76 #define ALL_SKIPLIST_ENTRIES_SAFE(E,TMP) \
77 for (E = skiplist_entry_chain; \
78 E ? (TMP = E->next, 1) : 0; \
81 /* Create a skip object. */
83 static struct skiplist_entry
*
84 make_skip_entry (int file_is_glob
, const char *file
,
85 int function_is_regexp
, const char *function
)
87 struct skiplist_entry
*e
= XCNEW (struct skiplist_entry
);
89 gdb_assert (file
!= NULL
|| function
!= NULL
);
91 gdb_assert (file
!= NULL
);
92 if (function_is_regexp
)
93 gdb_assert (function
!= NULL
);
96 e
->file
= xstrdup (file
);
98 e
->function
= xstrdup (function
);
99 e
->file_is_glob
= file_is_glob
;
100 e
->function_is_regexp
= function_is_regexp
;
106 /* Free a skiplist entry. */
109 free_skiplist_entry (struct skiplist_entry
*e
)
116 /* Wrapper to free_skiplist_entry for use as a cleanup. */
119 free_skiplist_entry_cleanup (void *e
)
121 free_skiplist_entry ((struct skiplist_entry
*) e
);
124 /* Create a cleanup to free skiplist entry E. */
126 static struct cleanup
*
127 make_free_skiplist_entry_cleanup (struct skiplist_entry
*e
)
129 return make_cleanup (free_skiplist_entry_cleanup
, e
);
133 skip_file_command (char *arg
, int from_tty
)
135 struct symtab
*symtab
;
136 const char *filename
= NULL
;
138 /* If no argument was given, try to default to the last
139 displayed codepoint. */
142 symtab
= get_last_displayed_symtab ();
144 error (_("No default file now."));
146 /* It is not a typo, symtab_to_filename_for_display woule be needlessly
148 filename
= symtab_to_fullname (symtab
);
153 add_skiplist_entry (make_skip_entry (0, filename
, 0, NULL
));
155 printf_filtered (_("File %s will be skipped when stepping.\n"), filename
);
158 /* Create a skiplist entry for the given function NAME and add it to the
162 skip_function (const char *name
)
164 add_skiplist_entry (make_skip_entry (0, NULL
, 0, name
));
166 printf_filtered (_("Function %s will be skipped when stepping.\n"), name
);
170 skip_function_command (char *arg
, int from_tty
)
172 /* Default to the current function if no argument is given. */
175 const char *name
= NULL
;
178 if (!last_displayed_sal_is_valid ())
179 error (_("No default function now."));
181 pc
= get_last_displayed_addr ();
182 if (!find_pc_partial_function (pc
, &name
, NULL
, NULL
))
184 error (_("No function found containing current program point %s."),
185 paddress (get_current_arch (), pc
));
187 skip_function (name
);
194 /* Compile the regexp in E.
195 An error is thrown if there's an error.
196 MESSAGE is used as a prefix of the error message. */
199 compile_skip_regexp (struct skiplist_entry
*e
, const char *message
)
201 int flags
= REG_NOSUB
;
204 flags
|= REG_EXTENDED
;
207 gdb_assert (e
->function_is_regexp
&& e
->function
!= NULL
);
208 e
->compiled_function_regexp
.emplace (e
->function
, flags
, message
);
211 /* Process "skip ..." that does not match "skip file" or "skip function". */
214 skip_command (char *arg
, int from_tty
)
216 const char *file
= NULL
;
217 const char *gfile
= NULL
;
218 const char *function
= NULL
;
219 const char *rfunction
= NULL
;
221 struct cleanup
*cleanups
;
222 struct skiplist_entry
*e
;
227 skip_function_command (arg
, from_tty
);
231 argv
= buildargv (arg
);
232 cleanups
= make_cleanup_freeargv (argv
);
234 for (i
= 0; argv
[i
] != NULL
; ++i
)
236 const char *p
= argv
[i
];
237 const char *value
= argv
[i
+ 1];
239 if (strcmp (p
, "-fi") == 0
240 || strcmp (p
, "-file") == 0)
243 error (_("Missing value for %s option."), p
);
247 else if (strcmp (p
, "-gfi") == 0
248 || strcmp (p
, "-gfile") == 0)
251 error (_("Missing value for %s option."), p
);
255 else if (strcmp (p
, "-fu") == 0
256 || strcmp (p
, "-function") == 0)
259 error (_("Missing value for %s option."), p
);
263 else if (strcmp (p
, "-rfu") == 0
264 || strcmp (p
, "-rfunction") == 0)
267 error (_("Missing value for %s option."), p
);
272 error (_("Invalid skip option: %s"), p
);
275 /* Assume the user entered "skip FUNCTION-NAME".
276 FUNCTION-NAME may be `foo (int)', and therefore we pass the
277 complete original arg to skip_function command as if the user
278 typed "skip function arg". */
279 do_cleanups (cleanups
);
280 skip_function_command (arg
, from_tty
);
284 error (_("Invalid argument: %s"), p
);
287 if (file
!= NULL
&& gfile
!= NULL
)
288 error (_("Cannot specify both -file and -gfile."));
290 if (function
!= NULL
&& rfunction
!= NULL
)
291 error (_("Cannot specify both -function and -rfunction."));
293 /* This shouldn't happen as "skip" by itself gets punted to
294 skip_function_command. */
295 gdb_assert (file
!= NULL
|| gfile
!= NULL
296 || function
!= NULL
|| rfunction
!= NULL
);
298 e
= make_skip_entry (gfile
!= NULL
, file
? file
: gfile
,
299 rfunction
!= NULL
, function
? function
: rfunction
);
300 if (rfunction
!= NULL
)
302 struct cleanup
*rf_cleanups
= make_free_skiplist_entry_cleanup (e
);
304 compile_skip_regexp (e
, _("regexp"));
305 discard_cleanups (rf_cleanups
);
307 add_skiplist_entry (e
);
309 /* I18N concerns drive some of the choices here (we can't piece together
310 the output too much). OTOH we want to keep this simple. Therefore the
311 only polish we add to the output is to append "(s)" to "File" or
312 "Function" if they're a glob/regexp. */
314 const char *file_to_print
= file
!= NULL
? file
: gfile
;
315 const char *function_to_print
= function
!= NULL
? function
: rfunction
;
316 const char *file_text
= gfile
!= NULL
? _("File(s)") : _("File");
317 const char *lower_file_text
= gfile
!= NULL
? _("file(s)") : _("file");
318 const char *function_text
319 = rfunction
!= NULL
? _("Function(s)") : _("Function");
321 if (function_to_print
== NULL
)
323 printf_filtered (_("%s %s will be skipped when stepping.\n"),
324 file_text
, file_to_print
);
326 else if (file_to_print
== NULL
)
328 printf_filtered (_("%s %s will be skipped when stepping.\n"),
329 function_text
, function_to_print
);
333 printf_filtered (_("%s %s in %s %s will be skipped"
334 " when stepping.\n"),
335 function_text
, function_to_print
,
336 lower_file_text
, file_to_print
);
340 do_cleanups (cleanups
);
344 skip_info (char *arg
, int from_tty
)
346 struct skiplist_entry
*e
;
347 int num_printable_entries
= 0;
348 struct value_print_options opts
;
350 get_user_print_options (&opts
);
352 /* Count the number of rows in the table and see if we need space for a
353 64-bit address anywhere. */
354 ALL_SKIPLIST_ENTRIES (e
)
355 if (arg
== NULL
|| number_is_in_list (arg
, e
->number
))
356 num_printable_entries
++;
358 if (num_printable_entries
== 0)
361 current_uiout
->message (_("Not skipping any files or functions.\n"));
363 current_uiout
->message (
364 _("No skiplist entries found with number %s.\n"), arg
);
369 ui_out_emit_table
table_emitter (current_uiout
, 6, num_printable_entries
,
372 current_uiout
->table_header (5, ui_left
, "number", "Num"); /* 1 */
373 current_uiout
->table_header (3, ui_left
, "enabled", "Enb"); /* 2 */
374 current_uiout
->table_header (4, ui_right
, "regexp", "Glob"); /* 3 */
375 current_uiout
->table_header (20, ui_left
, "file", "File"); /* 4 */
376 current_uiout
->table_header (2, ui_right
, "regexp", "RE"); /* 5 */
377 current_uiout
->table_header (40, ui_noalign
, "function", "Function"); /* 6 */
378 current_uiout
->table_body ();
380 ALL_SKIPLIST_ENTRIES (e
)
384 if (arg
!= NULL
&& !number_is_in_list (arg
, e
->number
))
387 ui_out_emit_tuple
tuple_emitter (current_uiout
, "blklst-entry");
388 current_uiout
->field_int ("number", e
->number
); /* 1 */
391 current_uiout
->field_string ("enabled", "y"); /* 2 */
393 current_uiout
->field_string ("enabled", "n"); /* 2 */
396 current_uiout
->field_string ("regexp", "y"); /* 3 */
398 current_uiout
->field_string ("regexp", "n"); /* 3 */
400 current_uiout
->field_string ("file",
401 e
->file
? e
->file
: "<none>"); /* 4 */
402 if (e
->function_is_regexp
)
403 current_uiout
->field_string ("regexp", "y"); /* 5 */
405 current_uiout
->field_string ("regexp", "n"); /* 5 */
407 current_uiout
->field_string (
408 "function", e
->function
? e
->function
: "<none>"); /* 6 */
410 current_uiout
->text ("\n");
415 skip_enable_command (char *arg
, int from_tty
)
417 struct skiplist_entry
*e
;
420 ALL_SKIPLIST_ENTRIES (e
)
421 if (arg
== NULL
|| number_is_in_list (arg
, e
->number
))
428 error (_("No skiplist entries found with number %s."), arg
);
432 skip_disable_command (char *arg
, int from_tty
)
434 struct skiplist_entry
*e
;
437 ALL_SKIPLIST_ENTRIES (e
)
438 if (arg
== NULL
|| number_is_in_list (arg
, e
->number
))
445 error (_("No skiplist entries found with number %s."), arg
);
449 skip_delete_command (char *arg
, int from_tty
)
451 struct skiplist_entry
*e
, *temp
, *b_prev
;
455 ALL_SKIPLIST_ENTRIES_SAFE (e
, temp
)
456 if (arg
== NULL
|| number_is_in_list (arg
, e
->number
))
459 b_prev
->next
= e
->next
;
461 skiplist_entry_chain
= e
->next
;
463 free_skiplist_entry (e
);
472 error (_("No skiplist entries found with number %s."), arg
);
475 /* Add the given skiplist entry to our list, and set the entry's number. */
478 add_skiplist_entry (struct skiplist_entry
*e
)
480 struct skiplist_entry
*e1
;
482 e
->number
= ++skiplist_entry_count
;
484 /* Add to the end of the chain so that the list of
485 skiplist entries will be in numerical order. */
487 e1
= skiplist_entry_chain
;
489 skiplist_entry_chain
= e
;
498 /* Return non-zero if we're stopped at a file to be skipped. */
501 skip_file_p (struct skiplist_entry
*e
,
502 const struct symtab_and_line
*function_sal
)
504 gdb_assert (e
->file
!= NULL
&& !e
->file_is_glob
);
506 if (function_sal
->symtab
== NULL
)
509 /* Check first sole SYMTAB->FILENAME. It may not be a substring of
510 symtab_to_fullname as it may contain "./" etc. */
511 if (compare_filenames_for_search (function_sal
->symtab
->filename
, e
->file
))
514 /* Before we invoke realpath, which can get expensive when many
515 files are involved, do a quick comparison of the basenames. */
516 if (!basenames_may_differ
517 && filename_cmp (lbasename (function_sal
->symtab
->filename
),
518 lbasename (e
->file
)) != 0)
521 /* Note: symtab_to_fullname caches its result, thus we don't have to. */
523 const char *fullname
= symtab_to_fullname (function_sal
->symtab
);
525 if (compare_filenames_for_search (fullname
, e
->file
))
532 /* Return non-zero if we're stopped at a globbed file to be skipped. */
535 skip_gfile_p (struct skiplist_entry
*e
,
536 const struct symtab_and_line
*function_sal
)
538 gdb_assert (e
->file
!= NULL
&& e
->file_is_glob
);
540 if (function_sal
->symtab
== NULL
)
543 /* Check first sole SYMTAB->FILENAME. It may not be a substring of
544 symtab_to_fullname as it may contain "./" etc. */
545 if (gdb_filename_fnmatch (e
->file
, function_sal
->symtab
->filename
,
546 FNM_FILE_NAME
| FNM_NOESCAPE
) == 0)
549 /* Before we invoke symtab_to_fullname, which is expensive, do a quick
550 comparison of the basenames.
551 Note that we assume that lbasename works with glob-style patterns.
552 If the basename of the glob pattern is something like "*.c" then this
553 isn't much of a win. Oh well. */
554 if (!basenames_may_differ
555 && gdb_filename_fnmatch (lbasename (e
->file
),
556 lbasename (function_sal
->symtab
->filename
),
557 FNM_FILE_NAME
| FNM_NOESCAPE
) != 0)
560 /* Note: symtab_to_fullname caches its result, thus we don't have to. */
562 const char *fullname
= symtab_to_fullname (function_sal
->symtab
);
564 if (compare_glob_filenames_for_search (fullname
, e
->file
))
571 /* Return non-zero if we're stopped at a function to be skipped. */
574 skip_function_p (struct skiplist_entry
*e
, const char *function_name
)
576 gdb_assert (e
->function
!= NULL
&& !e
->function_is_regexp
);
577 return strcmp_iw (function_name
, e
->function
) == 0;
580 /* Return non-zero if we're stopped at a function regexp to be skipped. */
583 skip_rfunction_p (struct skiplist_entry
*e
, const char *function_name
)
585 gdb_assert (e
->function
!= NULL
&& e
->function_is_regexp
586 && e
->compiled_function_regexp
);
587 return (e
->compiled_function_regexp
->exec (function_name
, 0, NULL
, 0)
594 function_name_is_marked_for_skip (const char *function_name
,
595 const struct symtab_and_line
*function_sal
)
597 struct skiplist_entry
*e
;
599 if (function_name
== NULL
)
602 ALL_SKIPLIST_ENTRIES (e
)
604 int skip_by_file
= 0;
605 int skip_by_function
= 0;
614 if (skip_gfile_p (e
, function_sal
))
619 if (skip_file_p (e
, function_sal
))
623 if (e
->function
!= NULL
)
625 if (e
->function_is_regexp
)
627 if (skip_rfunction_p (e
, function_name
))
628 skip_by_function
= 1;
632 if (skip_function_p (e
, function_name
))
633 skip_by_function
= 1;
637 /* If both file and function must match, make sure we don't errantly
638 exit if only one of them match. */
639 if (e
->file
!= NULL
&& e
->function
!= NULL
)
641 if (skip_by_file
&& skip_by_function
)
644 /* Only one of file/function is specified. */
645 else if (skip_by_file
|| skip_by_function
)
652 /* Provide a prototype to silence -Wmissing-prototypes. */
653 extern initialize_file_ftype _initialize_step_skip
;
656 _initialize_step_skip (void)
658 static struct cmd_list_element
*skiplist
= NULL
;
659 struct cmd_list_element
*c
;
661 skiplist_entry_chain
= 0;
662 skiplist_entry_count
= 0;
664 add_prefix_cmd ("skip", class_breakpoint
, skip_command
, _("\
665 Ignore a function while stepping.\n\
667 Usage: skip [FUNCTION-NAME]\n\
668 skip [<file-spec>] [<function-spec>]\n\
669 If no arguments are given, ignore the current function.\n\
671 <file-spec> is one of:\n\
672 -fi|-file FILE-NAME\n\
673 -gfi|-gfile GLOB-FILE-PATTERN\n\
674 <function-spec> is one of:\n\
675 -fu|-function FUNCTION-NAME\n\
676 -rfu|-rfunction FUNCTION-NAME-REGULAR-EXPRESSION"),
677 &skiplist
, "skip ", 1, &cmdlist
);
679 c
= add_cmd ("file", class_breakpoint
, skip_file_command
, _("\
680 Ignore a file while stepping.\n\
681 Usage: skip file [FILE-NAME]\n\
682 If no filename is given, ignore the current file."),
684 set_cmd_completer (c
, filename_completer
);
686 c
= add_cmd ("function", class_breakpoint
, skip_function_command
, _("\
687 Ignore a function while stepping.\n\
688 Usage: skip function [FUNCTION-NAME]\n\
689 If no function name is given, skip the current function."),
691 set_cmd_completer (c
, location_completer
);
693 add_cmd ("enable", class_breakpoint
, skip_enable_command
, _("\
694 Enable skip entries. You can specify numbers (e.g. \"skip enable 1 3\"), \
695 ranges (e.g. \"skip enable 4-8\"), or both (e.g. \"skip enable 1 3 4-8\").\n\n\
696 If you don't specify any numbers or ranges, we'll enable all skip entries.\n\n\
697 Usage: skip enable [NUMBERS AND/OR RANGES]"),
700 add_cmd ("disable", class_breakpoint
, skip_disable_command
, _("\
701 Disable skip entries. You can specify numbers (e.g. \"skip disable 1 3\"), \
702 ranges (e.g. \"skip disable 4-8\"), or both (e.g. \"skip disable 1 3 4-8\").\n\n\
703 If you don't specify any numbers or ranges, we'll disable all skip entries.\n\n\
704 Usage: skip disable [NUMBERS AND/OR RANGES]"),
707 add_cmd ("delete", class_breakpoint
, skip_delete_command
, _("\
708 Delete skip entries. You can specify numbers (e.g. \"skip delete 1 3\"), \
709 ranges (e.g. \"skip delete 4-8\"), or both (e.g. \"skip delete 1 3 4-8\").\n\n\
710 If you don't specify any numbers or ranges, we'll delete all skip entries.\n\n\
711 Usage: skip delete [NUMBERS AND/OR RANGES]"),
714 add_info ("skip", skip_info
, _("\
715 Display the status of skips. You can specify numbers (e.g. \"skip info 1 3\"), \
716 ranges (e.g. \"skip info 4-8\"), or both (e.g. \"skip info 1 3 4-8\").\n\n\
717 If you don't specify any numbers or ranges, we'll show all skips.\n\n\
718 Usage: skip info [NUMBERS AND/OR RANGES]\n\
719 The \"Type\" column indicates one of:\n\
720 \tfile - ignored file\n\
721 \tfunction - ignored function"));