[v4,26/39] dyndbg: warn if no flags are given

Message ID 20240210235009.2405808-27-ukaszb@chromium.org
State New
Headers
Series dyndbg: add support for writing debug logs to trace |

Commit Message

Ɓukasz Bartosik Feb. 10, 2024, 11:49 p.m. UTC
  From: Jim Cromie <jim.cromie@gmail.com>

Since [1,2], ``cat control`` has displayed callsites without flags as
``=_``, to positively assert that no flags are set.

It also took that as input, and the docs also tried to encourage its
use, allowing users to expressly assert that all flags are unset by
this operation:

  alias ddcmd='echo $* > /proc/dynamic_debug/control'

  ddcmd =_	# assert no-flags
  ddcmd =	# allowed, grandfathered

Now, warn on the latter.  This allows to disambiguate the meaning of
the :<label> extension:

  ddcmd =	# if this is dis-allowed,
  ddcmd =_	# then this is required to unset all

This positive assertion *allows* the grammar to specify both/either
flags and a :<label> independently and unambiguously:

  ddcmd =_:foo	# unset all flags, set the foo label
  ddcmd =:foo	# (only) set the foo label, since no flags are given.

The semantics of setting a label: callsite.dest=map[N], differ
slightly from setting the boolean flags; both ``+=`` op-flags set a
label.

And then the meaning of ``-:foo`` can be decided; either dest=0, or
dest=map[N] (just like ``+=``).  I prefer latter, since former can be
seen as turning off only foo, which is the label keyword's job.

Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 lib/dynamic_debug.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
  

Patch

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index d8cd40faeb4d..3a9dd73357c8 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -884,6 +884,7 @@  static int ddebug_parse_flags(const char *str, struct flag_settings *modifiers)
 {
 	read_flag_args_f read_args;
 	int op, i;
+	char *fst;
 
 	switch (*str) {
 	case '+':
@@ -896,7 +897,7 @@  static int ddebug_parse_flags(const char *str, struct flag_settings *modifiers)
 		return -EINVAL;
 	}
 
-	for (; *str ; ++str) {
+	for (fst = (char *)str; *str ; ++str, fst++) {
 		for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
 			if (*str == opt_array[i].opt_char) {
 				modifiers->flags |= opt_array[i].flag;
@@ -917,6 +918,9 @@  static int ddebug_parse_flags(const char *str, struct flag_settings *modifiers)
 			return -EINVAL;
 		}
 	}
+	/* warn if no flags/labels are given */
+	if (!(str - fst))
+		pr_err("no flags or label is specified, please use _ to assert no-flags\n");
 
 	/* calculate final flags, mask based upon op */
 	switch (op) {