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 15:48:53 -0500 |
commit | 820874c75ea0d3a9c22d69d6eaad42a279d6756c (patch) | |
tree | 96cc2880f8bccb0d6d76e6eb518a2cfd533f50e4 /lib | |
parent | 5ca7d2a6c5e4f24dfe39e8383c6d32e61d95d16a (diff) |
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 cde4dfe2b2d5..5a7bacc2e901 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c | |||
@@ -276,6 +276,19 @@ static char *unescape(char *str) | |||
276 | return str; | 276 | return str; |
277 | } | 277 | } |
278 | 278 | ||
279 | static int check_set(const char **dest, char *src, char *name) | ||
280 | { | ||
281 | int rc = 0; | ||
282 | |||
283 | if (*dest) { | ||
284 | rc = -EINVAL; | ||
285 | pr_err("match-spec:%s val:%s overridden by %s", | ||
286 | name, *dest, src); | ||
287 | } | ||
288 | *dest = src; | ||
289 | return rc; | ||
290 | } | ||
291 | |||
279 | /* | 292 | /* |
280 | * Parse words[] as a ddebug query specification, which is a series | 293 | * Parse words[] as a ddebug query specification, which is a series |
281 | * of (keyword, value) pairs chosen from these possibilities: | 294 | * of (keyword, value) pairs chosen from these possibilities: |
@@ -287,11 +300,15 @@ static char *unescape(char *str) | |||
287 | * format <escaped-string-to-find-in-format> | 300 | * format <escaped-string-to-find-in-format> |
288 | * line <lineno> | 301 | * line <lineno> |
289 | * line <first-lineno>-<last-lineno> // where either may be empty | 302 | * line <first-lineno>-<last-lineno> // where either may be empty |
303 | * | ||
304 | * Only 1 of each type is allowed. | ||
305 | * Returns 0 on success, <0 on error. | ||
290 | */ | 306 | */ |
291 | static int ddebug_parse_query(char *words[], int nwords, | 307 | static int ddebug_parse_query(char *words[], int nwords, |
292 | struct ddebug_query *query) | 308 | struct ddebug_query *query) |
293 | { | 309 | { |
294 | unsigned int i; | 310 | unsigned int i; |
311 | int rc; | ||
295 | 312 | ||
296 | /* check we have an even number of words */ | 313 | /* check we have an even number of words */ |
297 | if (nwords % 2 != 0) | 314 | if (nwords % 2 != 0) |
@@ -300,24 +317,32 @@ static int ddebug_parse_query(char *words[], int nwords, | |||
300 | 317 | ||
301 | for (i = 0 ; i < nwords ; i += 2) { | 318 | for (i = 0 ; i < nwords ; i += 2) { |
302 | if (!strcmp(words[i], "func")) | 319 | if (!strcmp(words[i], "func")) |
303 | query->function = words[i+1]; | 320 | rc = check_set(&query->function, words[i+1], "func"); |
304 | else if (!strcmp(words[i], "file")) | 321 | else if (!strcmp(words[i], "file")) |
305 | query->filename = words[i+1]; | 322 | rc = check_set(&query->filename, words[i+1], "file"); |
306 | else if (!strcmp(words[i], "module")) | 323 | else if (!strcmp(words[i], "module")) |
307 | query->module = words[i+1]; | 324 | rc = check_set(&query->module, words[i+1], "module"); |
308 | else if (!strcmp(words[i], "format")) | 325 | else if (!strcmp(words[i], "format")) |
309 | query->format = unescape(words[i+1]); | 326 | rc = check_set(&query->format, unescape(words[i+1]), |
327 | "format"); | ||
310 | else if (!strcmp(words[i], "line")) { | 328 | else if (!strcmp(words[i], "line")) { |
311 | char *first = words[i+1]; | 329 | char *first = words[i+1]; |
312 | char *last = strchr(first, '-'); | 330 | char *last = strchr(first, '-'); |
331 | if (query->first_lineno || query->last_lineno) { | ||
332 | pr_err("match-spec:line given 2 times\n"); | ||
333 | return -EINVAL; | ||
334 | } | ||
313 | if (last) | 335 | if (last) |
314 | *last++ = '\0'; | 336 | *last++ = '\0'; |
315 | if (parse_lineno(first, &query->first_lineno) < 0) | 337 | if (parse_lineno(first, &query->first_lineno) < 0) |
316 | return -EINVAL; | 338 | return -EINVAL; |
317 | if (last != NULL) { | 339 | if (last) { |
318 | /* range <first>-<last> */ | 340 | /* range <first>-<last> */ |
319 | if (parse_lineno(last, &query->last_lineno) < 0) | 341 | if (parse_lineno(last, &query->last_lineno) |
342 | < query->first_lineno) { | ||
343 | pr_err("last-line < 1st-line\n"); | ||
320 | return -EINVAL; | 344 | return -EINVAL; |
345 | } | ||
321 | } else { | 346 | } else { |
322 | query->last_lineno = query->first_lineno; | 347 | query->last_lineno = query->first_lineno; |
323 | } | 348 | } |
@@ -325,6 +350,8 @@ static int ddebug_parse_query(char *words[], int nwords, | |||
325 | pr_err("unknown keyword \"%s\"\n", words[i]); | 350 | pr_err("unknown keyword \"%s\"\n", words[i]); |
326 | return -EINVAL; | 351 | return -EINVAL; |
327 | } | 352 | } |
353 | if (rc) | ||
354 | return rc; | ||
328 | } | 355 | } |
329 | 356 | ||
330 | if (verbose) | 357 | if (verbose) |