This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFA] C++ : breakpoint in templates
- From: Jerome Guitton <guitton at adacore dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 16 Dec 2008 17:14:16 +0100
- Subject: [RFA] C++ : breakpoint in templates
Problem to break on lines that contain no "real code" in
template... Consider the following C++ program:
template <class T>
T GetMax (T a, T b) {
T result;
result = (a>b)? a : b;
return (result);
}
int main () {
int i=5, j=6, k;
long l=10, m=5, n;
k=GetMax<int>(i,j);
n=GetMax<long>(l,m);
return 0;
}
Now, in GDB, break in the template:
(gdb) l template.cc:5
1
2 template <class T>
3 T GetMax (T a, T b) {
4 T result;
5 result = (a>b)? a : b;
6
7
8 return (result);
9 }
10
(gdb) b 5
Breakpoint 1 at 0x8048274: file template.cc, line 5. (2 locations)
That's OK, we have 2 locations, one per template instantiation. But
if you break on line 6, the breakpoint is set in only one instance of
the template:
(gdb) b 6
Breakpoint 2 at 0x8048290: file template.cc, line 6.
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y <MULTIPLE> 0x08048274
1.1 y 0x08048274 in int GetMax<int>(int, int)
at template.cc:5
1.2 y 0x0804829c in long GetMax<long>(long, long)
at template.cc:5
2 breakpoint keep y 0x08048290 in int GetMax<int>(int, int)
at template.cc:6
(gdb)
That's unexpected... The difference is that there is no code generated
for line 6. This means that expand_line_sal will not find any exact
match for template.cc:6. In this case, expand_line_sal appends only
one item, the best one in all symtab; I think that it should append
all best matches (that is to say: all matches that are as good as the
best one).
The patch in attachment should fix the problem. Testsuite run on
x86-linux, no regression. New testcase will follow. OK to apply?
Thanks,
Jerome
2008-12-16 Jerome Guitton <guitton@adacore.com>
* symtab.c (append_exact_match_to_sals): New function, extracted
from expand_line_sal.
(expand_line_sal): Use append_exact_match_to_sals to append exact
matches. If none found, append all best items.
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.199
diff -u -p -r1.199 symtab.c
--- symtab.c 1 Oct 2008 17:25:22 -0000 1.199
+++ symtab.c 16 Dec 2008 16:08:09 -0000
@@ -4439,6 +4439,58 @@ append_expanded_sal (struct symtabs_and_
++sal->nelts;
}
+/* Helper to expand_line_sal below. Search in the symtabs for any
+ linetable entry that exactly matches FILENAME and LINENO and append
+ them to RET. If there is at least one match, return 1; otherwise,
+ return 0, and return the best choice in BEST_ITEM and BEST_SYMTAB. */
+
+static int
+append_exact_match_to_sals (char *filename, int lineno,
+ struct symtabs_and_lines *ret,
+ struct linetable_entry **best_item,
+ struct symtab **best_symtab)
+{
+ struct objfile *objfile;
+ struct symtab *symtab;
+ int exact = 0;
+ int j;
+ *best_item = 0;
+ *best_symtab = 0;
+
+ ALL_SYMTABS (objfile, symtab)
+ {
+ if (strcmp (filename, symtab->filename) == 0)
+ {
+ struct linetable *l;
+ int len;
+ l = LINETABLE (symtab);
+ if (!l)
+ continue;
+ len = l->nitems;
+
+ for (j = 0; j < len; j++)
+ {
+ struct linetable_entry *item = &(l->item[j]);
+
+ if (item->line == lineno)
+ {
+ exact = 1;
+ append_expanded_sal (ret, symtab, lineno, item->pc);
+ }
+ else if (!exact && item->line > lineno
+ && (*best_item == NULL
+ || item->line < (*best_item)->line))
+
+ {
+ *best_item = item;
+ *best_symtab = symtab;
+ }
+ }
+ }
+ }
+ return exact;
+}
+
/* Compute a set of all sals in
the entire program that correspond to same file
and line as SAL and return those. If there
@@ -4494,44 +4546,15 @@ expand_line_sal (struct symtab_and_line
PSYMTAB_TO_SYMTAB (psymtab);
}
-
- /* For each symtab, we add all pcs to ret.sals. I'm actually
- not sure what to do if we have exact match in one symtab,
- and non-exact match on another symtab.
- */
- ALL_SYMTABS (objfile, symtab)
- {
- if (strcmp (sal.symtab->filename,
- symtab->filename) == 0)
- {
- struct linetable *l;
- int len;
- l = LINETABLE (symtab);
- if (!l)
- continue;
- len = l->nitems;
-
- for (j = 0; j < len; j++)
- {
- struct linetable_entry *item = &(l->item[j]);
-
- if (item->line == lineno)
- {
- exact = 1;
- append_expanded_sal (&ret, symtab, lineno, item->pc);
- }
- else if (!exact && item->line > lineno
- && (best_item == NULL || item->line < best_item->line))
-
- {
- best_item = item;
- best_symtab = symtab;
- }
- }
- }
- }
+
+ /* Now search the symtab for exact matches and append them. If
+ none is found, append the best_item and all its exact
+ matches. */
+ exact = append_exact_match_to_sals (sal.symtab->filename, lineno,
+ &ret, &best_item, &best_symtab);
if (!exact && best_item)
- append_expanded_sal (&ret, best_symtab, lineno, best_item->pc);
+ append_exact_match_to_sals (best_symtab->filename, best_item->line,
+ &ret, &best_item, &best_symtab);
}
/* For optimized code, compiler can scatter one source line accross