]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/skip.c
Introduce compiled_regex, eliminate make_regfree_cleanup
[thirdparty/binutils-gdb.git] / gdb / skip.c
1 /* Skipping uninteresting files and functions while stepping.
2
3 Copyright (C) 2011-2017 Free Software Foundation, Inc.
4
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.
9
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.
14
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/>. */
17
18 #include "defs.h"
19 #include "skip.h"
20 #include "value.h"
21 #include "valprint.h"
22 #include "ui-out.h"
23 #include "symtab.h"
24 #include "gdbcmd.h"
25 #include "command.h"
26 #include "completer.h"
27 #include "stack.h"
28 #include "cli/cli-utils.h"
29 #include "arch-utils.h"
30 #include "linespec.h"
31 #include "objfiles.h"
32 #include "breakpoint.h" /* for get_sal_arch () */
33 #include "source.h"
34 #include "filenames.h"
35 #include "fnmatch.h"
36 #include "gdb_regex.h"
37 #include "common/gdb_optional.h"
38
39 struct skiplist_entry
40 {
41 int number;
42
43 /* Non-zero if FILE is a glob-style pattern.
44 Otherewise it is the plain file name (possibly with directories). */
45 int file_is_glob;
46
47 /* The name of the file or NULL.
48 The skiplist entry owns this pointer. */
49 char *file;
50
51 /* Non-zero if FUNCTION is a regexp.
52 Otherwise it is a plain function name (possibly with arguments,
53 for C++). */
54 int function_is_regexp;
55
56 /* The name of the function or NULL.
57 The skiplist entry owns this pointer. */
58 char *function;
59
60 /* If this is a function regexp, the compiled form. */
61 gdb::optional<compiled_regex> compiled_function_regexp;
62
63 int enabled;
64
65 struct skiplist_entry *next;
66 };
67
68 static void add_skiplist_entry (struct skiplist_entry *e);
69
70 static struct skiplist_entry *skiplist_entry_chain;
71 static int skiplist_entry_count;
72
73 #define ALL_SKIPLIST_ENTRIES(E) \
74 for (E = skiplist_entry_chain; E; E = E->next)
75
76 #define ALL_SKIPLIST_ENTRIES_SAFE(E,TMP) \
77 for (E = skiplist_entry_chain; \
78 E ? (TMP = E->next, 1) : 0; \
79 E = TMP)
80
81 /* Create a skip object. */
82
83 static struct skiplist_entry *
84 make_skip_entry (int file_is_glob, const char *file,
85 int function_is_regexp, const char *function)
86 {
87 struct skiplist_entry *e = XCNEW (struct skiplist_entry);
88
89 gdb_assert (file != NULL || function != NULL);
90 if (file_is_glob)
91 gdb_assert (file != NULL);
92 if (function_is_regexp)
93 gdb_assert (function != NULL);
94
95 if (file != NULL)
96 e->file = xstrdup (file);
97 if (function != NULL)
98 e->function = xstrdup (function);
99 e->file_is_glob = file_is_glob;
100 e->function_is_regexp = function_is_regexp;
101 e->enabled = 1;
102
103 return e;
104 }
105
106 /* Free a skiplist entry. */
107
108 static void
109 free_skiplist_entry (struct skiplist_entry *e)
110 {
111 xfree (e->file);
112 xfree (e->function);
113 xfree (e);
114 }
115
116 /* Wrapper to free_skiplist_entry for use as a cleanup. */
117
118 static void
119 free_skiplist_entry_cleanup (void *e)
120 {
121 free_skiplist_entry ((struct skiplist_entry *) e);
122 }
123
124 /* Create a cleanup to free skiplist entry E. */
125
126 static struct cleanup *
127 make_free_skiplist_entry_cleanup (struct skiplist_entry *e)
128 {
129 return make_cleanup (free_skiplist_entry_cleanup, e);
130 }
131
132 static void
133 skip_file_command (char *arg, int from_tty)
134 {
135 struct symtab *symtab;
136 const char *filename = NULL;
137
138 /* If no argument was given, try to default to the last
139 displayed codepoint. */
140 if (arg == NULL)
141 {
142 symtab = get_last_displayed_symtab ();
143 if (symtab == NULL)
144 error (_("No default file now."));
145
146 /* It is not a typo, symtab_to_filename_for_display woule be needlessly
147 ambiguous. */
148 filename = symtab_to_fullname (symtab);
149 }
150 else
151 filename = arg;
152
153 add_skiplist_entry (make_skip_entry (0, filename, 0, NULL));
154
155 printf_filtered (_("File %s will be skipped when stepping.\n"), filename);
156 }
157
158 /* Create a skiplist entry for the given function NAME and add it to the
159 list. */
160
161 static void
162 skip_function (const char *name)
163 {
164 add_skiplist_entry (make_skip_entry (0, NULL, 0, name));
165
166 printf_filtered (_("Function %s will be skipped when stepping.\n"), name);
167 }
168
169 static void
170 skip_function_command (char *arg, int from_tty)
171 {
172 /* Default to the current function if no argument is given. */
173 if (arg == NULL)
174 {
175 const char *name = NULL;
176 CORE_ADDR pc;
177
178 if (!last_displayed_sal_is_valid ())
179 error (_("No default function now."));
180
181 pc = get_last_displayed_addr ();
182 if (!find_pc_partial_function (pc, &name, NULL, NULL))
183 {
184 error (_("No function found containing current program point %s."),
185 paddress (get_current_arch (), pc));
186 }
187 skip_function (name);
188 return;
189 }
190
191 skip_function (arg);
192 }
193
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. */
197
198 static void
199 compile_skip_regexp (struct skiplist_entry *e, const char *message)
200 {
201 int flags = REG_NOSUB;
202
203 #ifdef REG_EXTENDED
204 flags |= REG_EXTENDED;
205 #endif
206
207 gdb_assert (e->function_is_regexp && e->function != NULL);
208 e->compiled_function_regexp.emplace (e->function, flags, message);
209 }
210
211 /* Process "skip ..." that does not match "skip file" or "skip function". */
212
213 static void
214 skip_command (char *arg, int from_tty)
215 {
216 const char *file = NULL;
217 const char *gfile = NULL;
218 const char *function = NULL;
219 const char *rfunction = NULL;
220 char **argv;
221 struct cleanup *cleanups;
222 struct skiplist_entry *e;
223 int i;
224
225 if (arg == NULL)
226 {
227 skip_function_command (arg, from_tty);
228 return;
229 }
230
231 argv = buildargv (arg);
232 cleanups = make_cleanup_freeargv (argv);
233
234 for (i = 0; argv[i] != NULL; ++i)
235 {
236 const char *p = argv[i];
237 const char *value = argv[i + 1];
238
239 if (strcmp (p, "-fi") == 0
240 || strcmp (p, "-file") == 0)
241 {
242 if (value == NULL)
243 error (_("Missing value for %s option."), p);
244 file = value;
245 ++i;
246 }
247 else if (strcmp (p, "-gfi") == 0
248 || strcmp (p, "-gfile") == 0)
249 {
250 if (value == NULL)
251 error (_("Missing value for %s option."), p);
252 gfile = value;
253 ++i;
254 }
255 else if (strcmp (p, "-fu") == 0
256 || strcmp (p, "-function") == 0)
257 {
258 if (value == NULL)
259 error (_("Missing value for %s option."), p);
260 function = value;
261 ++i;
262 }
263 else if (strcmp (p, "-rfu") == 0
264 || strcmp (p, "-rfunction") == 0)
265 {
266 if (value == NULL)
267 error (_("Missing value for %s option."), p);
268 rfunction = value;
269 ++i;
270 }
271 else if (*p == '-')
272 error (_("Invalid skip option: %s"), p);
273 else if (i == 0)
274 {
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);
281 return;
282 }
283 else
284 error (_("Invalid argument: %s"), p);
285 }
286
287 if (file != NULL && gfile != NULL)
288 error (_("Cannot specify both -file and -gfile."));
289
290 if (function != NULL && rfunction != NULL)
291 error (_("Cannot specify both -function and -rfunction."));
292
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);
297
298 e = make_skip_entry (gfile != NULL, file ? file : gfile,
299 rfunction != NULL, function ? function : rfunction);
300 if (rfunction != NULL)
301 {
302 struct cleanup *rf_cleanups = make_free_skiplist_entry_cleanup (e);
303
304 compile_skip_regexp (e, _("regexp"));
305 discard_cleanups (rf_cleanups);
306 }
307 add_skiplist_entry (e);
308
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. */
313 {
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");
320
321 if (function_to_print == NULL)
322 {
323 printf_filtered (_("%s %s will be skipped when stepping.\n"),
324 file_text, file_to_print);
325 }
326 else if (file_to_print == NULL)
327 {
328 printf_filtered (_("%s %s will be skipped when stepping.\n"),
329 function_text, function_to_print);
330 }
331 else
332 {
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);
337 }
338 }
339
340 do_cleanups (cleanups);
341 }
342
343 static void
344 skip_info (char *arg, int from_tty)
345 {
346 struct skiplist_entry *e;
347 int num_printable_entries = 0;
348 struct value_print_options opts;
349 struct cleanup *tbl_chain;
350
351 get_user_print_options (&opts);
352
353 /* Count the number of rows in the table and see if we need space for a
354 64-bit address anywhere. */
355 ALL_SKIPLIST_ENTRIES (e)
356 if (arg == NULL || number_is_in_list (arg, e->number))
357 num_printable_entries++;
358
359 if (num_printable_entries == 0)
360 {
361 if (arg == NULL)
362 current_uiout->message (_("Not skipping any files or functions.\n"));
363 else
364 current_uiout->message (
365 _("No skiplist entries found with number %s.\n"), arg);
366
367 return;
368 }
369
370 tbl_chain = make_cleanup_ui_out_table_begin_end (current_uiout, 6,
371 num_printable_entries,
372 "SkiplistTable");
373
374 current_uiout->table_header (5, ui_left, "number", "Num"); /* 1 */
375 current_uiout->table_header (3, ui_left, "enabled", "Enb"); /* 2 */
376 current_uiout->table_header (4, ui_right, "regexp", "Glob"); /* 3 */
377 current_uiout->table_header (20, ui_left, "file", "File"); /* 4 */
378 current_uiout->table_header (2, ui_right, "regexp", "RE"); /* 5 */
379 current_uiout->table_header (40, ui_noalign, "function", "Function"); /* 6 */
380 current_uiout->table_body ();
381
382 ALL_SKIPLIST_ENTRIES (e)
383 {
384
385 QUIT;
386 if (arg != NULL && !number_is_in_list (arg, e->number))
387 continue;
388
389 ui_out_emit_tuple tuple_emitter (current_uiout, "blklst-entry");
390 current_uiout->field_int ("number", e->number); /* 1 */
391
392 if (e->enabled)
393 current_uiout->field_string ("enabled", "y"); /* 2 */
394 else
395 current_uiout->field_string ("enabled", "n"); /* 2 */
396
397 if (e->file_is_glob)
398 current_uiout->field_string ("regexp", "y"); /* 3 */
399 else
400 current_uiout->field_string ("regexp", "n"); /* 3 */
401
402 current_uiout->field_string ("file",
403 e->file ? e->file : "<none>"); /* 4 */
404 if (e->function_is_regexp)
405 current_uiout->field_string ("regexp", "y"); /* 5 */
406 else
407 current_uiout->field_string ("regexp", "n"); /* 5 */
408
409 current_uiout->field_string (
410 "function", e->function ? e->function : "<none>"); /* 6 */
411
412 current_uiout->text ("\n");
413 }
414
415 do_cleanups (tbl_chain);
416 }
417
418 static void
419 skip_enable_command (char *arg, int from_tty)
420 {
421 struct skiplist_entry *e;
422 int found = 0;
423
424 ALL_SKIPLIST_ENTRIES (e)
425 if (arg == NULL || number_is_in_list (arg, e->number))
426 {
427 e->enabled = 1;
428 found = 1;
429 }
430
431 if (!found)
432 error (_("No skiplist entries found with number %s."), arg);
433 }
434
435 static void
436 skip_disable_command (char *arg, int from_tty)
437 {
438 struct skiplist_entry *e;
439 int found = 0;
440
441 ALL_SKIPLIST_ENTRIES (e)
442 if (arg == NULL || number_is_in_list (arg, e->number))
443 {
444 e->enabled = 0;
445 found = 1;
446 }
447
448 if (!found)
449 error (_("No skiplist entries found with number %s."), arg);
450 }
451
452 static void
453 skip_delete_command (char *arg, int from_tty)
454 {
455 struct skiplist_entry *e, *temp, *b_prev;
456 int found = 0;
457
458 b_prev = 0;
459 ALL_SKIPLIST_ENTRIES_SAFE (e, temp)
460 if (arg == NULL || number_is_in_list (arg, e->number))
461 {
462 if (b_prev != NULL)
463 b_prev->next = e->next;
464 else
465 skiplist_entry_chain = e->next;
466
467 free_skiplist_entry (e);
468 found = 1;
469 }
470 else
471 {
472 b_prev = e;
473 }
474
475 if (!found)
476 error (_("No skiplist entries found with number %s."), arg);
477 }
478
479 /* Add the given skiplist entry to our list, and set the entry's number. */
480
481 static void
482 add_skiplist_entry (struct skiplist_entry *e)
483 {
484 struct skiplist_entry *e1;
485
486 e->number = ++skiplist_entry_count;
487
488 /* Add to the end of the chain so that the list of
489 skiplist entries will be in numerical order. */
490
491 e1 = skiplist_entry_chain;
492 if (e1 == NULL)
493 skiplist_entry_chain = e;
494 else
495 {
496 while (e1->next)
497 e1 = e1->next;
498 e1->next = e;
499 }
500 }
501
502 /* Return non-zero if we're stopped at a file to be skipped. */
503
504 static int
505 skip_file_p (struct skiplist_entry *e,
506 const struct symtab_and_line *function_sal)
507 {
508 gdb_assert (e->file != NULL && !e->file_is_glob);
509
510 if (function_sal->symtab == NULL)
511 return 0;
512
513 /* Check first sole SYMTAB->FILENAME. It may not be a substring of
514 symtab_to_fullname as it may contain "./" etc. */
515 if (compare_filenames_for_search (function_sal->symtab->filename, e->file))
516 return 1;
517
518 /* Before we invoke realpath, which can get expensive when many
519 files are involved, do a quick comparison of the basenames. */
520 if (!basenames_may_differ
521 && filename_cmp (lbasename (function_sal->symtab->filename),
522 lbasename (e->file)) != 0)
523 return 0;
524
525 /* Note: symtab_to_fullname caches its result, thus we don't have to. */
526 {
527 const char *fullname = symtab_to_fullname (function_sal->symtab);
528
529 if (compare_filenames_for_search (fullname, e->file))
530 return 1;
531 }
532
533 return 0;
534 }
535
536 /* Return non-zero if we're stopped at a globbed file to be skipped. */
537
538 static int
539 skip_gfile_p (struct skiplist_entry *e,
540 const struct symtab_and_line *function_sal)
541 {
542 gdb_assert (e->file != NULL && e->file_is_glob);
543
544 if (function_sal->symtab == NULL)
545 return 0;
546
547 /* Check first sole SYMTAB->FILENAME. It may not be a substring of
548 symtab_to_fullname as it may contain "./" etc. */
549 if (gdb_filename_fnmatch (e->file, function_sal->symtab->filename,
550 FNM_FILE_NAME | FNM_NOESCAPE) == 0)
551 return 1;
552
553 /* Before we invoke symtab_to_fullname, which is expensive, do a quick
554 comparison of the basenames.
555 Note that we assume that lbasename works with glob-style patterns.
556 If the basename of the glob pattern is something like "*.c" then this
557 isn't much of a win. Oh well. */
558 if (!basenames_may_differ
559 && gdb_filename_fnmatch (lbasename (e->file),
560 lbasename (function_sal->symtab->filename),
561 FNM_FILE_NAME | FNM_NOESCAPE) != 0)
562 return 0;
563
564 /* Note: symtab_to_fullname caches its result, thus we don't have to. */
565 {
566 const char *fullname = symtab_to_fullname (function_sal->symtab);
567
568 if (compare_glob_filenames_for_search (fullname, e->file))
569 return 1;
570 }
571
572 return 0;
573 }
574
575 /* Return non-zero if we're stopped at a function to be skipped. */
576
577 static int
578 skip_function_p (struct skiplist_entry *e, const char *function_name)
579 {
580 gdb_assert (e->function != NULL && !e->function_is_regexp);
581 return strcmp_iw (function_name, e->function) == 0;
582 }
583
584 /* Return non-zero if we're stopped at a function regexp to be skipped. */
585
586 static int
587 skip_rfunction_p (struct skiplist_entry *e, const char *function_name)
588 {
589 gdb_assert (e->function != NULL && e->function_is_regexp
590 && e->compiled_function_regexp);
591 return (e->compiled_function_regexp->exec (function_name, 0, NULL, 0)
592 == 0);
593 }
594
595 /* See skip.h. */
596
597 int
598 function_name_is_marked_for_skip (const char *function_name,
599 const struct symtab_and_line *function_sal)
600 {
601 struct skiplist_entry *e;
602
603 if (function_name == NULL)
604 return 0;
605
606 ALL_SKIPLIST_ENTRIES (e)
607 {
608 int skip_by_file = 0;
609 int skip_by_function = 0;
610
611 if (!e->enabled)
612 continue;
613
614 if (e->file != NULL)
615 {
616 if (e->file_is_glob)
617 {
618 if (skip_gfile_p (e, function_sal))
619 skip_by_file = 1;
620 }
621 else
622 {
623 if (skip_file_p (e, function_sal))
624 skip_by_file = 1;
625 }
626 }
627 if (e->function != NULL)
628 {
629 if (e->function_is_regexp)
630 {
631 if (skip_rfunction_p (e, function_name))
632 skip_by_function = 1;
633 }
634 else
635 {
636 if (skip_function_p (e, function_name))
637 skip_by_function = 1;
638 }
639 }
640
641 /* If both file and function must match, make sure we don't errantly
642 exit if only one of them match. */
643 if (e->file != NULL && e->function != NULL)
644 {
645 if (skip_by_file && skip_by_function)
646 return 1;
647 }
648 /* Only one of file/function is specified. */
649 else if (skip_by_file || skip_by_function)
650 return 1;
651 }
652
653 return 0;
654 }
655
656 /* Provide a prototype to silence -Wmissing-prototypes. */
657 extern initialize_file_ftype _initialize_step_skip;
658
659 void
660 _initialize_step_skip (void)
661 {
662 static struct cmd_list_element *skiplist = NULL;
663 struct cmd_list_element *c;
664
665 skiplist_entry_chain = 0;
666 skiplist_entry_count = 0;
667
668 add_prefix_cmd ("skip", class_breakpoint, skip_command, _("\
669 Ignore a function while stepping.\n\
670 \n\
671 Usage: skip [FUNCTION-NAME]\n\
672 skip [<file-spec>] [<function-spec>]\n\
673 If no arguments are given, ignore the current function.\n\
674 \n\
675 <file-spec> is one of:\n\
676 -fi|-file FILE-NAME\n\
677 -gfi|-gfile GLOB-FILE-PATTERN\n\
678 <function-spec> is one of:\n\
679 -fu|-function FUNCTION-NAME\n\
680 -rfu|-rfunction FUNCTION-NAME-REGULAR-EXPRESSION"),
681 &skiplist, "skip ", 1, &cmdlist);
682
683 c = add_cmd ("file", class_breakpoint, skip_file_command, _("\
684 Ignore a file while stepping.\n\
685 Usage: skip file [FILE-NAME]\n\
686 If no filename is given, ignore the current file."),
687 &skiplist);
688 set_cmd_completer (c, filename_completer);
689
690 c = add_cmd ("function", class_breakpoint, skip_function_command, _("\
691 Ignore a function while stepping.\n\
692 Usage: skip function [FUNCTION-NAME]\n\
693 If no function name is given, skip the current function."),
694 &skiplist);
695 set_cmd_completer (c, location_completer);
696
697 add_cmd ("enable", class_breakpoint, skip_enable_command, _("\
698 Enable skip entries. You can specify numbers (e.g. \"skip enable 1 3\"), \
699 ranges (e.g. \"skip enable 4-8\"), or both (e.g. \"skip enable 1 3 4-8\").\n\n\
700 If you don't specify any numbers or ranges, we'll enable all skip entries.\n\n\
701 Usage: skip enable [NUMBERS AND/OR RANGES]"),
702 &skiplist);
703
704 add_cmd ("disable", class_breakpoint, skip_disable_command, _("\
705 Disable skip entries. You can specify numbers (e.g. \"skip disable 1 3\"), \
706 ranges (e.g. \"skip disable 4-8\"), or both (e.g. \"skip disable 1 3 4-8\").\n\n\
707 If you don't specify any numbers or ranges, we'll disable all skip entries.\n\n\
708 Usage: skip disable [NUMBERS AND/OR RANGES]"),
709 &skiplist);
710
711 add_cmd ("delete", class_breakpoint, skip_delete_command, _("\
712 Delete skip entries. You can specify numbers (e.g. \"skip delete 1 3\"), \
713 ranges (e.g. \"skip delete 4-8\"), or both (e.g. \"skip delete 1 3 4-8\").\n\n\
714 If you don't specify any numbers or ranges, we'll delete all skip entries.\n\n\
715 Usage: skip delete [NUMBERS AND/OR RANGES]"),
716 &skiplist);
717
718 add_info ("skip", skip_info, _("\
719 Display the status of skips. You can specify numbers (e.g. \"skip info 1 3\"), \
720 ranges (e.g. \"skip info 4-8\"), or both (e.g. \"skip info 1 3 4-8\").\n\n\
721 If you don't specify any numbers or ranges, we'll show all skips.\n\n\
722 Usage: skip info [NUMBERS AND/OR RANGES]\n\
723 The \"Type\" column indicates one of:\n\
724 \tfile - ignored file\n\
725 \tfunction - ignored function"));
726 }