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 /* Create a skiplist_entry object and add it to the chain. */
44 static void add_entry (bool file_is_glob
,
46 bool function_is_regexp
,
47 std::string
&&function
);
49 /* Return true if the skip entry has a file or glob-style file
50 pattern that matches FUNCTION_SAL. */
51 bool skip_file_p (const symtab_and_line
&function_sal
) const;
53 /* Return true if the skip entry has a function or function regexp
54 that matches FUNCTION_NAME. */
55 bool skip_function_p (const char *function_name
) const;
58 int number () const { return m_number
; };
59 bool enabled () const { return m_enabled
; };
60 bool file_is_glob () const { return m_file_is_glob
; }
61 const std::string
&file () const { return m_file
; }
62 const std::string
&function () const { return m_function
; }
63 bool function_is_regexp () const { return m_function_is_regexp
; }
66 void enable () { m_enabled
= true; };
67 void disable () { m_enabled
= false; };
70 skiplist_entry (const skiplist_entry
&) = delete;
71 void operator= (const skiplist_entry
&) = delete;
74 /* Key that grants access to the constructor. */
75 struct private_key
{};
77 /* Public so we can construct with container::emplace_back. Since
78 it requires a private class key, it can't be called from outside.
79 Use the add_entry static factory method to construct instead. */
80 skiplist_entry (bool file_is_glob
, std::string
&&file
,
81 bool function_is_regexp
, std::string
&&function
,
85 /* Return true if we're stopped at a file to be skipped. */
86 bool do_skip_file_p (const symtab_and_line
&function_sal
) const;
88 /* Return true if we're stopped at a globbed file to be skipped. */
89 bool do_skip_gfile_p (const symtab_and_line
&function_sal
) const;
94 /* True if FILE is a glob-style pattern.
95 Otherwise it is the plain file name (possibly with directories). */
98 /* The name of the file or empty if no name. */
101 /* True if FUNCTION is a regexp.
102 Otherwise it is a plain function name (possibly with arguments,
104 bool m_function_is_regexp
;
106 /* The name of the function or empty if no name. */
107 std::string m_function
;
109 /* If this is a function regexp, the compiled form. */
110 gdb::optional
<compiled_regex
> m_compiled_function_regexp
;
112 /* Enabled/disabled state. */
113 bool m_enabled
= true;
116 static std::list
<skiplist_entry
> skiplist_entries
;
117 static int highest_skiplist_entry_num
= 0;
119 skiplist_entry::skiplist_entry (bool file_is_glob
,
121 bool function_is_regexp
,
122 std::string
&&function
,
124 : m_file_is_glob (file_is_glob
),
125 m_file (std::move (file
)),
126 m_function_is_regexp (function_is_regexp
),
127 m_function (std::move (function
))
129 gdb_assert (!m_file
.empty () || !m_function
.empty ());
132 gdb_assert (!m_file
.empty ());
134 if (m_function_is_regexp
)
136 gdb_assert (!m_function
.empty ());
138 int flags
= REG_NOSUB
;
140 flags
|= REG_EXTENDED
;
143 gdb_assert (!m_function
.empty ());
144 m_compiled_function_regexp
.emplace (m_function
.c_str (), flags
,
150 skiplist_entry::add_entry (bool file_is_glob
, std::string
&&file
,
151 bool function_is_regexp
, std::string
&&function
)
153 skiplist_entries
.emplace_back (file_is_glob
,
156 std::move (function
),
159 /* Incremented after push_back, in case push_back throws. */
160 skiplist_entries
.back ().m_number
= ++highest_skiplist_entry_num
;
164 skip_file_command (const char *arg
, int from_tty
)
166 struct symtab
*symtab
;
167 const char *filename
= NULL
;
169 /* If no argument was given, try to default to the last
170 displayed codepoint. */
173 symtab
= get_last_displayed_symtab ();
175 error (_("No default file now."));
177 /* It is not a typo, symtab_to_filename_for_display woule be needlessly
179 filename
= symtab_to_fullname (symtab
);
184 skiplist_entry::add_entry (false, std::string (filename
),
185 false, std::string ());
187 printf_filtered (_("File %s will be skipped when stepping.\n"), filename
);
190 /* Create a skiplist entry for the given function NAME and add it to the
194 skip_function (const char *name
)
196 skiplist_entry::add_entry (false, std::string (), false, std::string (name
));
198 printf_filtered (_("Function %s will be skipped when stepping.\n"), name
);
202 skip_function_command (const char *arg
, int from_tty
)
204 /* Default to the current function if no argument is given. */
207 const char *name
= NULL
;
210 if (!last_displayed_sal_is_valid ())
211 error (_("No default function now."));
213 pc
= get_last_displayed_addr ();
214 if (!find_pc_partial_function (pc
, &name
, NULL
, NULL
))
216 error (_("No function found containing current program point %s."),
217 paddress (get_current_arch (), pc
));
219 skip_function (name
);
226 /* Process "skip ..." that does not match "skip file" or "skip function". */
229 skip_command (const char *arg
, int from_tty
)
231 const char *file
= NULL
;
232 const char *gfile
= NULL
;
233 const char *function
= NULL
;
234 const char *rfunction
= NULL
;
239 skip_function_command (arg
, from_tty
);
245 for (i
= 0; argv
[i
] != NULL
; ++i
)
247 const char *p
= argv
[i
];
248 const char *value
= argv
[i
+ 1];
250 if (strcmp (p
, "-fi") == 0
251 || strcmp (p
, "-file") == 0)
254 error (_("Missing value for %s option."), p
);
258 else if (strcmp (p
, "-gfi") == 0
259 || strcmp (p
, "-gfile") == 0)
262 error (_("Missing value for %s option."), p
);
266 else if (strcmp (p
, "-fu") == 0
267 || strcmp (p
, "-function") == 0)
270 error (_("Missing value for %s option."), p
);
274 else if (strcmp (p
, "-rfu") == 0
275 || strcmp (p
, "-rfunction") == 0)
278 error (_("Missing value for %s option."), p
);
283 error (_("Invalid skip option: %s"), p
);
286 /* Assume the user entered "skip FUNCTION-NAME".
287 FUNCTION-NAME may be `foo (int)', and therefore we pass the
288 complete original arg to skip_function command as if the user
289 typed "skip function arg". */
290 skip_function_command (arg
, from_tty
);
294 error (_("Invalid argument: %s"), p
);
297 if (file
!= NULL
&& gfile
!= NULL
)
298 error (_("Cannot specify both -file and -gfile."));
300 if (function
!= NULL
&& rfunction
!= NULL
)
301 error (_("Cannot specify both -function and -rfunction."));
303 /* This shouldn't happen as "skip" by itself gets punted to
304 skip_function_command. */
305 gdb_assert (file
!= NULL
|| gfile
!= NULL
306 || function
!= NULL
|| rfunction
!= NULL
);
308 std::string entry_file
;
311 else if (gfile
!= NULL
)
314 std::string entry_function
;
315 if (function
!= NULL
)
316 entry_function
= function
;
317 else if (rfunction
!= NULL
)
318 entry_function
= rfunction
;
320 skiplist_entry::add_entry (gfile
!= NULL
, std::move (entry_file
),
321 rfunction
!= NULL
, std::move (entry_function
));
323 /* I18N concerns drive some of the choices here (we can't piece together
324 the output too much). OTOH we want to keep this simple. Therefore the
325 only polish we add to the output is to append "(s)" to "File" or
326 "Function" if they're a glob/regexp. */
328 const char *file_to_print
= file
!= NULL
? file
: gfile
;
329 const char *function_to_print
= function
!= NULL
? function
: rfunction
;
330 const char *file_text
= gfile
!= NULL
? _("File(s)") : _("File");
331 const char *lower_file_text
= gfile
!= NULL
? _("file(s)") : _("file");
332 const char *function_text
333 = rfunction
!= NULL
? _("Function(s)") : _("Function");
335 if (function_to_print
== NULL
)
337 printf_filtered (_("%s %s will be skipped when stepping.\n"),
338 file_text
, file_to_print
);
340 else if (file_to_print
== NULL
)
342 printf_filtered (_("%s %s will be skipped when stepping.\n"),
343 function_text
, function_to_print
);
347 printf_filtered (_("%s %s in %s %s will be skipped"
348 " when stepping.\n"),
349 function_text
, function_to_print
,
350 lower_file_text
, file_to_print
);
356 info_skip_command (const char *arg
, int from_tty
)
358 int num_printable_entries
= 0;
359 struct value_print_options opts
;
361 get_user_print_options (&opts
);
363 /* Count the number of rows in the table and see if we need space for a
364 64-bit address anywhere. */
365 for (const skiplist_entry
&e
: skiplist_entries
)
366 if (arg
== NULL
|| number_is_in_list (arg
, e
.number ()))
367 num_printable_entries
++;
369 if (num_printable_entries
== 0)
372 current_uiout
->message (_("Not skipping any files or functions.\n"));
374 current_uiout
->message (
375 _("No skiplist entries found with number %s.\n"), arg
);
380 ui_out_emit_table
table_emitter (current_uiout
, 6, num_printable_entries
,
383 current_uiout
->table_header (5, ui_left
, "number", "Num"); /* 1 */
384 current_uiout
->table_header (3, ui_left
, "enabled", "Enb"); /* 2 */
385 current_uiout
->table_header (4, ui_right
, "regexp", "Glob"); /* 3 */
386 current_uiout
->table_header (20, ui_left
, "file", "File"); /* 4 */
387 current_uiout
->table_header (2, ui_right
, "regexp", "RE"); /* 5 */
388 current_uiout
->table_header (40, ui_noalign
, "function", "Function"); /* 6 */
389 current_uiout
->table_body ();
391 for (const skiplist_entry
&e
: skiplist_entries
)
394 if (arg
!= NULL
&& !number_is_in_list (arg
, e
.number ()))
397 ui_out_emit_tuple
tuple_emitter (current_uiout
, "blklst-entry");
398 current_uiout
->field_int ("number", e
.number ()); /* 1 */
401 current_uiout
->field_string ("enabled", "y"); /* 2 */
403 current_uiout
->field_string ("enabled", "n"); /* 2 */
405 if (e
.file_is_glob ())
406 current_uiout
->field_string ("regexp", "y"); /* 3 */
408 current_uiout
->field_string ("regexp", "n"); /* 3 */
410 current_uiout
->field_string ("file",
411 e
.file ().empty () ? "<none>"
412 : e
.file ().c_str ()); /* 4 */
413 if (e
.function_is_regexp ())
414 current_uiout
->field_string ("regexp", "y"); /* 5 */
416 current_uiout
->field_string ("regexp", "n"); /* 5 */
418 current_uiout
->field_string ("function",
419 e
.function ().empty () ? "<none>"
420 : e
.function ().c_str ()); /* 6 */
422 current_uiout
->text ("\n");
427 skip_enable_command (const char *arg
, int from_tty
)
431 for (skiplist_entry
&e
: skiplist_entries
)
432 if (arg
== NULL
|| number_is_in_list (arg
, e
.number ()))
439 error (_("No skiplist entries found with number %s."), arg
);
443 skip_disable_command (const char *arg
, int from_tty
)
447 for (skiplist_entry
&e
: skiplist_entries
)
448 if (arg
== NULL
|| number_is_in_list (arg
, e
.number ()))
455 error (_("No skiplist entries found with number %s."), arg
);
459 skip_delete_command (const char *arg
, int from_tty
)
463 for (auto it
= skiplist_entries
.begin (),
464 end
= skiplist_entries
.end ();
467 const skiplist_entry
&e
= *it
;
469 if (arg
== NULL
|| number_is_in_list (arg
, e
.number ()))
471 it
= skiplist_entries
.erase (it
);
479 error (_("No skiplist entries found with number %s."), arg
);
483 skiplist_entry::do_skip_file_p (const symtab_and_line
&function_sal
) const
485 /* Check first sole SYMTAB->FILENAME. It may not be a substring of
486 symtab_to_fullname as it may contain "./" etc. */
487 if (compare_filenames_for_search (function_sal
.symtab
->filename
,
491 /* Before we invoke realpath, which can get expensive when many
492 files are involved, do a quick comparison of the basenames. */
493 if (!basenames_may_differ
494 && filename_cmp (lbasename (function_sal
.symtab
->filename
),
495 lbasename (m_file
.c_str ())) != 0)
498 /* Note: symtab_to_fullname caches its result, thus we don't have to. */
500 const char *fullname
= symtab_to_fullname (function_sal
.symtab
);
502 if (compare_filenames_for_search (fullname
, m_file
.c_str ()))
510 skiplist_entry::do_skip_gfile_p (const symtab_and_line
&function_sal
) const
512 /* Check first sole SYMTAB->FILENAME. It may not be a substring of
513 symtab_to_fullname as it may contain "./" etc. */
514 if (gdb_filename_fnmatch (m_file
.c_str (), function_sal
.symtab
->filename
,
515 FNM_FILE_NAME
| FNM_NOESCAPE
) == 0)
518 /* Before we invoke symtab_to_fullname, which is expensive, do a quick
519 comparison of the basenames.
520 Note that we assume that lbasename works with glob-style patterns.
521 If the basename of the glob pattern is something like "*.c" then this
522 isn't much of a win. Oh well. */
523 if (!basenames_may_differ
524 && gdb_filename_fnmatch (lbasename (m_file
.c_str ()),
525 lbasename (function_sal
.symtab
->filename
),
526 FNM_FILE_NAME
| FNM_NOESCAPE
) != 0)
529 /* Note: symtab_to_fullname caches its result, thus we don't have to. */
531 const char *fullname
= symtab_to_fullname (function_sal
.symtab
);
533 if (compare_glob_filenames_for_search (fullname
, m_file
.c_str ()))
541 skiplist_entry::skip_file_p (const symtab_and_line
&function_sal
) const
546 if (function_sal
.symtab
== NULL
)
550 return do_skip_gfile_p (function_sal
);
552 return do_skip_file_p (function_sal
);
556 skiplist_entry::skip_function_p (const char *function_name
) const
558 if (m_function
.empty ())
561 if (m_function_is_regexp
)
563 gdb_assert (m_compiled_function_regexp
);
564 return (m_compiled_function_regexp
->exec (function_name
, 0, NULL
, 0)
568 return strcmp_iw (function_name
, m_function
.c_str ()) == 0;
574 function_name_is_marked_for_skip (const char *function_name
,
575 const symtab_and_line
&function_sal
)
577 if (function_name
== NULL
)
580 for (const skiplist_entry
&e
: skiplist_entries
)
585 bool skip_by_file
= e
.skip_file_p (function_sal
);
586 bool skip_by_function
= e
.skip_function_p (function_name
);
588 /* If both file and function must match, make sure we don't errantly
589 exit if only one of them match. */
590 if (!e
.file ().empty () && !e
.function ().empty ())
592 if (skip_by_file
&& skip_by_function
)
595 /* Only one of file/function is specified. */
596 else if (skip_by_file
|| skip_by_function
)
604 _initialize_step_skip (void)
606 static struct cmd_list_element
*skiplist
= NULL
;
607 struct cmd_list_element
*c
;
609 add_prefix_cmd ("skip", class_breakpoint
, skip_command
, _("\
610 Ignore a function while stepping.\n\
612 Usage: skip [FUNCTION-NAME]\n\
613 skip [<file-spec>] [<function-spec>]\n\
614 If no arguments are given, ignore the current function.\n\
616 <file-spec> is one of:\n\
617 -fi|-file FILE-NAME\n\
618 -gfi|-gfile GLOB-FILE-PATTERN\n\
619 <function-spec> is one of:\n\
620 -fu|-function FUNCTION-NAME\n\
621 -rfu|-rfunction FUNCTION-NAME-REGULAR-EXPRESSION"),
622 &skiplist
, "skip ", 1, &cmdlist
);
624 c
= add_cmd ("file", class_breakpoint
, skip_file_command
, _("\
625 Ignore a file while stepping.\n\
626 Usage: skip file [FILE-NAME]\n\
627 If no filename is given, ignore the current file."),
629 set_cmd_completer (c
, filename_completer
);
631 c
= add_cmd ("function", class_breakpoint
, skip_function_command
, _("\
632 Ignore a function while stepping.\n\
633 Usage: skip function [FUNCTION-NAME]\n\
634 If no function name is given, skip the current function."),
636 set_cmd_completer (c
, location_completer
);
638 add_cmd ("enable", class_breakpoint
, skip_enable_command
, _("\
639 Enable skip entries. You can specify numbers (e.g. \"skip enable 1 3\"), \
640 ranges (e.g. \"skip enable 4-8\"), or both (e.g. \"skip enable 1 3 4-8\").\n\n\
641 If you don't specify any numbers or ranges, we'll enable all skip entries.\n\n\
642 Usage: skip enable [NUMBERS AND/OR RANGES]"),
645 add_cmd ("disable", class_breakpoint
, skip_disable_command
, _("\
646 Disable skip entries. You can specify numbers (e.g. \"skip disable 1 3\"), \
647 ranges (e.g. \"skip disable 4-8\"), or both (e.g. \"skip disable 1 3 4-8\").\n\n\
648 If you don't specify any numbers or ranges, we'll disable all skip entries.\n\n\
649 Usage: skip disable [NUMBERS AND/OR RANGES]"),
652 add_cmd ("delete", class_breakpoint
, skip_delete_command
, _("\
653 Delete skip entries. You can specify numbers (e.g. \"skip delete 1 3\"), \
654 ranges (e.g. \"skip delete 4-8\"), or both (e.g. \"skip delete 1 3 4-8\").\n\n\
655 If you don't specify any numbers or ranges, we'll delete all skip entries.\n\n\
656 Usage: skip delete [NUMBERS AND/OR RANGES]"),
659 add_info ("skip", info_skip_command
, _("\
660 Display the status of skips. You can specify numbers (e.g. \"skip info 1 3\"), \
661 ranges (e.g. \"skip info 4-8\"), or both (e.g. \"skip info 1 3 4-8\").\n\n\
662 If you don't specify any numbers or ranges, we'll show all skips.\n\n\
663 Usage: skip info [NUMBERS AND/OR RANGES]\n\
664 The \"Type\" column indicates one of:\n\
665 \tfile - ignored file\n\
666 \tfunction - ignored function"));