|
@@ -606,23 +606,22 @@ static int create_trace_probe(int argc, char **argv)
|
|
|
*/
|
|
|
struct trace_probe *tp;
|
|
|
int i, ret = 0;
|
|
|
- int is_return = 0;
|
|
|
+ int is_return = 0, is_delete = 0;
|
|
|
char *symbol = NULL, *event = NULL, *arg = NULL, *group = NULL;
|
|
|
unsigned long offset = 0;
|
|
|
void *addr = NULL;
|
|
|
char buf[MAX_EVENT_NAME_LEN];
|
|
|
|
|
|
- if (argc < 2) {
|
|
|
- pr_info("Probe point is not specified.\n");
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
+ /* argc must be >= 1 */
|
|
|
if (argv[0][0] == 'p')
|
|
|
is_return = 0;
|
|
|
else if (argv[0][0] == 'r')
|
|
|
is_return = 1;
|
|
|
+ else if (argv[0][0] == '-')
|
|
|
+ is_delete = 1;
|
|
|
else {
|
|
|
- pr_info("Probe definition must be started with 'p' or 'r'.\n");
|
|
|
+ pr_info("Probe definition must be started with 'p', 'r' or"
|
|
|
+ " '-'.\n");
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
@@ -642,7 +641,29 @@ static int create_trace_probe(int argc, char **argv)
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
}
|
|
|
+ if (!group)
|
|
|
+ group = KPROBE_EVENT_SYSTEM;
|
|
|
|
|
|
+ if (is_delete) {
|
|
|
+ if (!event) {
|
|
|
+ pr_info("Delete command needs an event name.\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ tp = find_probe_event(event, group);
|
|
|
+ if (!tp) {
|
|
|
+ pr_info("Event %s/%s doesn't exist.\n", group, event);
|
|
|
+ return -ENOENT;
|
|
|
+ }
|
|
|
+ /* delete an event */
|
|
|
+ unregister_trace_probe(tp);
|
|
|
+ free_trace_probe(tp);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (argc < 2) {
|
|
|
+ pr_info("Probe point is not specified.\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
if (isdigit(argv[1][0])) {
|
|
|
if (is_return) {
|
|
|
pr_info("Return probe point must be a symbol.\n");
|
|
@@ -671,8 +692,6 @@ static int create_trace_probe(int argc, char **argv)
|
|
|
argc -= 2; argv += 2;
|
|
|
|
|
|
/* setup a probe */
|
|
|
- if (!group)
|
|
|
- group = KPROBE_EVENT_SYSTEM;
|
|
|
if (!event) {
|
|
|
/* Make a new event name */
|
|
|
if (symbol)
|