diff options
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r-- | tools/perf/util/probe-event.c | 55 |
1 files changed, 15 insertions, 40 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 7335a3b5e494..e3a683ab976f 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | #undef _GNU_SOURCE | 33 | #undef _GNU_SOURCE |
34 | #include "event.h" | 34 | #include "event.h" |
35 | #include "string.h" | ||
35 | #include "debug.h" | 36 | #include "debug.h" |
36 | #include "parse-events.h" /* For debugfs_path */ | 37 | #include "parse-events.h" /* For debugfs_path */ |
37 | #include "probe-event.h" | 38 | #include "probe-event.h" |
@@ -132,62 +133,36 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp) | |||
132 | /* Parse perf-probe event definition */ | 133 | /* Parse perf-probe event definition */ |
133 | int parse_perf_probe_event(const char *str, struct probe_point *pp) | 134 | int parse_perf_probe_event(const char *str, struct probe_point *pp) |
134 | { | 135 | { |
135 | char *argv[MAX_PROBE_ARGS + 1]; /* probe + args */ | 136 | char **argv; |
136 | int argc, i, need_dwarf = 0; | 137 | int argc, i, need_dwarf = 0; |
137 | 138 | ||
138 | /* Separate arguments, similar to argv_split */ | 139 | argv = argv_split(str, &argc); |
139 | argc = 0; | 140 | if (!argv) |
140 | do { | 141 | die("argv_split failed."); |
141 | /* Skip separators */ | 142 | if (argc > MAX_PROBE_ARGS + 1) |
142 | while (isspace(*str)) | 143 | semantic_error("Too many arguments"); |
143 | str++; | ||
144 | |||
145 | /* Add an argument */ | ||
146 | if (*str != '\0') { | ||
147 | const char *s = str; | ||
148 | /* Check the limit number of arguments */ | ||
149 | if (argc == MAX_PROBE_ARGS + 1) | ||
150 | semantic_error("Too many arguments"); | ||
151 | |||
152 | /* Skip the argument */ | ||
153 | while (!isspace(*str) && *str != '\0') | ||
154 | str++; | ||
155 | |||
156 | /* Duplicate the argument */ | ||
157 | argv[argc] = strndup(s, str - s); | ||
158 | if (argv[argc] == NULL) | ||
159 | die("strndup"); | ||
160 | pr_debug("argv[%d]=%s\n", argc, argv[argc]); | ||
161 | argc++; | ||
162 | } | ||
163 | } while (*str != '\0'); | ||
164 | if (!argc) | ||
165 | semantic_error("An empty argument."); | ||
166 | 144 | ||
167 | /* Parse probe point */ | 145 | /* Parse probe point */ |
168 | parse_perf_probe_probepoint(argv[0], pp); | 146 | parse_perf_probe_probepoint(argv[0], pp); |
169 | free(argv[0]); | ||
170 | if (pp->file || pp->line) | 147 | if (pp->file || pp->line) |
171 | need_dwarf = 1; | 148 | need_dwarf = 1; |
172 | 149 | ||
173 | /* Copy arguments */ | 150 | /* Copy arguments and ensure return probe has no C argument */ |
174 | pp->nr_args = argc - 1; | 151 | pp->nr_args = argc - 1; |
175 | if (pp->nr_args > 0) { | 152 | pp->args = zalloc(sizeof(char *) * pp->nr_args); |
176 | pp->args = (char **)malloc(sizeof(char *) * pp->nr_args); | 153 | for (i = 0; i < pp->nr_args; i++) { |
177 | if (!pp->args) | 154 | pp->args[i] = strdup(argv[i + 1]); |
178 | die("malloc"); | 155 | if (!pp->args[i]) |
179 | memcpy(pp->args, &argv[1], sizeof(char *) * pp->nr_args); | 156 | die("Failed to copy argument."); |
180 | } | ||
181 | |||
182 | /* Ensure return probe has no C argument */ | ||
183 | for (i = 0; i < pp->nr_args; i++) | ||
184 | if (is_c_varname(pp->args[i])) { | 157 | if (is_c_varname(pp->args[i])) { |
185 | if (pp->retprobe) | 158 | if (pp->retprobe) |
186 | semantic_error("You can't specify local" | 159 | semantic_error("You can't specify local" |
187 | " variable for kretprobe"); | 160 | " variable for kretprobe"); |
188 | need_dwarf = 1; | 161 | need_dwarf = 1; |
189 | } | 162 | } |
163 | } | ||
190 | 164 | ||
165 | argv_free(argv); | ||
191 | return need_dwarf; | 166 | return need_dwarf; |
192 | } | 167 | } |
193 | 168 | ||