Index: gdb/skip.c |
diff --git a/gdb/skip.c b/gdb/skip.c |
index 8e1965266a5346e05a1c448955a6ef5ebc38668d..73c5d35a54e3fefb9829ca4bbbb96bccc4383bdf 100644 |
--- a/gdb/skip.c |
+++ b/gdb/skip.c |
@@ -1,6 +1,6 @@ |
/* Skipping uninteresting files and functions while stepping. |
- Copyright (C) 2011-2012 Free Software Foundation, Inc. |
+ Copyright (C) 2011-2013 Free Software Foundation, Inc. |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
@@ -20,7 +20,7 @@ |
#include "value.h" |
#include "valprint.h" |
#include "ui-out.h" |
-#include "gdb_string.h" |
+#include <string.h> |
#include "symtab.h" |
#include "gdbcmd.h" |
#include "command.h" |
@@ -32,6 +32,8 @@ |
#include "objfiles.h" |
#include "exceptions.h" |
#include "breakpoint.h" /* for get_sal_arch () */ |
+#include "source.h" |
+#include "filenames.h" |
struct skiplist_entry |
{ |
@@ -42,34 +44,17 @@ struct skiplist_entry |
char *filename; |
/* The name of the marked-for-skip function, if this is a skiplist |
- entry for a function. Note that this might be non-null even if |
- the pc is 0 if the entry is pending a shared library load. |
- |
+ entry for a function. |
The skiplist entry owns this pointer. */ |
char *function_name; |
- /* 0 if this is a skiplist entry for an entire file, or if this |
- entry will be on a function, pending a shared library load. */ |
- CORE_ADDR pc; |
- |
- /* Architecture we used to create the skiplist entry. May be null |
- if the entry is pending a shared library load. */ |
- struct gdbarch *gdbarch; |
- |
int enabled; |
- int pending; |
struct skiplist_entry *next; |
}; |
-static void skip_function_command (char *arg, int from_tty); |
-static void skip_file_command (char *arg, int from_tty); |
-static void skip_info (char *arg, int from_tty); |
- |
static void add_skiplist_entry (struct skiplist_entry *e); |
-static void skip_function_pc (CORE_ADDR pc, const char *name, |
- struct gdbarch *arch, |
- int pending); |
+static void skip_function (const char *name); |
static struct skiplist_entry *skiplist_entry_chain; |
static int skiplist_entry_count; |
@@ -87,42 +72,38 @@ skip_file_command (char *arg, int from_tty) |
{ |
struct skiplist_entry *e; |
struct symtab *symtab; |
- int pending = 0; |
- char *filename = 0; |
+ const char *filename = NULL; |
/* If no argument was given, try to default to the last |
displayed codepoint. */ |
- if (arg == 0) |
+ if (arg == NULL) |
{ |
symtab = get_last_displayed_symtab (); |
- if (symtab == 0) |
+ if (symtab == NULL) |
error (_("No default file now.")); |
- else |
- filename = symtab->filename; |
+ |
+ /* It is not a typo, symtab_to_filename_for_display woule be needlessly |
+ ambiguous. */ |
+ filename = symtab_to_fullname (symtab); |
} |
else |
{ |
symtab = lookup_symtab (arg); |
- if (symtab == 0) |
+ if (symtab == NULL) |
{ |
fprintf_filtered (gdb_stderr, _("No source file named %s.\n"), arg); |
if (!nquery (_("\ |
Ignore file pending future shared library load? "))) |
return; |
- |
- pending = 1; |
- filename = arg; |
} |
- else |
- filename = symtab->filename; |
+ /* Do not use SYMTAB's filename, later loaded shared libraries may match |
+ given ARG but not SYMTAB's filename. */ |
+ filename = arg; |
} |
e = XZALLOC (struct skiplist_entry); |
e->filename = xstrdup (filename); |
e->enabled = 1; |
- e->pending = pending; |
- if (symtab != 0) |
- e->gdbarch = get_objfile_arch (symtab->objfile); |
add_skiplist_entry (e); |
@@ -132,78 +113,41 @@ Ignore file pending future shared library load? "))) |
static void |
skip_function_command (char *arg, int from_tty) |
{ |
- CORE_ADDR func_pc; |
const char *name = NULL; |
/* Default to the current function if no argument is given. */ |
- if (arg == 0) |
+ if (arg == NULL) |
{ |
CORE_ADDR pc; |
+ |
if (!last_displayed_sal_is_valid ()) |
error (_("No default function now.")); |
pc = get_last_displayed_addr (); |
- if (!find_pc_partial_function (pc, &name, &func_pc, 0)) |
+ if (!find_pc_partial_function (pc, &name, NULL, NULL)) |
{ |
error (_("No function found containing current program point %s."), |
paddress (get_current_arch (), pc)); |
} |
- skip_function_pc (func_pc, name, get_current_arch (), 0); |
+ skip_function (name); |
} |
else |
{ |
- /* Decode arg. We set funfirstline=1 so decode_line_1 will give us the |
- first line of the function specified, if it can, and so that we'll |
- reject variable names and the like. */ |
- char *orig_arg = arg; /* decode_line_1 modifies the arg pointer. */ |
- volatile struct gdb_exception decode_exception; |
- struct symtabs_and_lines sals = { 0 }; |
- |
- TRY_CATCH (decode_exception, RETURN_MASK_ERROR) |
- { |
- sals = decode_line_1 (&arg, DECODE_LINE_FUNFIRSTLINE, 0, 0); |
- } |
- |
- if (decode_exception.reason < 0) |
+ if (lookup_symbol (arg, NULL, VAR_DOMAIN, NULL) == NULL) |
{ |
- if (decode_exception.error != NOT_FOUND_ERROR) |
- throw_exception (decode_exception); |
- |
fprintf_filtered (gdb_stderr, |
- _("No function found named %s.\n"), orig_arg); |
+ _("No function found named %s.\n"), arg); |
if (nquery (_("\ |
Ignore function pending future shared library load? "))) |
{ |
- /* Add the pending skiplist entry. */ |
- skip_function_pc (0, orig_arg, 0, 1); |
+ /* Add the unverified skiplist entry. */ |
+ skip_function (arg); |
} |
- |
return; |
} |
- if (sals.nelts > 1) |
- error (_("Specify just one function at a time.")); |
- if (strlen (arg) != 0) |
- error (_("Junk at end of arguments.")); |
- |
- /* The pc decode_line_1 gives us is the first line of the function, |
- but we actually want the line before that. The call to |
- find_pc_partial_function gets us the value we actually want. */ |
- { |
- struct symtab_and_line sal = sals.sals[0]; |
- CORE_ADDR pc = sal.pc; |
- CORE_ADDR func_start = 0; |
- struct gdbarch *arch = get_sal_arch (sal); |
- |
- if (!find_pc_partial_function (pc, &name, &func_start, 0)) |
- { |
- error (_("No function found containing program point %s."), |
- paddress (arch, pc)); |
- } |
- |
- skip_function_pc (func_start, name, arch, 0); |
- } |
+ skip_function (arg); |
} |
} |
@@ -212,7 +156,6 @@ skip_info (char *arg, int from_tty) |
{ |
struct skiplist_entry *e; |
int num_printable_entries = 0; |
- int address_width = 10; |
struct value_print_options opts; |
struct cleanup *tbl_chain; |
@@ -221,16 +164,12 @@ skip_info (char *arg, int from_tty) |
/* Count the number of rows in the table and see if we need space for a |
64-bit address anywhere. */ |
ALL_SKIPLIST_ENTRIES (e) |
- if (arg == 0 || number_is_in_list (arg, e->number)) |
- { |
- num_printable_entries++; |
- if (e->gdbarch && gdbarch_addr_bit (e->gdbarch) > 32) |
- address_width = 18; |
- } |
+ if (arg == NULL || number_is_in_list (arg, e->number)) |
+ num_printable_entries++; |
if (num_printable_entries == 0) |
{ |
- if (arg == 0) |
+ if (arg == NULL) |
ui_out_message (current_uiout, 0, _("\ |
Not skipping any files or functions.\n")); |
else |
@@ -240,25 +179,14 @@ Not skipping any files or functions.\n")); |
return; |
} |
- if (opts.addressprint) |
- tbl_chain = make_cleanup_ui_out_table_begin_end (current_uiout, 5, |
- num_printable_entries, |
- "SkiplistTable"); |
- else |
- tbl_chain |
- = make_cleanup_ui_out_table_begin_end (current_uiout, 4, |
- num_printable_entries, |
- "SkiplistTable"); |
+ tbl_chain = make_cleanup_ui_out_table_begin_end (current_uiout, 4, |
+ num_printable_entries, |
+ "SkiplistTable"); |
ui_out_table_header (current_uiout, 7, ui_left, "number", "Num"); /* 1 */ |
ui_out_table_header (current_uiout, 14, ui_left, "type", "Type"); /* 2 */ |
ui_out_table_header (current_uiout, 3, ui_left, "enabled", "Enb"); /* 3 */ |
- if (opts.addressprint) |
- { |
- ui_out_table_header (current_uiout, address_width, ui_left, |
- "addr", "Address"); /* 4 */ |
- } |
- ui_out_table_header (current_uiout, 40, ui_noalign, "what", "What"); /* 5 */ |
+ ui_out_table_header (current_uiout, 40, ui_noalign, "what", "What"); /* 4 */ |
ui_out_table_body (current_uiout); |
ALL_SKIPLIST_ENTRIES (e) |
@@ -266,16 +194,16 @@ Not skipping any files or functions.\n")); |
struct cleanup *entry_chain; |
QUIT; |
- if (arg != 0 && !number_is_in_list (arg, e->number)) |
+ if (arg != NULL && !number_is_in_list (arg, e->number)) |
continue; |
entry_chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, |
"blklst-entry"); |
ui_out_field_int (current_uiout, "number", e->number); /* 1 */ |
- if (e->function_name != 0) |
+ if (e->function_name != NULL) |
ui_out_field_string (current_uiout, "type", "function"); /* 2 */ |
- else if (e->filename != 0) |
+ else if (e->filename != NULL) |
ui_out_field_string (current_uiout, "type", "file"); /* 2 */ |
else |
internal_error (__FILE__, __LINE__, _("\ |
@@ -286,39 +214,10 @@ Skiplist entry should have either a filename or a function name.")); |
else |
ui_out_field_string (current_uiout, "enabled", "n"); /* 3 */ |
- if (opts.addressprint) |
- { |
- if (e->pc != 0) |
- ui_out_field_core_addr (current_uiout, "addr", |
- e->gdbarch, e->pc); /* 4 */ |
- else |
- ui_out_field_string (current_uiout, "addr", ""); /* 4 */ |
- } |
- |
- if (!e->pending && e->function_name != 0) |
- { |
- struct symbol *sym; |
- |
- gdb_assert (e->pc != 0); |
- sym = find_pc_function (e->pc); |
- if (sym) |
- ui_out_field_fmt (current_uiout, "what", "%s at %s:%d", |
- sym->ginfo.name, |
- sym->symtab->filename, |
- sym->line); |
- else |
- ui_out_field_string (current_uiout, "what", "?"); |
- } |
- else if (e->pending && e->function_name != 0) |
- { |
- ui_out_field_fmt (current_uiout, "what", "%s (PENDING)", |
- e->function_name); |
- } |
- else if (!e->pending && e->filename != 0) |
- ui_out_field_string (current_uiout, "what", e->filename); |
- else if (e->pending && e->filename != 0) |
- ui_out_field_fmt (current_uiout, "what", "%s (PENDING)", |
- e->filename); |
+ if (e->function_name != NULL) |
+ ui_out_field_string (current_uiout, "what", e->function_name); /* 4 */ |
+ else if (e->filename != NULL) |
+ ui_out_field_string (current_uiout, "what", e->filename); /* 4 */ |
ui_out_text (current_uiout, "\n"); |
do_cleanups (entry_chain); |
@@ -334,7 +233,7 @@ skip_enable_command (char *arg, int from_tty) |
int found = 0; |
ALL_SKIPLIST_ENTRIES (e) |
- if (arg == 0 || number_is_in_list (arg, e->number)) |
+ if (arg == NULL || number_is_in_list (arg, e->number)) |
{ |
e->enabled = 1; |
found = 1; |
@@ -351,7 +250,7 @@ skip_disable_command (char *arg, int from_tty) |
int found = 0; |
ALL_SKIPLIST_ENTRIES (e) |
- if (arg == 0 || number_is_in_list (arg, e->number)) |
+ if (arg == NULL || number_is_in_list (arg, e->number)) |
{ |
e->enabled = 0; |
found = 1; |
@@ -369,9 +268,9 @@ skip_delete_command (char *arg, int from_tty) |
b_prev = 0; |
ALL_SKIPLIST_ENTRIES_SAFE (e, temp) |
- if (arg == 0 || number_is_in_list (arg, e->number)) |
+ if (arg == NULL || number_is_in_list (arg, e->number)) |
{ |
- if (b_prev != 0) |
+ if (b_prev != NULL) |
b_prev->next = e->next; |
else |
skiplist_entry_chain = e->next; |
@@ -390,30 +289,20 @@ skip_delete_command (char *arg, int from_tty) |
error (_("No skiplist entries found with number %s."), arg); |
} |
-/* Create a skiplist entry for the given pc corresponding to the given |
- function name and add it to the list. */ |
+/* Create a skiplist entry for the given function NAME and add it to the |
+ list. */ |
static void |
-skip_function_pc (CORE_ADDR pc, const char *name, struct gdbarch *arch, |
- int pending) |
+skip_function (const char *name) |
{ |
struct skiplist_entry *e = XZALLOC (struct skiplist_entry); |
- e->pc = pc; |
- e->gdbarch = arch; |
e->enabled = 1; |
- e->pending = pending; |
e->function_name = xstrdup (name); |
add_skiplist_entry (e); |
- if (!pending) |
- printf_filtered (_("Function %s at %s will be skipped when stepping.\n"), |
- name, paddress (get_current_arch (), pc)); |
- else |
- printf_filtered (_("Function %s will be skipped when stepping, " |
- "pending shared library load.\n"), |
- name); |
+ printf_filtered (_("Function %s will be skipped when stepping.\n"), name); |
} |
/* Add the given skiplist entry to our list, and set the entry's number. */ |
@@ -429,7 +318,7 @@ add_skiplist_entry (struct skiplist_entry *e) |
skiplist entries will be in numerical order. */ |
e1 = skiplist_entry_chain; |
- if (e1 == 0) |
+ if (e1 == NULL) |
skiplist_entry_chain = e; |
else |
{ |
@@ -439,37 +328,57 @@ add_skiplist_entry (struct skiplist_entry *e) |
} |
} |
-/* Does the given pc correspond to the beginning of a skipped function? */ |
+ |
+/* See skip.h. */ |
int |
-function_pc_is_marked_for_skip (CORE_ADDR pc) |
+function_name_is_marked_for_skip (const char *function_name, |
+ const struct symtab_and_line *function_sal) |
{ |
- int searched_for_sal = 0; |
- struct symtab_and_line sal; |
- char *filename = NULL; |
+ int searched_for_fullname = 0; |
+ const char *fullname = NULL; |
struct skiplist_entry *e; |
+ if (function_name == NULL) |
+ return 0; |
+ |
ALL_SKIPLIST_ENTRIES (e) |
{ |
- if (!e->enabled || e->pending) |
+ if (!e->enabled) |
continue; |
/* Does the pc we're stepping into match e's stored pc? */ |
- if (e->pc != 0 && pc == e->pc) |
+ if (e->function_name != NULL |
+ && strcmp_iw (function_name, e->function_name) == 0) |
return 1; |
- if (e->filename != 0) |
+ if (e->filename != NULL) |
{ |
- /* Get the filename corresponding to this pc, if we haven't |
- * yet. */ |
- if (!searched_for_sal) |
+ /* Check first sole SYMTAB->FILENAME. It does not need to be |
+ a substring of symtab_to_fullname as it may contain "./" etc. */ |
+ if (function_sal->symtab != NULL |
+ && compare_filenames_for_search (function_sal->symtab->filename, |
+ e->filename)) |
+ return 1; |
+ |
+ /* Before we invoke realpath, which can get expensive when many |
+ files are involved, do a quick comparison of the basenames. */ |
+ if (!basenames_may_differ |
+ && (function_sal->symtab == NULL |
+ || filename_cmp (lbasename (function_sal->symtab->filename), |
+ lbasename (e->filename)) != 0)) |
+ continue; |
+ |
+ /* Get the filename corresponding to this FUNCTION_SAL, if we haven't |
+ yet. */ |
+ if (!searched_for_fullname) |
{ |
- sal = find_pc_line (pc, 0); |
- if (sal.symtab != 0) |
- filename = sal.symtab->filename; |
- searched_for_sal = 1; |
+ if (function_sal->symtab != NULL) |
+ fullname = symtab_to_fullname (function_sal->symtab); |
+ searched_for_fullname = 1; |
} |
- if (filename != 0 && strcmp (filename, e->filename) == 0) |
+ if (fullname != NULL |
+ && compare_filenames_for_search (fullname, e->filename)) |
return 1; |
} |
} |
@@ -477,74 +386,13 @@ function_pc_is_marked_for_skip (CORE_ADDR pc) |
return 0; |
} |
-/* Re-set the skip list after symbols have been re-loaded. */ |
-void |
-skip_re_set (void) |
-{ |
- struct skiplist_entry *e; |
- |
- ALL_SKIPLIST_ENTRIES (e) |
- { |
- if (e->filename != 0) |
- { |
- /* If it's an entry telling us to skip a file, but the entry is |
- currently pending a solib load, let's see if we now know |
- about the file. */ |
- struct symtab *symtab = lookup_symtab (e->filename); |
- if (symtab != 0) |
- { |
- xfree (e->filename); |
- e->filename = xstrdup (symtab->filename); |
- e->gdbarch = get_objfile_arch (symtab->objfile); |
- e->pending = 0; |
- } |
- else |
- { |
- e->pending = 1; |
- } |
- } |
- else if (e->function_name != 0) |
- { |
- char *func_name = e->function_name; |
- struct symtabs_and_lines sals = { 0 }; |
- volatile struct gdb_exception decode_exception; |
- |
- TRY_CATCH (decode_exception, RETURN_MASK_ERROR) |
- { |
- sals = decode_line_1 (&func_name, DECODE_LINE_FUNFIRSTLINE, 0, 0); |
- } |
- |
- if (decode_exception.reason >= 0 |
- && sals.nelts == 1 && strlen (func_name) == 0) |
- { |
- struct symtab_and_line sal = sals.sals[0]; |
- CORE_ADDR pc = sal.pc; |
- CORE_ADDR func_start = 0; |
- struct gdbarch *arch = get_sal_arch (sal); |
- const char *func_name; |
- |
- if (find_pc_partial_function (pc, &func_name, &func_start, 0)) |
- { |
- e->pending = 0; |
- e->function_name = xstrdup (func_name); |
- e->pc = func_start; |
- e->gdbarch = arch; |
- } |
- } |
- else |
- { |
- e->pending = 1; |
- } |
- } |
- } |
-} |
- |
/* Provide a prototype to silence -Wmissing-prototypes. */ |
extern initialize_file_ftype _initialize_step_skip; |
void |
_initialize_step_skip (void) |
{ |
+ static struct cmd_list_element *skiplist = NULL; |
struct cmd_list_element *c; |
skiplist_entry_chain = 0; |