Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: improve error messages in veristat

Return error if preset parsing fails. Avoid proceeding with veristat run
if preset does not parse.
Before:
```
./veristat set_global_vars.bpf.o -G "arr[999999999999999999999] = 1"
Failed to parse value '999999999999999999999'
Processing 'set_global_vars.bpf.o'...
File Program Verdict Duration (us) Insns States Program size Jited size
--------------------- ---------------- ------- ------------- ----- ------ ------------ ----------
set_global_vars.bpf.o test_set_globals success 27 64 0 82 0
--------------------- ---------------- ------- ------------- ----- ------ ------------ ----------
Done. Processed 1 files, 0 programs. Skipped 1 files, 0 programs.
```
After:
```
./veristat set_global_vars.bpf.o -G "arr[999999999999999999999] = 1"
Failed to parse value '999999999999999999999'
Failed to parse global variable presets: arr[999999999999999999999] = 1
```

Improve error messages:
* If preset struct member can't be found.
* Array index out of bounds

Extract rtrim function.

Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20250627144342.686896-1-mykyta.yatsenko5@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Mykyta Yatsenko and committed by
Alexei Starovoitov
ffaff180 bacdf5a0

+25 -11
+25 -11
tools/testing/selftests/bpf/veristat.c
··· 890 890 return c == 'v' || c == 'V' || c == '.' || c == '!' || c == '_'; 891 891 } 892 892 893 + static char *rtrim(char *str) 894 + { 895 + int i; 896 + 897 + for (i = strlen(str) - 1; i > 0; --i) { 898 + if (!isspace(str[i])) 899 + break; 900 + str[i] = '\0'; 901 + } 902 + return str; 903 + } 904 + 893 905 static int parse_stat(const char *stat_name, struct stat_specs *specs) 894 906 { 895 907 int id; ··· 1678 1666 static int parse_var_atoms(const char *full_var, struct var_preset *preset) 1679 1667 { 1680 1668 char expr[256], var[256], *name, *saveptr; 1681 - int n, len, off; 1669 + int n, len, off, err; 1682 1670 1683 1671 snprintf(expr, sizeof(expr), "%s", full_var); 1684 1672 preset->atom_count = 0; ··· 1689 1677 fprintf(stderr, "Can't parse %s\n", name); 1690 1678 return -EINVAL; 1691 1679 } 1692 - append_preset_atom(preset, var, false); 1680 + err = append_preset_atom(preset, var, false); 1681 + if (err) 1682 + return err; 1693 1683 1694 1684 /* parse optional array indexes */ 1695 1685 while (off < len) { ··· 1699 1685 fprintf(stderr, "Can't parse %s as index\n", name + off); 1700 1686 return -EINVAL; 1701 1687 } 1702 - append_preset_atom(preset, var, true); 1688 + err = append_preset_atom(preset, var, true); 1689 + if (err) 1690 + return err; 1703 1691 off += n; 1704 1692 } 1705 1693 } ··· 1713 1697 void *tmp; 1714 1698 struct var_preset *cur; 1715 1699 char var[256], val[256]; 1716 - int n, err, i; 1700 + int n, err; 1717 1701 1718 1702 tmp = realloc(*presets, (*cnt + 1) * sizeof(**presets)); 1719 1703 if (!tmp) ··· 1728 1712 return -EINVAL; 1729 1713 } 1730 1714 /* Remove trailing spaces from var, as scanf may add those */ 1731 - for (i = strlen(var) - 1; i > 0; --i) { 1732 - if (!isspace(var[i])) 1733 - break; 1734 - var[i] = '\0'; 1735 - } 1715 + rtrim(var); 1736 1716 1737 1717 err = parse_rvalue(val, &cur->value); 1738 1718 if (err) ··· 1881 1869 if (err) 1882 1870 return err; 1883 1871 if (idx < 0 || idx >= barr->nelems) { 1884 - fprintf(stderr, "Array index %lld is out of bounds [0, %u]: %s\n", 1872 + fprintf(stderr, "Array index %lld is out of bounds [0, %u): %s\n", 1885 1873 idx, barr->nelems, array_name); 1886 1874 return -EINVAL; 1887 1875 } ··· 1940 1928 } 1941 1929 } 1942 1930 1943 - return -EINVAL; 1931 + return -ESRCH; 1944 1932 } 1945 1933 1946 1934 static int adjust_var_secinfo(struct btf *btf, const struct btf_type *t, ··· 1967 1955 break; 1968 1956 case FIELD_NAME: 1969 1957 err = adjust_var_secinfo_member(btf, base_type, 0, atom->name, sinfo); 1958 + if (err == -ESRCH) 1959 + fprintf(stderr, "Can't find '%s'\n", atom->name); 1970 1960 prev_name = atom->name; 1971 1961 break; 1972 1962 default: