diff options
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r-- | tools/perf/util/probe-event.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 91f55f24fa9d..fa156f008e0b 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -119,14 +119,14 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp) | |||
119 | char c, nc = 0; | 119 | char c, nc = 0; |
120 | /* | 120 | /* |
121 | * <Syntax> | 121 | * <Syntax> |
122 | * perf probe [EVENT=]SRC:LN | 122 | * perf probe [EVENT=]SRC[:LN|;PTN] |
123 | * perf probe [EVENT=]FUNC[+OFFS|%return][@SRC] | 123 | * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT] |
124 | * | 124 | * |
125 | * TODO:Group name support | 125 | * TODO:Group name support |
126 | */ | 126 | */ |
127 | 127 | ||
128 | ptr = strchr(arg, '='); | 128 | ptr = strpbrk(arg, ";=@+%"); |
129 | if (ptr) { /* Event name */ | 129 | if (ptr && *ptr == '=') { /* Event name */ |
130 | *ptr = '\0'; | 130 | *ptr = '\0'; |
131 | tmp = ptr + 1; | 131 | tmp = ptr + 1; |
132 | ptr = strchr(arg, ':'); | 132 | ptr = strchr(arg, ':'); |
@@ -139,7 +139,7 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp) | |||
139 | arg = tmp; | 139 | arg = tmp; |
140 | } | 140 | } |
141 | 141 | ||
142 | ptr = strpbrk(arg, ":+@%"); | 142 | ptr = strpbrk(arg, ";:+@%"); |
143 | if (ptr) { | 143 | if (ptr) { |
144 | nc = *ptr; | 144 | nc = *ptr; |
145 | *ptr++ = '\0'; | 145 | *ptr++ = '\0'; |
@@ -156,7 +156,11 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp) | |||
156 | while (ptr) { | 156 | while (ptr) { |
157 | arg = ptr; | 157 | arg = ptr; |
158 | c = nc; | 158 | c = nc; |
159 | ptr = strpbrk(arg, ":+@%"); | 159 | if (c == ';') { /* Lazy pattern must be the last part */ |
160 | pp->lazy_line = strdup(arg); | ||
161 | break; | ||
162 | } | ||
163 | ptr = strpbrk(arg, ";:+@%"); | ||
160 | if (ptr) { | 164 | if (ptr) { |
161 | nc = *ptr; | 165 | nc = *ptr; |
162 | *ptr++ = '\0'; | 166 | *ptr++ = '\0'; |
@@ -165,13 +169,13 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp) | |||
165 | case ':': /* Line number */ | 169 | case ':': /* Line number */ |
166 | pp->line = strtoul(arg, &tmp, 0); | 170 | pp->line = strtoul(arg, &tmp, 0); |
167 | if (*tmp != '\0') | 171 | if (*tmp != '\0') |
168 | semantic_error("There is non-digit charactor" | 172 | semantic_error("There is non-digit char" |
169 | " in line number."); | 173 | " in line number."); |
170 | break; | 174 | break; |
171 | case '+': /* Byte offset from a symbol */ | 175 | case '+': /* Byte offset from a symbol */ |
172 | pp->offset = strtoul(arg, &tmp, 0); | 176 | pp->offset = strtoul(arg, &tmp, 0); |
173 | if (*tmp != '\0') | 177 | if (*tmp != '\0') |
174 | semantic_error("There is non-digit charactor" | 178 | semantic_error("There is non-digit character" |
175 | " in offset."); | 179 | " in offset."); |
176 | break; | 180 | break; |
177 | case '@': /* File name */ | 181 | case '@': /* File name */ |
@@ -179,9 +183,6 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp) | |||
179 | semantic_error("SRC@SRC is not allowed."); | 183 | semantic_error("SRC@SRC is not allowed."); |
180 | pp->file = strdup(arg); | 184 | pp->file = strdup(arg); |
181 | DIE_IF(pp->file == NULL); | 185 | DIE_IF(pp->file == NULL); |
182 | if (ptr) | ||
183 | semantic_error("@SRC must be the last " | ||
184 | "option."); | ||
185 | break; | 186 | break; |
186 | case '%': /* Probe places */ | 187 | case '%': /* Probe places */ |
187 | if (strcmp(arg, "return") == 0) { | 188 | if (strcmp(arg, "return") == 0) { |
@@ -196,11 +197,18 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp) | |||
196 | } | 197 | } |
197 | 198 | ||
198 | /* Exclusion check */ | 199 | /* Exclusion check */ |
200 | if (pp->lazy_line && pp->line) | ||
201 | semantic_error("Lazy pattern can't be used with line number."); | ||
202 | |||
203 | if (pp->lazy_line && pp->offset) | ||
204 | semantic_error("Lazy pattern can't be used with offset."); | ||
205 | |||
199 | if (pp->line && pp->offset) | 206 | if (pp->line && pp->offset) |
200 | semantic_error("Offset can't be used with line number."); | 207 | semantic_error("Offset can't be used with line number."); |
201 | 208 | ||
202 | if (!pp->line && pp->file && !pp->function) | 209 | if (!pp->line && !pp->lazy_line && pp->file && !pp->function) |
203 | semantic_error("File always requires line number."); | 210 | semantic_error("File always requires line number or " |
211 | "lazy pattern."); | ||
204 | 212 | ||
205 | if (pp->offset && !pp->function) | 213 | if (pp->offset && !pp->function) |
206 | semantic_error("Offset requires an entry function."); | 214 | semantic_error("Offset requires an entry function."); |
@@ -208,11 +216,13 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp) | |||
208 | if (pp->retprobe && !pp->function) | 216 | if (pp->retprobe && !pp->function) |
209 | semantic_error("Return probe requires an entry function."); | 217 | semantic_error("Return probe requires an entry function."); |
210 | 218 | ||
211 | if ((pp->offset || pp->line) && pp->retprobe) | 219 | if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) |
212 | semantic_error("Offset/Line can't be used with return probe."); | 220 | semantic_error("Offset/Line/Lazy pattern can't be used with " |
221 | "return probe."); | ||
213 | 222 | ||
214 | pr_debug("symbol:%s file:%s line:%d offset:%d, return:%d\n", | 223 | pr_debug("symbol:%s file:%s line:%d offset:%d return:%d lazy:%s\n", |
215 | pp->function, pp->file, pp->line, pp->offset, pp->retprobe); | 224 | pp->function, pp->file, pp->line, pp->offset, pp->retprobe, |
225 | pp->lazy_line); | ||
216 | } | 226 | } |
217 | 227 | ||
218 | /* Parse perf-probe event definition */ | 228 | /* Parse perf-probe event definition */ |
@@ -456,6 +466,8 @@ static void clear_probe_point(struct probe_point *pp) | |||
456 | free(pp->function); | 466 | free(pp->function); |
457 | if (pp->file) | 467 | if (pp->file) |
458 | free(pp->file); | 468 | free(pp->file); |
469 | if (pp->lazy_line) | ||
470 | free(pp->lazy_line); | ||
459 | for (i = 0; i < pp->nr_args; i++) | 471 | for (i = 0; i < pp->nr_args; i++) |
460 | free(pp->args[i]); | 472 | free(pp->args[i]); |
461 | if (pp->args) | 473 | if (pp->args) |