aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJim Cromie <jim.cromie@gmail.com>2011-12-19 17:12:49 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2012-01-24 15:48:53 -0500
commit820874c75ea0d3a9c22d69d6eaad42a279d6756c (patch)
tree96cc2880f8bccb0d6d76e6eb518a2cfd533f50e4 /lib
parent5ca7d2a6c5e4f24dfe39e8383c6d32e61d95d16a (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.c39
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)
276 return str; 276 return str;
277} 277}
278 278
279static 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 */
291static int ddebug_parse_query(char *words[], int nwords, 307static 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)