gdb/skip.c - gdb

Global variables defined

Data types defined

Functions defined

Macros defined

Source code

  1. /* Skipping uninteresting files and functions while stepping.

  2.    Copyright (C) 2011-2015 Free Software Foundation, Inc.

  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 3 of the License, or
  6.    (at your option) any later version.

  7.    This program is distributed in the hope that it will be useful,
  8.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.    GNU General Public License for more details.

  11.    You should have received a copy of the GNU General Public License
  12.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  13. #include "defs.h"
  14. #include "skip.h"
  15. #include "value.h"
  16. #include "valprint.h"
  17. #include "ui-out.h"
  18. #include "symtab.h"
  19. #include "gdbcmd.h"
  20. #include "command.h"
  21. #include "completer.h"
  22. #include "stack.h"
  23. #include "cli/cli-utils.h"
  24. #include "arch-utils.h"
  25. #include "linespec.h"
  26. #include "objfiles.h"
  27. #include "breakpoint.h" /* for get_sal_arch () */
  28. #include "source.h"
  29. #include "filenames.h"

  30. struct skiplist_entry
  31. {
  32.   int number;

  33.   /* NULL if this isn't a skiplist entry for an entire file.
  34.      The skiplist entry owns this pointer.  */
  35.   char *filename;

  36.   /* The name of the marked-for-skip function, if this is a skiplist
  37.      entry for a function.
  38.      The skiplist entry owns this pointer.  */
  39.   char *function_name;

  40.   int enabled;

  41.   struct skiplist_entry *next;
  42. };

  43. static void add_skiplist_entry (struct skiplist_entry *e);
  44. static void skip_function (const char *name);

  45. static struct skiplist_entry *skiplist_entry_chain;
  46. static int skiplist_entry_count;

  47. #define ALL_SKIPLIST_ENTRIES(E) \
  48.   for (E = skiplist_entry_chain; E; E = E->next)

  49. #define ALL_SKIPLIST_ENTRIES_SAFE(E,TMP) \
  50.   for (E = skiplist_entry_chain;         \
  51.        E ? (TMP = E->next, 1) : 0;       \
  52.        E = TMP)

  53. static void
  54. skip_file_command (char *arg, int from_tty)
  55. {
  56.   struct skiplist_entry *e;
  57.   struct symtab *symtab;
  58.   const char *filename = NULL;

  59.   /* If no argument was given, try to default to the last
  60.      displayed codepoint.  */
  61.   if (arg == NULL)
  62.     {
  63.       symtab = get_last_displayed_symtab ();
  64.       if (symtab == NULL)
  65.         error (_("No default file now."));

  66.       /* It is not a typo, symtab_to_filename_for_display woule be needlessly
  67.          ambiguous.  */
  68.       filename = symtab_to_fullname (symtab);
  69.     }
  70.   else
  71.     {
  72.       symtab = lookup_symtab (arg);
  73.       if (symtab == NULL)
  74.         {
  75.           fprintf_filtered (gdb_stderr, _("No source file named %s.\n"), arg);
  76.           if (!nquery (_("\
  77. Ignore file pending future shared library load? ")))
  78.             return;
  79.         }
  80.       /* Do not use SYMTAB's filename, later loaded shared libraries may match
  81.          given ARG but not SYMTAB's filename.  */
  82.       filename = arg;
  83.     }

  84.   e = XCNEW (struct skiplist_entry);
  85.   e->filename = xstrdup (filename);
  86.   e->enabled = 1;

  87.   add_skiplist_entry (e);

  88.   printf_filtered (_("File %s will be skipped when stepping.\n"), filename);
  89. }

  90. static void
  91. skip_function_command (char *arg, int from_tty)
  92. {
  93.   const char *name = NULL;

  94.   /* Default to the current function if no argument is given.  */
  95.   if (arg == NULL)
  96.     {
  97.       CORE_ADDR pc;

  98.       if (!last_displayed_sal_is_valid ())
  99.         error (_("No default function now."));

  100.       pc = get_last_displayed_addr ();
  101.       if (!find_pc_partial_function (pc, &name, NULL, NULL))
  102.         {
  103.           error (_("No function found containing current program point %s."),
  104.                   paddress (get_current_arch (), pc));
  105.         }
  106.       skip_function (name);
  107.     }
  108.   else
  109.     {
  110.       if (lookup_symbol (arg, NULL, VAR_DOMAIN, NULL) == NULL)
  111.         {
  112.           fprintf_filtered (gdb_stderr,
  113.                             _("No function found named %s.\n"), arg);

  114.           if (nquery (_("\
  115. Ignore function pending future shared library load? ")))
  116.             {
  117.               /* Add the unverified skiplist entry.  */
  118.               skip_function (arg);
  119.             }
  120.           return;
  121.         }

  122.       skip_function (arg);
  123.     }
  124. }

  125. static void
  126. skip_info (char *arg, int from_tty)
  127. {
  128.   struct skiplist_entry *e;
  129.   int num_printable_entries = 0;
  130.   struct value_print_options opts;
  131.   struct cleanup *tbl_chain;

  132.   get_user_print_options (&opts);

  133.   /* Count the number of rows in the table and see if we need space for a
  134.      64-bit address anywhere.  */
  135.   ALL_SKIPLIST_ENTRIES (e)
  136.     if (arg == NULL || number_is_in_list (arg, e->number))
  137.       num_printable_entries++;

  138.   if (num_printable_entries == 0)
  139.     {
  140.       if (arg == NULL)
  141.         ui_out_message (current_uiout, 0, _("\
  142. Not skipping any files or functions.\n"));
  143.       else
  144.         ui_out_message (current_uiout, 0,
  145.                         _("No skiplist entries found with number %s.\n"), arg);

  146.       return;
  147.     }

  148.   tbl_chain = make_cleanup_ui_out_table_begin_end (current_uiout, 4,
  149.                                                    num_printable_entries,
  150.                                                    "SkiplistTable");

  151.   ui_out_table_header (current_uiout, 7, ui_left, "number", "Num");      /* 1 */
  152.   ui_out_table_header (current_uiout, 14, ui_left, "type", "Type");      /* 2 */
  153.   ui_out_table_header (current_uiout, 3, ui_left, "enabled", "Enb");     /* 3 */
  154.   ui_out_table_header (current_uiout, 40, ui_noalign, "what", "What");   /* 4 */
  155.   ui_out_table_body (current_uiout);

  156.   ALL_SKIPLIST_ENTRIES (e)
  157.     {
  158.       struct cleanup *entry_chain;

  159.       QUIT;
  160.       if (arg != NULL && !number_is_in_list (arg, e->number))
  161.         continue;

  162.       entry_chain = make_cleanup_ui_out_tuple_begin_end (current_uiout,
  163.                                                          "blklst-entry");
  164.       ui_out_field_int (current_uiout, "number", e->number);             /* 1 */

  165.       if (e->function_name != NULL)
  166.         ui_out_field_string (current_uiout, "type", "function");         /* 2 */
  167.       else if (e->filename != NULL)
  168.         ui_out_field_string (current_uiout, "type", "file");             /* 2 */
  169.       else
  170.         internal_error (__FILE__, __LINE__, _("\
  171. Skiplist entry should have either a filename or a function name."));

  172.       if (e->enabled)
  173.         ui_out_field_string (current_uiout, "enabled", "y");             /* 3 */
  174.       else
  175.         ui_out_field_string (current_uiout, "enabled", "n");             /* 3 */

  176.       if (e->function_name != NULL)
  177.         ui_out_field_string (current_uiout, "what", e->function_name);         /* 4 */
  178.       else if (e->filename != NULL)
  179.         ui_out_field_string (current_uiout, "what", e->filename);         /* 4 */

  180.       ui_out_text (current_uiout, "\n");
  181.       do_cleanups (entry_chain);
  182.     }

  183.   do_cleanups (tbl_chain);
  184. }

  185. static void
  186. skip_enable_command (char *arg, int from_tty)
  187. {
  188.   struct skiplist_entry *e;
  189.   int found = 0;

  190.   ALL_SKIPLIST_ENTRIES (e)
  191.     if (arg == NULL || number_is_in_list (arg, e->number))
  192.       {
  193.         e->enabled = 1;
  194.         found = 1;
  195.       }

  196.   if (!found)
  197.     error (_("No skiplist entries found with number %s."), arg);
  198. }

  199. static void
  200. skip_disable_command (char *arg, int from_tty)
  201. {
  202.   struct skiplist_entry *e;
  203.   int found = 0;

  204.   ALL_SKIPLIST_ENTRIES (e)
  205.     if (arg == NULL || number_is_in_list (arg, e->number))
  206.       {
  207.         e->enabled = 0;
  208.         found = 1;
  209.       }

  210.   if (!found)
  211.     error (_("No skiplist entries found with number %s."), arg);
  212. }

  213. static void
  214. skip_delete_command (char *arg, int from_tty)
  215. {
  216.   struct skiplist_entry *e, *temp, *b_prev;
  217.   int found = 0;

  218.   b_prev = 0;
  219.   ALL_SKIPLIST_ENTRIES_SAFE (e, temp)
  220.     if (arg == NULL || number_is_in_list (arg, e->number))
  221.       {
  222.         if (b_prev != NULL)
  223.           b_prev->next = e->next;
  224.         else
  225.           skiplist_entry_chain = e->next;

  226.         xfree (e->function_name);
  227.         xfree (e->filename);
  228.         xfree (e);
  229.         found = 1;
  230.       }
  231.     else
  232.       {
  233.         b_prev = e;
  234.       }

  235.   if (!found)
  236.     error (_("No skiplist entries found with number %s."), arg);
  237. }

  238. /* Create a skiplist entry for the given function NAME and add it to the
  239.    list.  */

  240. static void
  241. skip_function (const char *name)
  242. {
  243.   struct skiplist_entry *e = XCNEW (struct skiplist_entry);

  244.   e->enabled = 1;
  245.   e->function_name = xstrdup (name);

  246.   add_skiplist_entry (e);

  247.   printf_filtered (_("Function %s will be skipped when stepping.\n"), name);
  248. }

  249. /* Add the given skiplist entry to our list, and set the entry's number.  */

  250. static void
  251. add_skiplist_entry (struct skiplist_entry *e)
  252. {
  253.   struct skiplist_entry *e1;

  254.   e->number = ++skiplist_entry_count;

  255.   /* Add to the end of the chain so that the list of
  256.      skiplist entries will be in numerical order.  */

  257.   e1 = skiplist_entry_chain;
  258.   if (e1 == NULL)
  259.     skiplist_entry_chain = e;
  260.   else
  261.     {
  262.       while (e1->next)
  263.         e1 = e1->next;
  264.       e1->next = e;
  265.     }
  266. }


  267. /* See skip.h.  */

  268. int
  269. function_name_is_marked_for_skip (const char *function_name,
  270.                                   const struct symtab_and_line *function_sal)
  271. {
  272.   int searched_for_fullname = 0;
  273.   const char *fullname = NULL;
  274.   struct skiplist_entry *e;

  275.   if (function_name == NULL)
  276.     return 0;

  277.   ALL_SKIPLIST_ENTRIES (e)
  278.     {
  279.       if (!e->enabled)
  280.         continue;

  281.       /* Does the pc we're stepping into match e's stored pc? */
  282.       if (e->function_name != NULL
  283.           && strcmp_iw (function_name, e->function_name) == 0)
  284.         return 1;

  285.       if (e->filename != NULL)
  286.         {
  287.           /* Check first sole SYMTAB->FILENAME.  It does not need to be
  288.              a substring of symtab_to_fullname as it may contain "./" etc.  */
  289.           if (function_sal->symtab != NULL
  290.               && compare_filenames_for_search (function_sal->symtab->filename,
  291.                                                e->filename))
  292.             return 1;

  293.           /* Before we invoke realpath, which can get expensive when many
  294.              files are involved, do a quick comparison of the basenames.  */
  295.           if (!basenames_may_differ
  296.               && (function_sal->symtab == NULL
  297.                   || filename_cmp (lbasename (function_sal->symtab->filename),
  298.                                    lbasename (e->filename)) != 0))
  299.             continue;

  300.           /* Get the filename corresponding to this FUNCTION_SAL, if we haven't
  301.              yet.  */
  302.           if (!searched_for_fullname)
  303.             {
  304.               if (function_sal->symtab != NULL)
  305.                 fullname = symtab_to_fullname (function_sal->symtab);
  306.               searched_for_fullname = 1;
  307.             }
  308.           if (fullname != NULL
  309.               && compare_filenames_for_search (fullname, e->filename))
  310.             return 1;
  311.         }
  312.     }

  313.   return 0;
  314. }

  315. /* Provide a prototype to silence -Wmissing-prototypes.  */
  316. extern initialize_file_ftype _initialize_step_skip;

  317. void
  318. _initialize_step_skip (void)
  319. {
  320.   static struct cmd_list_element *skiplist = NULL;
  321.   struct cmd_list_element *c;

  322.   skiplist_entry_chain = 0;
  323.   skiplist_entry_count = 0;

  324.   add_prefix_cmd ("skip", class_breakpoint, skip_function_command, _("\
  325. Ignore a function while stepping.\n\
  326. Usage: skip [FUNCTION NAME]\n\
  327. If no function name is given, ignore the current function."),
  328.                   &skiplist, "skip ", 1, &cmdlist);

  329.   c = add_cmd ("file", class_breakpoint, skip_file_command, _("\
  330. Ignore a file while stepping.\n\
  331. Usage: skip file [FILENAME]\n\
  332. If no filename is given, ignore the current file."),
  333.                &skiplist);
  334.   set_cmd_completer (c, filename_completer);

  335.   c = add_cmd ("function", class_breakpoint, skip_function_command, _("\
  336. Ignore a function while stepping.\n\
  337. Usage: skip function [FUNCTION NAME]\n\
  338. If no function name is given, skip the current function."),
  339.                &skiplist);
  340.   set_cmd_completer (c, location_completer);

  341.   add_cmd ("enable", class_breakpoint, skip_enable_command, _("\
  342. Enable skip entries.  You can specify numbers (e.g. \"skip enable 1 3\"), \
  343. ranges (e.g. \"skip enable 4-8\"), or both (e.g. \"skip enable 1 3 4-8\").\n\n\
  344. If you don't specify any numbers or ranges, we'll enable all skip entries.\n\n\
  345. Usage: skip enable [NUMBERS AND/OR RANGES]"),
  346.            &skiplist);

  347.   add_cmd ("disable", class_breakpoint, skip_disable_command, _("\
  348. Disable skip entries.  You can specify numbers (e.g. \"skip disable 1 3\"), \
  349. ranges (e.g. \"skip disable 4-8\"), or both (e.g. \"skip disable 1 3 4-8\").\n\n\
  350. If you don't specify any numbers or ranges, we'll disable all skip entries.\n\n\
  351. Usage: skip disable [NUMBERS AND/OR RANGES]"),
  352.            &skiplist);

  353.   add_cmd ("delete", class_breakpoint, skip_delete_command, _("\
  354. Delete skip entries.  You can specify numbers (e.g. \"skip delete 1 3\"), \
  355. ranges (e.g. \"skip delete 4-8\"), or both (e.g. \"skip delete 1 3 4-8\").\n\n\
  356. If you don't specify any numbers or ranges, we'll delete all skip entries.\n\n\
  357. Usage: skip delete [NUMBERS AND/OR RANGES]"),
  358.            &skiplist);

  359.   add_info ("skip", skip_info, _("\
  360. Display the status of skips.  You can specify numbers (e.g. \"skip info 1 3\"), \
  361. ranges (e.g. \"skip info 4-8\"), or both (e.g. \"skip info 1 3 4-8\").\n\n\
  362. If you don't specify any numbers or ranges, we'll show all skips.\n\n\
  363. Usage: skip info [NUMBERS AND/OR RANGES]\n\
  364. The \"Type\" column indicates one of:\n\
  365. \tfile        - ignored file\n\
  366. \tfunction    - ignored function"));
  367. }