This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]