trace-event-scripting.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * trace-event-scripting. Scripting engine common and initialization code.
  4. *
  5. * Copyright (C) 2009-2010 Tom Zanussi <tzanussi@gmail.com>
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <errno.h>
  11. #ifdef HAVE_LIBTRACEEVENT
  12. #include <event-parse.h>
  13. #endif
  14. #include "debug.h"
  15. #include "event.h"
  16. #include "trace-event.h"
  17. #include "evsel.h"
  18. #include <linux/perf_event.h>
  19. #include <linux/zalloc.h>
  20. #include "util/sample.h"
  21. unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
  22. struct scripting_context *scripting_context;
  23. struct script_spec {
  24. struct list_head node;
  25. struct scripting_ops *ops;
  26. char spec[];
  27. };
  28. static LIST_HEAD(script_specs);
  29. static struct script_spec *script_spec__new(const char *spec,
  30. struct scripting_ops *ops)
  31. {
  32. struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1);
  33. if (s != NULL) {
  34. strcpy(s->spec, spec);
  35. s->ops = ops;
  36. }
  37. return s;
  38. }
  39. static void script_spec__add(struct script_spec *s)
  40. {
  41. list_add_tail(&s->node, &script_specs);
  42. }
  43. static struct script_spec *script_spec__find(const char *spec)
  44. {
  45. struct script_spec *s;
  46. list_for_each_entry(s, &script_specs, node)
  47. if (strcasecmp(s->spec, spec) == 0)
  48. return s;
  49. return NULL;
  50. }
  51. static int script_spec_register(const char *spec, struct scripting_ops *ops)
  52. {
  53. struct script_spec *s;
  54. s = script_spec__find(spec);
  55. if (s)
  56. return -1;
  57. s = script_spec__new(spec, ops);
  58. if (!s)
  59. return -1;
  60. script_spec__add(s);
  61. return 0;
  62. }
  63. struct scripting_ops *script_spec__lookup(const char *spec)
  64. {
  65. struct script_spec *s = script_spec__find(spec);
  66. if (!s)
  67. return NULL;
  68. return s->ops;
  69. }
  70. int script_spec__for_each(int (*cb)(struct scripting_ops *ops, const char *spec))
  71. {
  72. struct script_spec *s;
  73. int ret = 0;
  74. list_for_each_entry(s, &script_specs, node) {
  75. ret = cb(s->ops, s->spec);
  76. if (ret)
  77. break;
  78. }
  79. return ret;
  80. }
  81. void scripting_context__update(struct scripting_context *c,
  82. union perf_event *event,
  83. struct perf_sample *sample,
  84. struct evsel *evsel,
  85. struct addr_location *al,
  86. struct addr_location *addr_al)
  87. {
  88. #ifdef HAVE_LIBTRACEEVENT
  89. const struct tep_event *tp_format = evsel__tp_format(evsel);
  90. c->pevent = tp_format ? tp_format->tep : NULL;
  91. #else
  92. c->pevent = NULL;
  93. #endif
  94. c->event_data = sample->raw_data;
  95. c->event = event;
  96. c->sample = sample;
  97. c->evsel = evsel;
  98. c->al = al;
  99. c->addr_al = addr_al;
  100. }
  101. static int flush_script_unsupported(void)
  102. {
  103. return 0;
  104. }
  105. static int stop_script_unsupported(void)
  106. {
  107. return 0;
  108. }
  109. static void process_event_unsupported(union perf_event *event __maybe_unused,
  110. struct perf_sample *sample __maybe_unused,
  111. struct evsel *evsel __maybe_unused,
  112. struct addr_location *al __maybe_unused,
  113. struct addr_location *addr_al __maybe_unused)
  114. {
  115. }
  116. static void print_python_unsupported_msg(void)
  117. {
  118. fprintf(stderr, "Python scripting not supported."
  119. " Install libpython and rebuild perf to enable it.\n"
  120. "For example:\n # apt-get install python-dev (ubuntu)"
  121. "\n # yum install python-devel (Fedora)"
  122. "\n etc.\n");
  123. }
  124. static int python_start_script_unsupported(const char *script __maybe_unused,
  125. int argc __maybe_unused,
  126. const char **argv __maybe_unused,
  127. struct perf_session *session __maybe_unused)
  128. {
  129. print_python_unsupported_msg();
  130. return -1;
  131. }
  132. static int python_generate_script_unsupported(struct tep_handle *pevent
  133. __maybe_unused,
  134. const char *outfile
  135. __maybe_unused)
  136. {
  137. print_python_unsupported_msg();
  138. return -1;
  139. }
  140. struct scripting_ops python_scripting_unsupported_ops = {
  141. .name = "Python",
  142. .dirname = "python",
  143. .start_script = python_start_script_unsupported,
  144. .flush_script = flush_script_unsupported,
  145. .stop_script = stop_script_unsupported,
  146. .process_event = process_event_unsupported,
  147. .generate_script = python_generate_script_unsupported,
  148. };
  149. static void register_python_scripting(struct scripting_ops *scripting_ops)
  150. {
  151. if (scripting_context == NULL)
  152. scripting_context = malloc(sizeof(*scripting_context));
  153. if (scripting_context == NULL ||
  154. script_spec_register("Python", scripting_ops) ||
  155. script_spec_register("py", scripting_ops)) {
  156. pr_err("Error registering Python script extension: disabling it\n");
  157. zfree(&scripting_context);
  158. }
  159. }
  160. #ifndef HAVE_LIBPYTHON_SUPPORT
  161. void setup_python_scripting(void)
  162. {
  163. register_python_scripting(&python_scripting_unsupported_ops);
  164. }
  165. #else
  166. extern struct scripting_ops python_scripting_ops;
  167. void setup_python_scripting(void)
  168. {
  169. register_python_scripting(&python_scripting_ops);
  170. }
  171. #endif
  172. #ifdef HAVE_LIBTRACEEVENT
  173. static void print_perl_unsupported_msg(void)
  174. {
  175. fprintf(stderr, "Perl scripting not supported."
  176. " Install libperl and rebuild perf to enable it.\n"
  177. "For example:\n # apt-get install libperl-dev (ubuntu)"
  178. "\n # yum install 'perl(ExtUtils::Embed)' (Fedora)"
  179. "\n etc.\n");
  180. }
  181. static int perl_start_script_unsupported(const char *script __maybe_unused,
  182. int argc __maybe_unused,
  183. const char **argv __maybe_unused,
  184. struct perf_session *session __maybe_unused)
  185. {
  186. print_perl_unsupported_msg();
  187. return -1;
  188. }
  189. static int perl_generate_script_unsupported(struct tep_handle *pevent
  190. __maybe_unused,
  191. const char *outfile __maybe_unused)
  192. {
  193. print_perl_unsupported_msg();
  194. return -1;
  195. }
  196. struct scripting_ops perl_scripting_unsupported_ops = {
  197. .name = "Perl",
  198. .dirname = "perl",
  199. .start_script = perl_start_script_unsupported,
  200. .flush_script = flush_script_unsupported,
  201. .stop_script = stop_script_unsupported,
  202. .process_event = process_event_unsupported,
  203. .generate_script = perl_generate_script_unsupported,
  204. };
  205. static void register_perl_scripting(struct scripting_ops *scripting_ops)
  206. {
  207. if (scripting_context == NULL)
  208. scripting_context = malloc(sizeof(*scripting_context));
  209. if (scripting_context == NULL ||
  210. script_spec_register("Perl", scripting_ops) ||
  211. script_spec_register("pl", scripting_ops)) {
  212. pr_err("Error registering Perl script extension: disabling it\n");
  213. zfree(&scripting_context);
  214. }
  215. }
  216. #ifndef HAVE_LIBPERL_SUPPORT
  217. void setup_perl_scripting(void)
  218. {
  219. register_perl_scripting(&perl_scripting_unsupported_ops);
  220. }
  221. #else
  222. extern struct scripting_ops perl_scripting_ops;
  223. void setup_perl_scripting(void)
  224. {
  225. register_perl_scripting(&perl_scripting_ops);
  226. }
  227. #endif
  228. #endif
  229. static const struct {
  230. u32 flags;
  231. const char *name;
  232. } sample_flags[] = {
  233. {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"},
  234. {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"},
  235. {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"},
  236. {PERF_IP_FLAG_BRANCH, "jmp"},
  237. {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"},
  238. {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"},
  239. {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"},
  240. {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"},
  241. {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"},
  242. {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | PERF_IP_FLAG_INTERRUPT,
  243. "hw int"},
  244. {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"},
  245. {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"},
  246. {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"},
  247. {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_VMENTRY, "vmentry"},
  248. {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_VMEXIT, "vmexit"},
  249. {0, NULL}
  250. };
  251. static const struct {
  252. u32 flags;
  253. const char *name;
  254. } branch_events[] = {
  255. {PERF_IP_FLAG_BRANCH_MISS, "miss"},
  256. {PERF_IP_FLAG_NOT_TAKEN, "not_taken"},
  257. {0, NULL}
  258. };
  259. static int sample_flags_to_name(u32 flags, char *str, size_t size)
  260. {
  261. int i;
  262. const char *prefix;
  263. int pos = 0, ret, ev_idx = 0;
  264. u32 xf = flags & PERF_ADDITIONAL_STATE_MASK;
  265. u32 types, events;
  266. char xs[16] = { 0 };
  267. /* Clear additional state bits */
  268. flags &= ~PERF_ADDITIONAL_STATE_MASK;
  269. if (flags & PERF_IP_FLAG_TRACE_BEGIN)
  270. prefix = "tr strt ";
  271. else if (flags & PERF_IP_FLAG_TRACE_END)
  272. prefix = "tr end ";
  273. else
  274. prefix = "";
  275. ret = snprintf(str + pos, size - pos, "%s", prefix);
  276. if (ret < 0)
  277. return ret;
  278. pos += ret;
  279. flags &= ~(PERF_IP_FLAG_TRACE_BEGIN | PERF_IP_FLAG_TRACE_END);
  280. types = flags & ~PERF_IP_FLAG_BRANCH_EVENT_MASK;
  281. for (i = 0; sample_flags[i].name; i++) {
  282. if (sample_flags[i].flags != types)
  283. continue;
  284. ret = snprintf(str + pos, size - pos, "%s", sample_flags[i].name);
  285. if (ret < 0)
  286. return ret;
  287. pos += ret;
  288. break;
  289. }
  290. events = flags & PERF_IP_FLAG_BRANCH_EVENT_MASK;
  291. for (i = 0; branch_events[i].name; i++) {
  292. if (!(branch_events[i].flags & events))
  293. continue;
  294. ret = snprintf(str + pos, size - pos, !ev_idx ? "/%s" : ",%s",
  295. branch_events[i].name);
  296. if (ret < 0)
  297. return ret;
  298. pos += ret;
  299. ev_idx++;
  300. }
  301. /* Add an end character '/' for events */
  302. if (ev_idx) {
  303. ret = snprintf(str + pos, size - pos, "/");
  304. if (ret < 0)
  305. return ret;
  306. pos += ret;
  307. }
  308. if (!xf)
  309. return pos;
  310. snprintf(xs, sizeof(xs), "(%s%s%s)",
  311. flags & PERF_IP_FLAG_IN_TX ? "x" : "",
  312. flags & PERF_IP_FLAG_INTR_DISABLE ? "D" : "",
  313. flags & PERF_IP_FLAG_INTR_TOGGLE ? "t" : "");
  314. /* Right align the string if its length is less than the limit */
  315. if ((pos + strlen(xs)) < SAMPLE_FLAGS_STR_ALIGNED_SIZE)
  316. ret = snprintf(str + pos, size - pos, "%*s",
  317. (int)(SAMPLE_FLAGS_STR_ALIGNED_SIZE - ret), xs);
  318. else
  319. ret = snprintf(str + pos, size - pos, " %s", xs);
  320. if (ret < 0)
  321. return ret;
  322. return pos + ret;
  323. }
  324. int perf_sample__sprintf_flags(u32 flags, char *str, size_t sz)
  325. {
  326. const char *chars = PERF_IP_FLAG_CHARS;
  327. const size_t n = strlen(PERF_IP_FLAG_CHARS);
  328. size_t i, pos = 0;
  329. int ret;
  330. ret = sample_flags_to_name(flags, str, sz);
  331. if (ret > 0)
  332. return ret;
  333. for (i = 0; i < n; i++, flags >>= 1) {
  334. if ((flags & 1) && pos < sz)
  335. str[pos++] = chars[i];
  336. }
  337. for (; i < 32; i++, flags >>= 1) {
  338. if ((flags & 1) && pos < sz)
  339. str[pos++] = '?';
  340. }
  341. if (pos < sz)
  342. str[pos] = 0;
  343. return pos;
  344. }