RFC: allow breakpoints on labels
Tom Tromey
tromey@redhat.com
Tue Jul 13 20:07:00 GMT 2010
>>>>> "Tom" == Tom Tromey <tromey@redhat.com> writes:
Tom> This has been sitting around for almost a year:
Tom> http://sourceware.org/ml/gdb-patches/2009-08/msg00322.html
I needed to set the pspace on the new sal, and I took the opportunity to
update the .exp file as well. Here is the patch I am committing.
Tom
2010-07-13 Tom Tromey <tromey@redhat.com>
PR breakpoints/8357:
* symtab.h (domain_enum_tag) <LABEL_DOMAIN>: Update comment.
* linespec.c (decode_line_1): Update comment. Call decode_label.
(decode_label): New function.
(symbol_found): Handle LOC_LABEL.
* dwarf2read.c (new_symbol) <DW_TAG_label>: Set symbol's type and
domain. Call add_symbol_to_list.
2010-07-13 Tom Tromey <tromey@redhat.com>
* gdb.texinfo (Specify Location): Document labels.
2010-07-13 Tom Tromey <tromey@redhat.com>
* gdb.base/label.exp: New file.
* gdb.base/label.c: New file.
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.412
diff -u -r1.412 dwarf2read.c
--- dwarf2read.c 13 Jul 2010 15:09:03 -0000 1.412
+++ dwarf2read.c 13 Jul 2010 20:04:43 -0000
@@ -8807,7 +8807,10 @@
{
SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr) + baseaddr;
}
+ SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_core_addr;
+ SYMBOL_DOMAIN (sym) = LABEL_DOMAIN;
SYMBOL_CLASS (sym) = LOC_LABEL;
+ add_symbol_to_list (sym, cu->list_in_scope);
break;
case DW_TAG_subprogram:
/* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
Index: linespec.c
===================================================================
RCS file: /cvs/src/src/gdb/linespec.c,v
retrieving revision 1.103
diff -u -r1.103 linespec.c
--- linespec.c 14 May 2010 23:41:04 -0000 1.103
+++ linespec.c 13 Jul 2010 20:04:43 -0000
@@ -122,6 +122,9 @@
char ***canonical,
struct symtab *file_symtab);
+static int decode_label (char *copy, char ***canonical,
+ struct symtabs_and_lines *result);
+
static struct symtabs_and_lines decode_variable (char *copy,
int funfirstline,
char ***canonical,
@@ -672,6 +675,7 @@
FILE:LINENUM -- that line in that file. PC returned is 0.
FUNCTION -- line number of openbrace of that function.
PC returned is the start of the function.
+ LABEL -- a label in the current scope
VARIABLE -- line number of definition of that variable.
PC returned is 0.
FILE:FUNCTION -- likewise, but prefer functions in that file.
@@ -903,6 +907,16 @@
return decode_dollar (copy, funfirstline, default_symtab,
canonical, file_symtab);
+ /* Try the token as a label, but only if no file was specified,
+ because we can only really find labels in the current scope. */
+
+ if (!file_symtab)
+ {
+ struct symtabs_and_lines label_result;
+ if (decode_label (copy, canonical, &label_result))
+ return label_result;
+ }
+
/* Look up that token as a variable.
If file specified, use that file's per-file block to start with. */
@@ -1838,6 +1852,27 @@
+/* A helper for decode_line_1 that tries to find a label. The label
+ is searched for in the current block.
+ COPY is the name of the label to find.
+ CANONICAL is the same as the "canonical" argument to decode_line_1.
+ RESULT is a pointer to a symtabs_and_lines structure which will be
+ filled in on success.
+ This function returns 1 if a label was found, 0 otherwise. */
+
+static int
+decode_label (char *copy, char ***canonical, struct symtabs_and_lines *result)
+{
+ struct symbol *sym;
+
+ sym = lookup_symbol (copy, get_selected_block (0), LABEL_DOMAIN, 0);
+
+ if (sym != NULL)
+ *result = symbol_found (0, canonical, copy, sym, NULL);
+
+ return sym != NULL;
+}
+
/* Decode a linespec that's a variable. If FILE_SYMTAB is non-NULL,
look in that symtab's static variables first. If NOT_FOUND_PTR is not NULL and
the function cannot be found, store boolean true in the location pointed to
@@ -1917,7 +1952,7 @@
}
else
{
- if (funfirstline)
+ if (funfirstline && SYMBOL_CLASS (sym) != LOC_LABEL)
error (_("\"%s\" is not a function"), copy);
else if (SYMBOL_LINE (sym) != 0)
{
@@ -1928,6 +1963,7 @@
memset (&values.sals[0], 0, sizeof (values.sals[0]));
values.sals[0].symtab = SYMBOL_SYMTAB (sym);
values.sals[0].line = SYMBOL_LINE (sym);
+ values.sals[0].pspace = SYMTAB_PSPACE (SYMBOL_SYMTAB (sym));
return values;
}
else
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.154
diff -u -r1.154 symtab.h
--- symtab.h 28 Jun 2010 20:35:52 -0000 1.154
+++ symtab.h 13 Jul 2010 20:04:44 -0000
@@ -377,8 +377,7 @@
STRUCT_DOMAIN,
- /* LABEL_DOMAIN may be used for names of labels (for gotos);
- currently it is not used and labels are not recorded at all. */
+ /* LABEL_DOMAIN may be used for names of labels (for gotos). */
LABEL_DOMAIN,
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.737
diff -u -r1.737 gdb.texinfo
--- doc/gdb.texinfo 1 Jul 2010 17:40:04 -0000 1.737
+++ doc/gdb.texinfo 13 Jul 2010 20:04:47 -0000
@@ -6330,6 +6330,13 @@
function name to avoid ambiguity when there are identically named
functions in different source files.
+@item @var{label}
+Specifies the line at which the label named @var{label} appears.
+@value{GDBN} searches for the label in the function corresponding to
+the currently selected stack frame. If there is no current selected
+stack frame (for instance, if the inferior is not running), then
+@value{GDBN} will not search for a label.
+
@item *@var{address}
Specifies the program address @var{address}. For line-oriented
commands, such as @code{list} and @code{edit}, this specifies a source
Index: testsuite/gdb.base/label.c
===================================================================
RCS file: testsuite/gdb.base/label.c
diff -N testsuite/gdb.base/label.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.base/label.c 13 Jul 2010 20:04:49 -0000
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int
+main (int argc, char *argv)
+{
+ int i = 0;
+ goto there;
+
+here:
+ printf("not here\n");
+ i = 1;
+
+there:
+ printf("but here\n");
+ if (i == 0)
+ goto here;
+
+done:
+ return 0;
+}
+
Index: testsuite/gdb.base/label.exp
===================================================================
RCS file: testsuite/gdb.base/label.exp
diff -N testsuite/gdb.base/label.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.base/label.exp 13 Jul 2010 20:04:49 -0000
@@ -0,0 +1,59 @@
+# Copyright 2010 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
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+
+if [is_remote target] then {
+ return 0
+}
+
+
+#
+# test running programs
+#
+
+set testfile "label"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [prepare_for_testing ${testfile}.exp $testfile ${testfile}.c debug] } {
+ untested label.exp
+ return -1
+}
+
+
+if {![runto_main]} {
+ fail "label tests suppressed"
+ return -1
+}
+
+gdb_test "break here" \
+ "Breakpoint.*at.*" \
+ "breakpoint here"
+
+gdb_test "break there" \
+ "Breakpoint.*at.*" \
+ "breakpoint there"
+
+gdb_test "cont" \
+ "Breakpoint 3,.*" \
+ "continue to 'there'"
+
+gdb_test "cont" \
+ "Breakpoint 2,.*" \
+ "continue to 'here'"
More information about the Gdb-patches
mailing list