diff options
| author | Jim Cromie <jim.cromie@gmail.com> | 2011-12-19 17:12:49 -0500 | 
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2012-01-24 12:48:53 -0800 | 
| commit | 820874c75ea0d3a9c22d69d6eaad42a279d6756c (patch) | |
| tree | 96cc2880f8bccb0d6d76e6eb518a2cfd533f50e4 /lib | |
| parent | 5ca7d2a6c5e4f24dfe39e8383c6d32e61d95d16a (diff) | |
| download | olio-linux-3.10-820874c75ea0d3a9c22d69d6eaad42a279d6756c.tar.xz olio-linux-3.10-820874c75ea0d3a9c22d69d6eaad42a279d6756c.zip  | |
dynamic_debug: tighten up error checking on debug queries
Issue error when a match-spec is given multiple times in a rule.
Previous code kept last one, but was silent about it.  Docs imply only
one is allowed by saying match-specs are ANDed together, given that
module M cannot match both A and B.  Also error when last_line < 1st_line.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Signed-off-by: Jason Baron <jbaron@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/dynamic_debug.c | 39 | 
1 files changed, 33 insertions, 6 deletions
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index cde4dfe2b2d..5a7bacc2e90 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -276,6 +276,19 @@ static char *unescape(char *str)  	return str;  } +static int check_set(const char **dest, char *src, char *name) +{ +	int rc = 0; + +	if (*dest) { +		rc = -EINVAL; +		pr_err("match-spec:%s val:%s overridden by %s", +			name, *dest, src); +	} +	*dest = src; +	return rc; +} +  /*   * Parse words[] as a ddebug query specification, which is a series   * of (keyword, value) pairs chosen from these possibilities: @@ -287,11 +300,15 @@ static char *unescape(char *str)   * format <escaped-string-to-find-in-format>   * line <lineno>   * line <first-lineno>-<last-lineno> // where either may be empty + * + * Only 1 of each type is allowed. + * Returns 0 on success, <0 on error.   */  static int ddebug_parse_query(char *words[], int nwords,  			       struct ddebug_query *query)  {  	unsigned int i; +	int rc;  	/* check we have an even number of words */  	if (nwords % 2 != 0) @@ -300,24 +317,32 @@ static int ddebug_parse_query(char *words[], int nwords,  	for (i = 0 ; i < nwords ; i += 2) {  		if (!strcmp(words[i], "func")) -			query->function = words[i+1]; +			rc = check_set(&query->function, words[i+1], "func");  		else if (!strcmp(words[i], "file")) -			query->filename = words[i+1]; +			rc = check_set(&query->filename, words[i+1], "file");  		else if (!strcmp(words[i], "module")) -			query->module = words[i+1]; +			rc = check_set(&query->module, words[i+1], "module");  		else if (!strcmp(words[i], "format")) -			query->format = unescape(words[i+1]); +			rc = check_set(&query->format, unescape(words[i+1]), +				"format");  		else if (!strcmp(words[i], "line")) {  			char *first = words[i+1];  			char *last = strchr(first, '-'); +			if (query->first_lineno || query->last_lineno) { +				pr_err("match-spec:line given 2 times\n"); +				return -EINVAL; +			}  			if (last)  				*last++ = '\0';  			if (parse_lineno(first, &query->first_lineno) < 0)  				return -EINVAL; -			if (last != NULL) { +			if (last) {  				/* range <first>-<last> */ -				if (parse_lineno(last, &query->last_lineno) < 0) +				if (parse_lineno(last, &query->last_lineno) +				    < query->first_lineno) { +					pr_err("last-line < 1st-line\n");  					return -EINVAL; +				}  			} else {  				query->last_lineno = query->first_lineno;  			} @@ -325,6 +350,8 @@ static int ddebug_parse_query(char *words[], int nwords,  			pr_err("unknown keyword \"%s\"\n", words[i]);  			return -EINVAL;  		} +		if (rc) +			return rc;  	}  	if (verbose)  |