1 /* Skipping uninteresting files and functions while stepping. 2 3 Copyright (C) 2011-2013 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 "gdb_string.h" 24 #include "symtab.h" 25 #include "gdbcmd.h" 26 #include "command.h" 27 #include "completer.h" 28 #include "stack.h" 29 #include "cli/cli-utils.h" 30 #include "arch-utils.h" 31 #include "linespec.h" 32 #include "objfiles.h" 33 #include "exceptions.h" 34 #include "breakpoint.h" /* for get_sal_arch () */ 35 #include "source.h" 36 #include "filenames.h" 37 38 struct skiplist_entry 39 { 40 int number; 41 42 /* NULL if this isn't a skiplist entry for an entire file. 43 The skiplist entry owns this pointer. */ 44 char *filename; 45 46 /* The name of the marked-for-skip function, if this is a skiplist 47 entry for a function. 48 The skiplist entry owns this pointer. */ 49 char *function_name; 50 51 int enabled; 52 53 struct skiplist_entry *next; 54 }; 55 56 static void add_skiplist_entry (struct skiplist_entry *e); 57 static void skip_function (const char *name); 58 59 static struct skiplist_entry *skiplist_entry_chain; 60 static int skiplist_entry_count; 61 62 #define ALL_SKIPLIST_ENTRIES(E) \ 63 for (E = skiplist_entry_chain; E; E = E->next) 64 65 #define ALL_SKIPLIST_ENTRIES_SAFE(E,TMP) \ 66 for (E = skiplist_entry_chain; \ 67 E ? (TMP = E->next, 1) : 0; \ 68 E = TMP) 69 70 static void 71 skip_file_command (char *arg, int from_tty) 72 { 73 struct skiplist_entry *e; 74 struct symtab *symtab; 75 const char *filename = NULL; 76 77 /* If no argument was given, try to default to the last 78 displayed codepoint. */ 79 if (arg == NULL) 80 { 81 symtab = get_last_displayed_symtab (); 82 if (symtab == NULL) 83 error (_("No default file now.")); 84 85 /* It is not a typo, symtab_to_filename_for_display woule be needlessly 86 ambiguous. */ 87 filename = symtab_to_fullname (symtab); 88 } 89 else 90 { 91 symtab = lookup_symtab (arg); 92 if (symtab == NULL) 93 { 94 fprintf_filtered (gdb_stderr, _("No source file named %s.\n"), arg); 95 if (!nquery (_("\ 96 Ignore file pending future shared library load? "))) 97 return; 98 } 99 /* Do not use SYMTAB's filename, later loaded shared libraries may match 100 given ARG but not SYMTAB's filename. */ 101 filename = arg; 102 } 103 104 e = XZALLOC (struct skiplist_entry); 105 e->filename = xstrdup (filename); 106 e->enabled = 1; 107 108 add_skiplist_entry (e); 109 110 printf_filtered (_("File %s will be skipped when stepping.\n"), filename); 111 } 112 113 static void 114 skip_function_command (char *arg, int from_tty) 115 { 116 const char *name = NULL; 117 118 /* Default to the current function if no argument is given. */ 119 if (arg == NULL) 120 { 121 CORE_ADDR pc; 122 123 if (!last_displayed_sal_is_valid ()) 124 error (_("No default function now.")); 125 126 pc = get_last_displayed_addr (); 127 if (!find_pc_partial_function (pc, &name, NULL, NULL)) 128 { 129 error (_("No function found containing current program point %s."), 130 paddress (get_current_arch (), pc)); 131 } 132 skip_function (name); 133 } 134 else 135 { 136 if (lookup_symbol (arg, NULL, VAR_DOMAIN, NULL) == NULL) 137 { 138 fprintf_filtered (gdb_stderr, 139 _("No function found named %s.\n"), arg); 140 141 if (nquery (_("\ 142 Ignore function pending future shared library load? "))) 143 { 144 /* Add the unverified skiplist entry. */ 145 skip_function (arg); 146 } 147 return; 148 } 149 150 skip_function (arg); 151 } 152 } 153 154 static void 155 skip_info (char *arg, int from_tty) 156 { 157 struct skiplist_entry *e; 158 int num_printable_entries = 0; 159 struct value_print_options opts; 160 struct cleanup *tbl_chain; 161 162 get_user_print_options (&opts); 163 164 /* Count the number of rows in the table and see if we need space for a 165 64-bit address anywhere. */ 166 ALL_SKIPLIST_ENTRIES (e) 167 if (arg == NULL || number_is_in_list (arg, e->number)) 168 num_printable_entries++; 169 170 if (num_printable_entries == 0) 171 { 172 if (arg == NULL) 173 ui_out_message (current_uiout, 0, _("\ 174 Not skipping any files or functions.\n")); 175 else 176 ui_out_message (current_uiout, 0, 177 _("No skiplist entries found with number %s.\n"), arg); 178 179 return; 180 } 181 182 tbl_chain = make_cleanup_ui_out_table_begin_end (current_uiout, 4, 183 num_printable_entries, 184 "SkiplistTable"); 185 186 ui_out_table_header (current_uiout, 7, ui_left, "number", "Num"); /* 1 */ 187 ui_out_table_header (current_uiout, 14, ui_left, "type", "Type"); /* 2 */ 188 ui_out_table_header (current_uiout, 3, ui_left, "enabled", "Enb"); /* 3 */ 189 ui_out_table_header (current_uiout, 40, ui_noalign, "what", "What"); /* 4 */ 190 ui_out_table_body (current_uiout); 191 192 ALL_SKIPLIST_ENTRIES (e) 193 { 194 struct cleanup *entry_chain; 195 196 QUIT; 197 if (arg != NULL && !number_is_in_list (arg, e->number)) 198 continue; 199 200 entry_chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, 201 "blklst-entry"); 202 ui_out_field_int (current_uiout, "number", e->number); /* 1 */ 203 204 if (e->function_name != NULL) 205 ui_out_field_string (current_uiout, "type", "function"); /* 2 */ 206 else if (e->filename != NULL) 207 ui_out_field_string (current_uiout, "type", "file"); /* 2 */ 208 else 209 internal_error (__FILE__, __LINE__, _("\ 210 Skiplist entry should have either a filename or a function name.")); 211 212 if (e->enabled) 213 ui_out_field_string (current_uiout, "enabled", "y"); /* 3 */ 214 else 215 ui_out_field_string (current_uiout, "enabled", "n"); /* 3 */ 216 217 if (e->function_name != NULL) 218 ui_out_field_string (current_uiout, "what", e->function_name); /* 4 */ 219 else if (e->filename != NULL) 220 ui_out_field_string (current_uiout, "what", e->filename); /* 4 */ 221 222 ui_out_text (current_uiout, "\n"); 223 do_cleanups (entry_chain); 224 } 225 226 do_cleanups (tbl_chain); 227 } 228 229 static void 230 skip_enable_command (char *arg, int from_tty) 231 { 232 struct skiplist_entry *e; 233 int found = 0; 234 235 ALL_SKIPLIST_ENTRIES (e) 236 if (arg == NULL || number_is_in_list (arg, e->number)) 237 { 238 e->enabled = 1; 239 found = 1; 240 } 241 242 if (!found) 243 error (_("No skiplist entries found with number %s."), arg); 244 } 245 246 static void 247 skip_disable_command (char *arg, int from_tty) 248 { 249 struct skiplist_entry *e; 250 int found = 0; 251 252 ALL_SKIPLIST_ENTRIES (e) 253 if (arg == NULL || number_is_in_list (arg, e->number)) 254 { 255 e->enabled = 0; 256 found = 1; 257 } 258 259 if (!found) 260 error (_("No skiplist entries found with number %s."), arg); 261 } 262 263 static void 264 skip_delete_command (char *arg, int from_tty) 265 { 266 struct skiplist_entry *e, *temp, *b_prev; 267 int found = 0; 268 269 b_prev = 0; 270 ALL_SKIPLIST_ENTRIES_SAFE (e, temp) 271 if (arg == NULL || number_is_in_list (arg, e->number)) 272 { 273 if (b_prev != NULL) 274 b_prev->next = e->next; 275 else 276 skiplist_entry_chain = e->next; 277 278 xfree (e->function_name); 279 xfree (e->filename); 280 xfree (e); 281 found = 1; 282 } 283 else 284 { 285 b_prev = e; 286 } 287 288 if (!found) 289 error (_("No skiplist entries found with number %s."), arg); 290 } 291 292 /* Create a skiplist entry for the given function NAME and add it to the 293 list. */ 294 295 static void 296 skip_function (const char *name) 297 { 298 struct skiplist_entry *e = XZALLOC (struct skiplist_entry); 299 300 e->enabled = 1; 301 e->function_name = xstrdup (name); 302 303 add_skiplist_entry (e); 304 305 printf_filtered (_("Function %s will be skipped when stepping.\n"), name); 306 } 307 308 /* Add the given skiplist entry to our list, and set the entry's number. */ 309 310 static void 311 add_skiplist_entry (struct skiplist_entry *e) 312 { 313 struct skiplist_entry *e1; 314 315 e->number = ++skiplist_entry_count; 316 317 /* Add to the end of the chain so that the list of 318 skiplist entries will be in numerical order. */ 319 320 e1 = skiplist_entry_chain; 321 if (e1 == NULL) 322 skiplist_entry_chain = e; 323 else 324 { 325 while (e1->next) 326 e1 = e1->next; 327 e1->next = e; 328 } 329 } 330 331 332 /* See skip.h. */ 333 334 int 335 function_name_is_marked_for_skip (const char *function_name, 336 const struct symtab_and_line *function_sal) 337 { 338 int searched_for_fullname = 0; 339 const char *fullname = NULL; 340 struct skiplist_entry *e; 341 342 if (function_name == NULL) 343 return 0; 344 345 ALL_SKIPLIST_ENTRIES (e) 346 { 347 if (!e->enabled) 348 continue; 349 350 /* Does the pc we're stepping into match e's stored pc? */ 351 if (e->function_name != NULL 352 && strcmp_iw (function_name, e->function_name) == 0) 353 return 1; 354 355 if (e->filename != NULL) 356 { 357 /* Check first sole SYMTAB->FILENAME. It does not need to be 358 a substring of symtab_to_fullname as it may contain "./" etc. */ 359 if (function_sal->symtab != NULL 360 && compare_filenames_for_search (function_sal->symtab->filename, 361 e->filename)) 362 return 1; 363 364 /* Before we invoke realpath, which can get expensive when many 365 files are involved, do a quick comparison of the basenames. */ 366 if (!basenames_may_differ 367 && (function_sal->symtab == NULL 368 || filename_cmp (lbasename (function_sal->symtab->filename), 369 lbasename (e->filename)) != 0)) 370 continue; 371 372 /* Get the filename corresponding to this FUNCTION_SAL, if we haven't 373 yet. */ 374 if (!searched_for_fullname) 375 { 376 if (function_sal->symtab != NULL) 377 fullname = symtab_to_fullname (function_sal->symtab); 378 searched_for_fullname = 1; 379 } 380 if (fullname != NULL 381 && compare_filenames_for_search (fullname, e->filename)) 382 return 1; 383 } 384 } 385 386 return 0; 387 } 388 389 /* Provide a prototype to silence -Wmissing-prototypes. */ 390 extern initialize_file_ftype _initialize_step_skip; 391 392 void 393 _initialize_step_skip (void) 394 { 395 static struct cmd_list_element *skiplist = NULL; 396 struct cmd_list_element *c; 397 398 skiplist_entry_chain = 0; 399 skiplist_entry_count = 0; 400 401 add_prefix_cmd ("skip", class_breakpoint, skip_function_command, _("\ 402 Ignore a function while stepping.\n\ 403 Usage: skip [FUNCTION NAME]\n\ 404 If no function name is given, ignore the current function."), 405 &skiplist, "skip ", 1, &cmdlist); 406 407 c = add_cmd ("file", class_breakpoint, skip_file_command, _("\ 408 Ignore a file while stepping.\n\ 409 Usage: skip file [FILENAME]\n\ 410 If no filename is given, ignore the current file."), 411 &skiplist); 412 set_cmd_completer (c, filename_completer); 413 414 c = add_cmd ("function", class_breakpoint, skip_function_command, _("\ 415 Ignore a function while stepping.\n\ 416 Usage: skip function [FUNCTION NAME]\n\ 417 If no function name is given, skip the current function."), 418 &skiplist); 419 set_cmd_completer (c, location_completer); 420 421 add_cmd ("enable", class_breakpoint, skip_enable_command, _("\ 422 Enable skip entries. You can specify numbers (e.g. \"skip enable 1 3\"), \ 423 ranges (e.g. \"skip enable 4-8\"), or both (e.g. \"skip enable 1 3 4-8\").\n\n\ 424 If you don't specify any numbers or ranges, we'll enable all skip entries.\n\n\ 425 Usage: skip enable [NUMBERS AND/OR RANGES]"), 426 &skiplist); 427 428 add_cmd ("disable", class_breakpoint, skip_disable_command, _("\ 429 Disable skip entries. You can specify numbers (e.g. \"skip disable 1 3\"), \ 430 ranges (e.g. \"skip disable 4-8\"), or both (e.g. \"skip disable 1 3 4-8\").\n\n\ 431 If you don't specify any numbers or ranges, we'll disable all skip entries.\n\n\ 432 Usage: skip disable [NUMBERS AND/OR RANGES]"), 433 &skiplist); 434 435 add_cmd ("delete", class_breakpoint, skip_delete_command, _("\ 436 Delete skip entries. You can specify numbers (e.g. \"skip delete 1 3\"), \ 437 ranges (e.g. \"skip delete 4-8\"), or both (e.g. \"skip delete 1 3 4-8\").\n\n\ 438 If you don't specify any numbers or ranges, we'll delete all skip entries.\n\n\ 439 Usage: skip delete [NUMBERS AND/OR RANGES]"), 440 &skiplist); 441 442 add_info ("skip", skip_info, _("\ 443 Display the status of skips. You can specify numbers (e.g. \"skip info 1 3\"), \ 444 ranges (e.g. \"skip info 4-8\"), or both (e.g. \"skip info 1 3 4-8\").\n\n\ 445 If you don't specify any numbers or ranges, we'll show all skips.\n\n\ 446 Usage: skip info [NUMBERS AND/OR RANGES]\n\ 447 The \"Type\" column indicates one of:\n\ 448 \tfile - ignored file\n\ 449 \tfunction - ignored function")); 450 } 451