From 7c09e5a0f7f3612c42e52d90056f73167cdb4ae5 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Thu, 11 Oct 2012 16:12:05 +0000 Subject: [PATCH] PR breakpoints/14643. * linespec.c (struct ls_parser): New member keyword_ok. (linespec_lexer_lex_string): Add comment. (linespec_lexer_lex_one): Ignore keywords if it's the wrong place for one. (parse_linespec): Set keyword_ok. testsuite/ * gdb.linespec/ls-errs.exp: Change tests of "b if|task|thread". * gdb.linespec/thread.c: New file. * gdb.linespec/thread.exp: New file. --- gdb/ChangeLog | 9 ++++++++ gdb/linespec.c | 22 ++++++++++++++++-- gdb/testsuite/ChangeLog | 5 +++++ gdb/testsuite/gdb.linespec/ls-errs.exp | 2 +- gdb/testsuite/gdb.linespec/thread.c | 31 +++++++++++++++++++++++++ gdb/testsuite/gdb.linespec/thread.exp | 41 ++++++++++++++++++++++++++++++++++ 6 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 gdb/testsuite/gdb.linespec/thread.c create mode 100644 gdb/testsuite/gdb.linespec/thread.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7955f5f..8b07e47 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2012-10-11 Doug Evans + + PR breakpoints/14643. + * linespec.c (struct ls_parser): New member keyword_ok. + (linespec_lexer_lex_string): Add comment. + (linespec_lexer_lex_one): Ignore keywords if it's the wrong place + for one. + (parse_linespec): Set keyword_ok. + 2012-10-10 Doug Evans * dwarf2read.c (process_psymtab_comp_unit_reader): Remove duplicate diff --git a/gdb/linespec.c b/gdb/linespec.c index 3edc09f..06634d2 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -286,6 +286,11 @@ struct ls_parser /* Is the entire linespec quote-enclosed? */ int is_quote_enclosed; + /* Is a keyword syntactically valid at this point? + In, e.g., "break thread thread 1", the leading "keyword" must not + be interpreted as such. */ + int keyword_ok; + /* The state of the parse. */ struct linespec_state state; #define PARSER_STATE(PPTR) (&(PPTR)->state) @@ -607,6 +612,10 @@ linespec_lexer_lex_string (linespec_parser *parser) if (isspace (*PARSER_STREAM (parser))) { p = skip_spaces (PARSER_STREAM (parser)); + /* When we get here we know we've found something followed by + a space (we skip over parens and templates below). + So if we find a keyword now, we know it is a keyword and not, + say, a function name. */ if (linespec_lexer_lex_keyword (p) != NULL) { LS_TOKEN_STOKEN (token).ptr = start; @@ -716,8 +725,10 @@ linespec_lexer_lex_one (linespec_parser *parser) /* Skip any whitespace. */ PARSER_STREAM (parser) = skip_spaces (PARSER_STREAM (parser)); - /* Check for a keyword. */ - keyword = linespec_lexer_lex_keyword (PARSER_STREAM (parser)); + /* Check for a keyword, they end the linespec. */ + keyword = NULL; + if (parser->keyword_ok) + keyword = linespec_lexer_lex_keyword (PARSER_STREAM (parser)); if (keyword != NULL) { parser->lexer.current.type = LSTOKEN_KEYWORD; @@ -2024,6 +2035,10 @@ parse_linespec (linespec_parser *parser, char **argptr) } } + /* A keyword at the start cannot be interpreted as such. + Consider "b thread thread 42". */ + parser->keyword_ok = 0; + parser->lexer.saved_arg = *argptr; parser->lexer.stream = argptr; file_exception.reason = 0; @@ -2098,6 +2113,9 @@ parse_linespec (linespec_parser *parser, char **argptr) else if (token.type != LSTOKEN_STRING && token.type != LSTOKEN_NUMBER) unexpected_linespec_error (parser); + /* Now we can recognize keywords. */ + parser->keyword_ok = 1; + /* Shortcut: If the next token is not LSTOKEN_COLON, we know that this token cannot represent a filename. */ token = linespec_lexer_peek_token (parser); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index b58e351..4354197 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2012-10-11 Doug Evans + PR breakpoints/14643. + * gdb.linespec/ls-errs.exp: Change tests of "b if|task|thread". + * gdb.linespec/thread.c: New file. + * gdb.linespec/thread.exp: New file. + * lib/gdb.exp (gdb_breakpoint): Fix varargs scan. Recognize "message" -> print pass and fail. Add eof case. (runto): Recognize message, no-message. Print pass/fail if requested, diff --git a/gdb/testsuite/gdb.linespec/ls-errs.exp b/gdb/testsuite/gdb.linespec/ls-errs.exp index 5668397..7ee2623 100644 --- a/gdb/testsuite/gdb.linespec/ls-errs.exp +++ b/gdb/testsuite/gdb.linespec/ls-errs.exp @@ -171,7 +171,7 @@ foreach x {"3" "+100" "-100" "foo"} { } foreach x {"if" "task" "thread"} { - add the_tests $x unexpected_opt "keyword" $x + add the_tests $x invalid_function $x } add the_tests "'main.c'flubber" unexpected_opt "string" "flubber" diff --git a/gdb/testsuite/gdb.linespec/thread.c b/gdb/testsuite/gdb.linespec/thread.c new file mode 100644 index 0000000..185e4a3 --- /dev/null +++ b/gdb/testsuite/gdb.linespec/thread.c @@ -0,0 +1,31 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2012 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://sourceware.org/bugzilla/show_bug.cgi?id=14643 */ + +static void +thread () +{ +} + +int +main () +{ + int x = 0; + thread (); /* set breakpoint 1 here */ + return x; +} diff --git a/gdb/testsuite/gdb.linespec/thread.exp b/gdb/testsuite/gdb.linespec/thread.exp new file mode 100644 index 0000000..1e8ee46 --- /dev/null +++ b/gdb/testsuite/gdb.linespec/thread.exp @@ -0,0 +1,41 @@ +# Copyright 2012 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://sourceware.org/bugzilla/show_bug.cgi?id=14643 +# gdb 7.5 thinks "thread" is a linespec keyword. + +standard_testfile +set exefile $testfile + +if {[prepare_for_testing $testfile $exefile $srcfile {debug}]} { + return -1 +} + +if ![runto_main] { + fail "Can't run to main" + return 0 +} + +set bp_location1 [gdb_get_line_number "set breakpoint 1 here"] + +gdb_test "break $srcfile:$bp_location1" \ + "Breakpoint.*at.* file .*$srcfile, line $bp_location1\\." \ + "breakpoint line number in file" + +gdb_continue_to_breakpoint "$bp_location1" + +gdb_breakpoint "thread" "message" + +gdb_continue_to_breakpoint "thread function" -- 2.7.4