builtin-probe.c (de1764892a61a3ed212973cc028c80dd083179dd) | builtin-probe.c (631c9def804b2c92b5cca04fb9ff7b5df9e35094) |
---|---|
1/* 2 * builtin-probe.c 3 * 4 * Builtin probe command: Set up probe events by C expression 5 * 6 * Written by Masami Hiramatsu <mhiramat@redhat.com> 7 * 8 * This program is free software; you can redistribute it and/or modify --- 41 unchanged lines hidden (view full) --- 50#define MAX_PATH_LEN 256 51#define MAX_PROBES 128 52 53/* Session management structure */ 54static struct { 55 bool need_dwarf; 56 bool list_events; 57 bool force_add; | 1/* 2 * builtin-probe.c 3 * 4 * Builtin probe command: Set up probe events by C expression 5 * 6 * Written by Masami Hiramatsu <mhiramat@redhat.com> 7 * 8 * This program is free software; you can redistribute it and/or modify --- 41 unchanged lines hidden (view full) --- 50#define MAX_PATH_LEN 256 51#define MAX_PROBES 128 52 53/* Session management structure */ 54static struct { 55 bool need_dwarf; 56 bool list_events; 57 bool force_add; |
58 bool show_lines; |
|
58 int nr_probe; 59 struct probe_point probes[MAX_PROBES]; 60 struct strlist *dellist; 61 struct perf_session *psession; 62 struct map *kmap; | 59 int nr_probe; 60 struct probe_point probes[MAX_PROBES]; 61 struct strlist *dellist; 62 struct perf_session *psession; 63 struct map *kmap; |
64 struct line_range line_range; |
|
63} session; 64 65 66/* Parse an event definition. Note that any error must die. */ 67static void parse_probe_event(const char *str) 68{ 69 struct probe_point *pp = &session.probes[session.nr_probe]; 70 --- 40 unchanged lines hidden (view full) --- 111 if (str) { 112 if (!session.dellist) 113 session.dellist = strlist__new(true, NULL); 114 strlist__add(session.dellist, str); 115 } 116 return 0; 117} 118 | 65} session; 66 67 68/* Parse an event definition. Note that any error must die. */ 69static void parse_probe_event(const char *str) 70{ 71 struct probe_point *pp = &session.probes[session.nr_probe]; 72 --- 40 unchanged lines hidden (view full) --- 113 if (str) { 114 if (!session.dellist) 115 session.dellist = strlist__new(true, NULL); 116 strlist__add(session.dellist, str); 117 } 118 return 0; 119} 120 |
121static int opt_show_lines(const struct option *opt __used, 122 const char *str, int unset __used) 123{ 124 if (str) 125 parse_line_range_desc(str, &session.line_range); 126 INIT_LIST_HEAD(&session.line_range.line_list); 127 session.show_lines = true; 128 return 0; 129} |
|
119/* Currently just checking function name from symbol map */ 120static void evaluate_probe_point(struct probe_point *pp) 121{ 122 struct symbol *sym; 123 sym = map__find_symbol_by_name(session.kmap, pp->function, 124 session.psession, NULL); 125 if (!sym) 126 die("Kernel symbol \'%s\' not found - probe not added.", --- 12 unchanged lines hidden (view full) --- 139} 140#endif 141 142static const char * const probe_usage[] = { 143 "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]", 144 "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]", 145 "perf probe [<options>] --del '[GROUP:]EVENT' ...", 146 "perf probe --list", | 130/* Currently just checking function name from symbol map */ 131static void evaluate_probe_point(struct probe_point *pp) 132{ 133 struct symbol *sym; 134 sym = map__find_symbol_by_name(session.kmap, pp->function, 135 session.psession, NULL); 136 if (!sym) 137 die("Kernel symbol \'%s\' not found - probe not added.", --- 12 unchanged lines hidden (view full) --- 150} 151#endif 152 153static const char * const probe_usage[] = { 154 "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]", 155 "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]", 156 "perf probe [<options>] --del '[GROUP:]EVENT' ...", 157 "perf probe --list", |
158 "perf probe --line 'LINEDESC'", |
|
147 NULL 148}; 149 150static const struct option options[] = { 151 OPT_BOOLEAN('v', "verbose", &verbose, 152 "be more verbose (show parsed arguments, etc)"), 153#ifndef NO_LIBDWARF 154 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, --- 22 unchanged lines hidden (view full) --- 177 "\t\tRLN:\tRelative line number from function entry.\n" 178 "\t\tALN:\tAbsolute line number in file.\n" 179 "\t\tARG:\tProbe argument (local variable name or\n" 180#endif 181 "\t\t\tkprobe-tracer argument format.)\n", 182 opt_add_probe_event), 183 OPT_BOOLEAN('f', "force", &session.force_add, "forcibly add events" 184 " with existing name"), | 159 NULL 160}; 161 162static const struct option options[] = { 163 OPT_BOOLEAN('v', "verbose", &verbose, 164 "be more verbose (show parsed arguments, etc)"), 165#ifndef NO_LIBDWARF 166 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, --- 22 unchanged lines hidden (view full) --- 189 "\t\tRLN:\tRelative line number from function entry.\n" 190 "\t\tALN:\tAbsolute line number in file.\n" 191 "\t\tARG:\tProbe argument (local variable name or\n" 192#endif 193 "\t\t\tkprobe-tracer argument format.)\n", 194 opt_add_probe_event), 195 OPT_BOOLEAN('f', "force", &session.force_add, "forcibly add events" 196 " with existing name"), |
197#ifndef NO_LIBDWARF 198 OPT_CALLBACK('L', "line", NULL, 199 "FUNC[:RLN[+NUM|:RLN2]]|SRC:ALN[+NUM|:ALN2]", 200 "Show source code lines.", opt_show_lines), 201#endif |
|
185 OPT_END() 186}; 187 | 202 OPT_END() 203}; 204 |
205/* Initialize symbol maps for vmlinux */ 206static void init_vmlinux(void) 207{ 208 symbol_conf.sort_by_name = true; 209 if (symbol_conf.vmlinux_name == NULL) 210 symbol_conf.try_vmlinux_path = true; 211 else 212 pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name); 213 if (symbol__init() < 0) 214 die("Failed to init symbol map."); 215 session.psession = perf_session__new(NULL, O_WRONLY, false); 216 if (session.psession == NULL) 217 die("Failed to init perf_session."); 218 session.kmap = session.psession->vmlinux_maps[MAP__FUNCTION]; 219 if (!session.kmap) 220 die("Could not find kernel map.\n"); 221} 222 |
|
188int cmd_probe(int argc, const char **argv, const char *prefix __used) 189{ 190 int i, ret; 191#ifndef NO_LIBDWARF 192 int fd; 193#endif 194 struct probe_point *pp; 195 196 argc = parse_options(argc, argv, options, probe_usage, 197 PARSE_OPT_STOP_AT_NON_OPTION); 198 if (argc > 0) { 199 if (strcmp(argv[0], "-") == 0) { 200 pr_warning(" Error: '-' is not supported.\n"); 201 usage_with_options(probe_usage, options); 202 } 203 parse_probe_event_argv(argc, argv); 204 } 205 | 223int cmd_probe(int argc, const char **argv, const char *prefix __used) 224{ 225 int i, ret; 226#ifndef NO_LIBDWARF 227 int fd; 228#endif 229 struct probe_point *pp; 230 231 argc = parse_options(argc, argv, options, probe_usage, 232 PARSE_OPT_STOP_AT_NON_OPTION); 233 if (argc > 0) { 234 if (strcmp(argv[0], "-") == 0) { 235 pr_warning(" Error: '-' is not supported.\n"); 236 usage_with_options(probe_usage, options); 237 } 238 parse_probe_event_argv(argc, argv); 239 } 240 |
206 if ((!session.nr_probe && !session.dellist && !session.list_events)) | 241 if ((!session.nr_probe && !session.dellist && !session.list_events && 242 !session.show_lines)) |
207 usage_with_options(probe_usage, options); 208 209 if (debugfs_valid_mountpoint(debugfs_path) < 0) 210 die("Failed to find debugfs path."); 211 212 if (session.list_events) { 213 if (session.nr_probe != 0 || session.dellist) { 214 pr_warning(" Error: Don't use --list with" 215 " --add/--del.\n"); 216 usage_with_options(probe_usage, options); 217 } | 243 usage_with_options(probe_usage, options); 244 245 if (debugfs_valid_mountpoint(debugfs_path) < 0) 246 die("Failed to find debugfs path."); 247 248 if (session.list_events) { 249 if (session.nr_probe != 0 || session.dellist) { 250 pr_warning(" Error: Don't use --list with" 251 " --add/--del.\n"); 252 usage_with_options(probe_usage, options); 253 } |
254 if (session.show_lines) { 255 pr_warning(" Error: Don't use --list with --line.\n"); 256 usage_with_options(probe_usage, options); 257 } |
|
218 show_perf_probe_events(); 219 return 0; 220 } 221 | 258 show_perf_probe_events(); 259 return 0; 260 } 261 |
262#ifndef NO_LIBDWARF 263 if (session.show_lines) { 264 if (session.nr_probe != 0 || session.dellist) { 265 pr_warning(" Error: Don't use --line with" 266 " --add/--del.\n"); 267 usage_with_options(probe_usage, options); 268 } 269 init_vmlinux(); 270 fd = open_vmlinux(); 271 if (fd < 0) 272 die("Could not open debuginfo file."); 273 ret = find_line_range(fd, &session.line_range); 274 if (ret <= 0) 275 die("Source line is not found.\n"); 276 close(fd); 277 show_line_range(&session.line_range); 278 return 0; 279 } 280#endif 281 |
|
222 if (session.dellist) { 223 del_trace_kprobe_events(session.dellist); 224 strlist__delete(session.dellist); 225 if (session.nr_probe == 0) 226 return 0; 227 } 228 | 282 if (session.dellist) { 283 del_trace_kprobe_events(session.dellist); 284 strlist__delete(session.dellist); 285 if (session.nr_probe == 0) 286 return 0; 287 } 288 |
229 /* Initialize symbol maps for vmlinux */ 230 symbol_conf.sort_by_name = true; 231 if (symbol_conf.vmlinux_name == NULL) 232 symbol_conf.try_vmlinux_path = true; 233 if (symbol__init() < 0) 234 die("Failed to init symbol map."); 235 session.psession = perf_session__new(NULL, O_WRONLY, false); 236 if (session.psession == NULL) 237 die("Failed to init perf_session."); 238 session.kmap = session.psession->vmlinux_maps[MAP__FUNCTION]; 239 if (!session.kmap) 240 die("Could not find kernel map.\n"); | 289 /* Add probes */ 290 init_vmlinux(); |
241 242 if (session.need_dwarf) 243#ifdef NO_LIBDWARF 244 die("Debuginfo-analysis is not supported"); 245#else /* !NO_LIBDWARF */ 246 pr_debug("Some probes require debuginfo.\n"); 247 248 fd = open_vmlinux(); --- 59 unchanged lines hidden --- | 291 292 if (session.need_dwarf) 293#ifdef NO_LIBDWARF 294 die("Debuginfo-analysis is not supported"); 295#else /* !NO_LIBDWARF */ 296 pr_debug("Some probes require debuginfo.\n"); 297 298 fd = open_vmlinux(); --- 59 unchanged lines hidden --- |