mirror of https://github.com/torvalds/linux.git
tracing: uprobes: Cleanup __trace_uprobe_create() with __free()
Use __free() to cleanup ugly gotos in __trace_uprobe_create(). Link: https://lore.kernel.org/all/175509540482.193596.6541098946023873304.stgit@devnote2/ Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
This commit is contained in:
parent
0d6edbc9a4
commit
8b658df206
|
|
@ -533,22 +533,25 @@ static int register_trace_uprobe(struct trace_uprobe *tu)
|
|||
return ret;
|
||||
}
|
||||
|
||||
DEFINE_FREE(free_trace_uprobe, struct trace_uprobe *, if (_T) free_trace_uprobe(_T))
|
||||
|
||||
/*
|
||||
* Argument syntax:
|
||||
* - Add uprobe: p|r[:[GRP/][EVENT]] PATH:OFFSET[%return][(REF)] [FETCHARGS]
|
||||
*/
|
||||
static int __trace_uprobe_create(int argc, const char **argv)
|
||||
{
|
||||
struct trace_uprobe *tu __free(free_trace_uprobe) = NULL;
|
||||
const char *trlog __free(trace_probe_log_clear) = NULL;
|
||||
const char *event = NULL, *group = UPROBE_EVENT_SYSTEM;
|
||||
char *arg, *filename, *rctr, *rctr_end, *tmp;
|
||||
struct path path __free(path_put) = {};
|
||||
unsigned long offset, ref_ctr_offset;
|
||||
char *filename __free(kfree) = NULL;
|
||||
char *arg, *rctr, *rctr_end, *tmp;
|
||||
char *gbuf __free(kfree) = NULL;
|
||||
char *buf __free(kfree) = NULL;
|
||||
enum probe_print_type ptype;
|
||||
struct trace_uprobe *tu;
|
||||
bool is_return = false;
|
||||
struct path path;
|
||||
int i, ret;
|
||||
|
||||
ref_ctr_offset = 0;
|
||||
|
|
@ -586,10 +589,8 @@ static int __trace_uprobe_create(int argc, const char **argv)
|
|||
|
||||
/* Find the last occurrence, in case the path contains ':' too. */
|
||||
arg = strrchr(filename, ':');
|
||||
if (!arg || !isdigit(arg[1])) {
|
||||
kfree(filename);
|
||||
if (!arg || !isdigit(arg[1]))
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
trace_probe_log_set_index(1); /* filename is the 2nd argument */
|
||||
|
||||
|
|
@ -597,13 +598,11 @@ static int __trace_uprobe_create(int argc, const char **argv)
|
|||
ret = kern_path(filename, LOOKUP_FOLLOW, &path);
|
||||
if (ret) {
|
||||
trace_probe_log_err(0, FILE_NOT_FOUND);
|
||||
kfree(filename);
|
||||
return ret;
|
||||
}
|
||||
if (!d_is_reg(path.dentry)) {
|
||||
trace_probe_log_err(0, NO_REGULAR_FILE);
|
||||
ret = -EINVAL;
|
||||
goto fail_address_parse;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Parse reference counter offset if specified. */
|
||||
|
|
@ -611,16 +610,14 @@ static int __trace_uprobe_create(int argc, const char **argv)
|
|||
if (rctr) {
|
||||
rctr_end = strchr(rctr, ')');
|
||||
if (!rctr_end) {
|
||||
ret = -EINVAL;
|
||||
rctr_end = rctr + strlen(rctr);
|
||||
trace_probe_log_err(rctr_end - filename,
|
||||
REFCNT_OPEN_BRACE);
|
||||
goto fail_address_parse;
|
||||
return -EINVAL;
|
||||
} else if (rctr_end[1] != '\0') {
|
||||
ret = -EINVAL;
|
||||
trace_probe_log_err(rctr_end + 1 - filename,
|
||||
BAD_REFCNT_SUFFIX);
|
||||
goto fail_address_parse;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*rctr++ = '\0';
|
||||
|
|
@ -628,7 +625,7 @@ static int __trace_uprobe_create(int argc, const char **argv)
|
|||
ret = kstrtoul(rctr, 0, &ref_ctr_offset);
|
||||
if (ret) {
|
||||
trace_probe_log_err(rctr - filename, BAD_REFCNT);
|
||||
goto fail_address_parse;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -640,8 +637,7 @@ static int __trace_uprobe_create(int argc, const char **argv)
|
|||
is_return = true;
|
||||
} else {
|
||||
trace_probe_log_err(tmp - filename, BAD_ADDR_SUFFIX);
|
||||
ret = -EINVAL;
|
||||
goto fail_address_parse;
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -649,7 +645,7 @@ static int __trace_uprobe_create(int argc, const char **argv)
|
|||
ret = kstrtoul(arg, 0, &offset);
|
||||
if (ret) {
|
||||
trace_probe_log_err(arg - filename, BAD_UPROBE_OFFS);
|
||||
goto fail_address_parse;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* setup a probe */
|
||||
|
|
@ -657,12 +653,12 @@ static int __trace_uprobe_create(int argc, const char **argv)
|
|||
if (event) {
|
||||
gbuf = kmalloc(MAX_EVENT_NAME_LEN, GFP_KERNEL);
|
||||
if (!gbuf)
|
||||
goto fail_mem;
|
||||
return -ENOMEM;
|
||||
|
||||
ret = traceprobe_parse_event_name(&event, &group, gbuf,
|
||||
event - argv[0]);
|
||||
if (ret)
|
||||
goto fail_address_parse;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!event) {
|
||||
|
|
@ -671,7 +667,7 @@ static int __trace_uprobe_create(int argc, const char **argv)
|
|||
|
||||
tail = kstrdup(kbasename(filename), GFP_KERNEL);
|
||||
if (!tail)
|
||||
goto fail_mem;
|
||||
return -ENOMEM;
|
||||
|
||||
ptr = strpbrk(tail, ".-_");
|
||||
if (ptr)
|
||||
|
|
@ -679,7 +675,7 @@ static int __trace_uprobe_create(int argc, const char **argv)
|
|||
|
||||
buf = kmalloc(MAX_EVENT_NAME_LEN, GFP_KERNEL);
|
||||
if (!buf)
|
||||
goto fail_mem;
|
||||
return -ENOMEM;
|
||||
snprintf(buf, MAX_EVENT_NAME_LEN, "%c_%s_0x%lx", 'p', tail, offset);
|
||||
event = buf;
|
||||
kfree(tail);
|
||||
|
|
@ -693,49 +689,37 @@ static int __trace_uprobe_create(int argc, const char **argv)
|
|||
ret = PTR_ERR(tu);
|
||||
/* This must return -ENOMEM otherwise there is a bug */
|
||||
WARN_ON_ONCE(ret != -ENOMEM);
|
||||
goto fail_address_parse;
|
||||
return ret;
|
||||
}
|
||||
tu->offset = offset;
|
||||
tu->ref_ctr_offset = ref_ctr_offset;
|
||||
tu->path = path;
|
||||
tu->filename = filename;
|
||||
/* Clear @path so that it will not freed by path_put() */
|
||||
memset(&path, 0, sizeof(path));
|
||||
tu->filename = no_free_ptr(filename);
|
||||
|
||||
/* parse arguments */
|
||||
for (i = 0; i < argc; i++) {
|
||||
struct traceprobe_parse_context *ctx __free(traceprobe_parse_context)
|
||||
= kzalloc(sizeof(*ctx), GFP_KERNEL);
|
||||
|
||||
if (!ctx) {
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
ctx->flags = (is_return ? TPARG_FL_RETURN : 0) | TPARG_FL_USER;
|
||||
trace_probe_log_set_index(i + 2);
|
||||
ret = traceprobe_parse_probe_arg(&tu->tp, i, argv[i], ctx);
|
||||
if (ret)
|
||||
goto error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ptype = is_ret_probe(tu) ? PROBE_PRINT_RETURN : PROBE_PRINT_NORMAL;
|
||||
ret = traceprobe_set_print_fmt(&tu->tp, ptype);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
return ret;
|
||||
|
||||
ret = register_trace_uprobe(tu);
|
||||
if (!ret)
|
||||
goto out;
|
||||
|
||||
error:
|
||||
free_trace_uprobe(tu);
|
||||
out:
|
||||
return ret;
|
||||
|
||||
fail_mem:
|
||||
ret = -ENOMEM;
|
||||
|
||||
fail_address_parse:
|
||||
path_put(&path);
|
||||
kfree(filename);
|
||||
tu = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue