Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [patch[ Improve the error messages of tvariable command
@ 2013-02-12 16:59 Hafiz Abid Qadeer
  2013-02-13 16:47 ` Pedro Alves
  2013-02-13 17:07 ` Pedro Alves
  0 siblings, 2 replies; 5+ messages in thread
From: Hafiz Abid Qadeer @ 2013-02-12 16:59 UTC (permalink / raw)
  To: gdb-patches, palves

[-- Attachment #1: Type: text/plain, Size: 1863 bytes --]

Hi All,
This patch improves the error message of tvariable command. The  
difference in error messages in various cases is shown below. This  
patch was originally written by Pedro. I have updated it to latest code  
and regtested. Is it ok?

Regards,
Abid

Before the patch:

(gdb) start
Temporary breakpoint 1 at 0x80483ba: file test.c, line 3.
Starting program: /home/abidh/test

Temporary breakpoint 1, main () at test.c:3
3	  int x = 1;

(gdb) list
1	int main()
2	{
3	  int x = 1;
4	  return 0;
5	}
(gdb) tvar x
Syntax must be $NAME [ = EXPR ]
(gdb) tvar y
No symbol "y" in current context.
(gdb) tvar $
Syntax must be $NAME [ = EXPR ]
(gdb) tvar $1234
Syntax must be $NAME [ = EXPR ]


After the patch:

(gdb) start
Temporary breakpoint 1 at 0x80483ba: file test.c, line 3.
Starting program: /home/abidh/test

Temporary breakpoint 1, main () at test.c:3
3	  int x = 1;

(gdb) list
1	int main()
2	{
3	  int x = 1;
4	  return 0;
5	}
(gdb) tvar x
Name of trace variable should start with '$'
(gdb) tvar y
Name of trace variable should start with '$'
(gdb) tvar $
Must supply a non-empty variable name
(gdb) tvar $1234
$1234 is not a valid trace state variable name
(gdb) tvar $asdf=1=1
Left operand of assignment is not an lvalue.



2013-02-12  Pedro Alves  <palves@redhat.com>
	    Hafiz Abid Qadeer  <abidh@codesourcery.com>

	gdb/
	* tracepoint.h (validate_trace_state_variable_name): Declare.
	* tracepoint.c (validate_trace_state_variable_name): New.
	(trace_variable_command): Parse the trace state variable's name
	without using parse_expression.  Do several validations.
	* mi/mi-main.c (mi_cmd_trace_define_variable): Don't parse the
	trace state variable's name with parse_expression.  Validate it.

	gdb/testsuite/
	* gdb.trace/tsv.exp: Adjust tests, and add a few more.


[-- Attachment #2: tvar.patch --]
[-- Type: text/x-patch, Size: 6694 bytes --]

diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 28de126aa..37294e0 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -2357,7 +2357,6 @@ void
 mi_cmd_trace_define_variable (char *command, char **argv, int argc)
 {
   struct expression *expr;
-  struct cleanup *back_to;
   LONGEST initval = 0;
   struct trace_state_variable *tsv;
   char *name = 0;
@@ -2365,19 +2364,11 @@ mi_cmd_trace_define_variable (char *command, char **argv, int argc)
   if (argc != 1 && argc != 2)
     error (_("Usage: -trace-define-variable VARIABLE [VALUE]"));
 
-  expr = parse_expression (argv[0]);
-  back_to = make_cleanup (xfree, expr);
-
-  if (expr->nelts == 3 && expr->elts[0].opcode == OP_INTERNALVAR)
-    {
-      struct internalvar *intvar = expr->elts[1].internalvar;
-
-      if (intvar)
-	name = internalvar_name (intvar);
-    }
+  name = argv[0];
+  if (*name++ != '$')
+    error (_("Name of trace variable should start with '$'"));
 
-  if (!name || *name == '\0')
-    error (_("Invalid name of trace variable"));
+  validate_trace_state_variable_name (name);
 
   tsv = find_trace_state_variable (name);
   if (!tsv)
@@ -2387,8 +2378,6 @@ mi_cmd_trace_define_variable (char *command, char **argv, int argc)
     initval = value_as_long (parse_and_eval (argv[1]));
 
   tsv->initial_value = initval;
-
-  do_cleanups (back_to);
 }
 
 void
diff --git a/gdb/testsuite/gdb.trace/tsv.exp b/gdb/testsuite/gdb.trace/tsv.exp
index 4ea930f..47d66ad 100644
--- a/gdb/testsuite/gdb.trace/tsv.exp
+++ b/gdb/testsuite/gdb.trace/tsv.exp
@@ -46,14 +46,30 @@ gdb_test "tvariable \$tvar3 = 1234567000000" \
   "Trace state variable \\\$tvar3 now has initial value 1234567000000." \
   "Init trace state variable to a 64-bit value"
 
+gdb_test "tvariable $" \
+  "Must supply a non-empty variable name" \
+  "tvariable syntax error, not empty variable name"
+
 gdb_test "tvariable main" \
-  "Syntax must be \\\$NAME \\\[ = EXPR \\\]" \
+  "Name of trace variable should start with '\\\$'" \
   "tvariable syntax error, bad name"
 
+gdb_test "tvariable \$\$" \
+  "Syntax must be \\\$NAME \\\[ = EXPR \\\]" \
+  "tvariable syntax error, bad name 2"
+
+gdb_test "tvariable \$123" \
+  "\\\$123 is not a valid trace state variable name" \
+  "tvariable syntax error, bad name 3"
+
 gdb_test "tvariable \$tvar1 - 93" \
   "Syntax must be \\\$NAME \\\[ = EXPR \\\]" \
   "tvariable syntax error, not an assignment"
 
+gdb_test "tvariable \$tvar0 = 1 = 1" \
+  "Left operand of assignment is not an lvalue\." \
+  "tvariable creation fails with invalid expression"
+
 gdb_test "info tvariables" \
     "Name\[\t \]+Initial\[\t \]+Current.*
 \\\$tvar1\[\t \]+0\[\t \]+<undefined>.*
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index b45863e..540665d 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -362,50 +362,67 @@ delete_trace_state_variable (const char *name)
   warning (_("No trace variable named \"$%s\", not deleting"), name);
 }
 
+/* Throws an error if NAME is not valid syntax for a trace state
+   variable's name.  */
+
+void
+validate_trace_state_variable_name (const char *name)
+{
+  const char *p;
+
+  if (*name == '\0')
+    error (_("Must supply a non-empty variable name"));
+
+  /* All digits in the name is reserved for value history
+     references.  */
+  for (p = name; isdigit (*p); p++)
+    ;
+  if (*p == '\0')
+    error (_("$%s is not a valid trace state variable name"), name);
+
+  for (p = name; isalnum (*p) || *p == '_'; p++)
+    ;
+  if (*p != '\0')
+    error (_("$%s is not a valid trace state variable name"), name);
+}
+
 /* The 'tvariable' command collects a name and optional expression to
    evaluate into an initial value.  */
 
 static void
 trace_variable_command (char *args, int from_tty)
 {
-  struct expression *expr;
   struct cleanup *old_chain;
-  struct internalvar *intvar = NULL;
   LONGEST initval = 0;
   struct trace_state_variable *tsv;
+  char *name, *p;
 
   if (!args || !*args)
-    error_no_arg (_("trace state variable name"));
+    error_no_arg (_("Syntax is $NAME [ = EXPR ]"));
 
-  /* All the possible valid arguments are expressions.  */
-  expr = parse_expression (args);
-  old_chain = make_cleanup (free_current_contents, &expr);
+  /* Only allow two syntaxes; "$name" and "$name=value".  */
+  p = skip_spaces (args);
 
-  if (expr->nelts == 0)
-    error (_("No expression?"));
+  if (*p++ != '$')
+    error (_("Name of trace variable should start with '$'"));
 
-  /* Only allow two syntaxes; "$name" and "$name=value".  */
-  if (expr->elts[0].opcode == OP_INTERNALVAR)
-    {
-      intvar = expr->elts[1].internalvar;
-    }
-  else if (expr->elts[0].opcode == BINOP_ASSIGN
-	   && expr->elts[1].opcode == OP_INTERNALVAR)
-    {
-      intvar = expr->elts[2].internalvar;
-      initval = value_as_long (evaluate_subexpression_type (expr, 4));
-    }
-  else
+  name = p;
+  while (isalnum (*p) || *p == '_')
+    p++;
+  name = savestring (name, p - name);
+  old_chain = make_cleanup (xfree, name);
+
+  p = skip_spaces (p);
+  if (*p != '=' && *p != '\0')
     error (_("Syntax must be $NAME [ = EXPR ]"));
 
-  if (!intvar)
-    error (_("No name given"));
+  validate_trace_state_variable_name (name);
 
-  if (strlen (internalvar_name (intvar)) <= 0)
-    error (_("Must supply a non-empty variable name"));
+  if (*p == '=')
+    initval = value_as_long (parse_and_eval (++p));
 
   /* If the variable already exists, just change its initial value.  */
-  tsv = find_trace_state_variable (internalvar_name (intvar));
+  tsv = find_trace_state_variable (name);
   if (tsv)
     {
       if (tsv->initial_value != initval)
@@ -421,7 +438,7 @@ trace_variable_command (char *args, int from_tty)
     }
 
   /* Create a new variable.  */
-  tsv = create_trace_state_variable (internalvar_name (intvar));
+  tsv = create_trace_state_variable (name);
   tsv->initial_value = initval;
 
   observer_notify_tsv_created (tsv);
diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h
index 2e1d83a..61c7212 100644
--- a/gdb/tracepoint.h
+++ b/gdb/tracepoint.h
@@ -246,6 +246,7 @@ extern void validate_actionline (char **, struct breakpoint *);
 
 extern void end_actions_pseudocommand (char *args, int from_tty);
 extern void while_stepping_pseudocommand (char *args, int from_tty);
+extern void validate_trace_state_variable_name (const char *name);
 
 extern struct trace_state_variable *find_trace_state_variable (const char *name);
 extern struct trace_state_variable *create_trace_state_variable (const char *name);

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch[ Improve the error messages of tvariable command
  2013-02-12 16:59 [patch[ Improve the error messages of tvariable command Hafiz Abid Qadeer
@ 2013-02-13 16:47 ` Pedro Alves
  2013-02-13 16:58   ` Abid, Hafiz
  2013-02-13 17:07 ` Pedro Alves
  1 sibling, 1 reply; 5+ messages in thread
From: Pedro Alves @ 2013-02-13 16:47 UTC (permalink / raw)
  To: Hafiz Abid Qadeer; +Cc: gdb-patches, palves

I somewhat remember investigating this, and writing a longer
rationale for the change -- the gist of it being not
handling tsv name as expressions.   Can you dig it out from
the internal archives and repost including that info?  It'd
be good for posterity.

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch[ Improve the error messages of tvariable command
  2013-02-13 16:47 ` Pedro Alves
@ 2013-02-13 16:58   ` Abid, Hafiz
  2013-02-13 17:01     ` Pedro Alves
  0 siblings, 1 reply; 5+ messages in thread
From: Abid, Hafiz @ 2013-02-13 16:58 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches, palves

On 13/02/13 16:47:38, Pedro Alves wrote:
> I somewhat remember investigating this, and writing a longer
> rationale for the change -- the gist of it being not
> handling tsv name as expressions.   Can you dig it out from
> the internal archives and repost including that info?  It'd
> be good for posterity.
> 
> --
> Pedro Alves
> 
> 

Here is what I found. Is it what you were expecting?

--

Here's a fix for issue #8161, which is about the "tvariable" returning
errors on invalid and tsv names.  E.g.,

  Temporary breakpoint 1, main () at a.cc:2
  2           int x = 1;
  (gdb) tvar x
  Syntax must be $NAME [ = EXPR ]
  (gdb) tvar y
  No symbol "y" in current context.

The problem is the use of parse_expression to parse the tvariable's
name.  We could merely always catch errors thrown from within
parse_expression, and issue a "usage" error, but it wouldn't cover
all cases correctly.  E.g.,

  (gdb) tvar x = nonexistingvariable

is an invalid expression, not invalid syntax.

I also noticed that

  (gdb) tvar x = 1 = 1

would be incorrectly accepted.

Given that the comand is documented to only take an expression
on the right side of the '=', it seems that whatever is on
the left side of the '=' should not be treated as an expression, but
literaly as "$NAME".  That's what the patch does.

MI now shares the same name validations as the CLI variant.

--

Regards,
Abid


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch[ Improve the error messages of tvariable command
  2013-02-13 16:58   ` Abid, Hafiz
@ 2013-02-13 17:01     ` Pedro Alves
  0 siblings, 0 replies; 5+ messages in thread
From: Pedro Alves @ 2013-02-13 17:01 UTC (permalink / raw)
  To: Abid, Hafiz; +Cc: gdb-patches

On 02/13/2013 04:58 PM, Abid, Hafiz wrote:
> On 13/02/13 16:47:38, Pedro Alves wrote:
>> I somewhat remember investigating this, and writing a longer
>> rationale for the change -- the gist of it being not
>> handling tsv name as expressions.   Can you dig it out from
>> the internal archives and repost including that info?  It'd
>> be good for posterity.
>>
>> -- 
>> Pedro Alves
>>
>>
> 
> Here is what I found. Is it what you were expecting?
> 
> -- 
> 
> Here's a fix for issue #8161, which is about the "tvariable" returning
> errors on invalid and tsv names.  E.g.,
> 
>  Temporary breakpoint 1, main () at a.cc:2
>  2           int x = 1;
>  (gdb) tvar x
>  Syntax must be $NAME [ = EXPR ]
>  (gdb) tvar y
>  No symbol "y" in current context.
> 
> The problem is the use of parse_expression to parse the tvariable's
> name.  We could merely always catch errors thrown from within
> parse_expression, and issue a "usage" error, but it wouldn't cover
> all cases correctly.  E.g.,
> 
>  (gdb) tvar x = nonexistingvariable
> 
> is an invalid expression, not invalid syntax.
> 
> I also noticed that
> 
>  (gdb) tvar x = 1 = 1
> 
> would be incorrectly accepted.
> 
> Given that the comand is documented to only take an expression
> on the right side of the '=', it seems that whatever is on
> the left side of the '=' should not be treated as an expression, but
> literaly as "$NAME".  That's what the patch does.

Ah, that's it.  Thanks for digging it out.

> MI now shares the same name validations as the CLI variant.

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch[ Improve the error messages of tvariable command
  2013-02-12 16:59 [patch[ Improve the error messages of tvariable command Hafiz Abid Qadeer
  2013-02-13 16:47 ` Pedro Alves
@ 2013-02-13 17:07 ` Pedro Alves
  1 sibling, 0 replies; 5+ messages in thread
From: Pedro Alves @ 2013-02-13 17:07 UTC (permalink / raw)
  To: Hafiz Abid Qadeer; +Cc: gdb-patches

On 02/12/2013 04:59 PM, Hafiz Abid Qadeer wrote:
> Hi All,
> This patch improves the error message of tvariable command. The difference in error messages in various cases is shown below.
> This patch was originally written by Pedro.
> I have updated it to latest code and regtested.
> Is it ok?

OK, but ...

> 2013-02-12  Pedro Alves  <palves@redhat.com>

Write pedro@codesourcery.com.

>         Hafiz Abid Qadeer  <abidh@codesourcery.com>

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-02-13 17:07 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-12 16:59 [patch[ Improve the error messages of tvariable command Hafiz Abid Qadeer
2013-02-13 16:47 ` Pedro Alves
2013-02-13 16:58   ` Abid, Hafiz
2013-02-13 17:01     ` Pedro Alves
2013-02-13 17:07 ` Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox