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

From: Łukasz Bartosik
Date: Sat Feb 10 2024 - 18:56:54 EST


From: Jim Cromie <jim.cromie@xxxxxxxxx>

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@xxxxxxxxx>
---
lib/dynamic_debug.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

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) {
--
2.43.0.687.g38aa6559b0-goog