trace-event-perl.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. /*
  2. * trace-event-perl. Feed perf trace events to an embedded Perl interpreter.
  3. *
  4. * Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. *
  20. */
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <ctype.h>
  25. #include <errno.h>
  26. #include "../perf.h"
  27. #include "util.h"
  28. #include "trace-event.h"
  29. #include "trace-event-perl.h"
  30. INTERP my_perl;
  31. #define FTRACE_MAX_EVENT \
  32. ((1 << (sizeof(unsigned short) * 8)) - 1)
  33. struct event *events[FTRACE_MAX_EVENT];
  34. static struct scripting_context *scripting_context;
  35. static char *cur_field_name;
  36. static int zero_flag_atom;
  37. static void define_symbolic_value(const char *ev_name,
  38. const char *field_name,
  39. const char *field_value,
  40. const char *field_str)
  41. {
  42. unsigned long long value;
  43. dSP;
  44. value = eval_flag(field_value);
  45. ENTER;
  46. SAVETMPS;
  47. PUSHMARK(SP);
  48. XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
  49. XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
  50. XPUSHs(sv_2mortal(newSVuv(value)));
  51. XPUSHs(sv_2mortal(newSVpv(field_str, 0)));
  52. PUTBACK;
  53. if (get_cv("main::define_symbolic_value", 0))
  54. call_pv("main::define_symbolic_value", G_SCALAR);
  55. SPAGAIN;
  56. PUTBACK;
  57. FREETMPS;
  58. LEAVE;
  59. }
  60. static void define_symbolic_values(struct print_flag_sym *field,
  61. const char *ev_name,
  62. const char *field_name)
  63. {
  64. define_symbolic_value(ev_name, field_name, field->value, field->str);
  65. if (field->next)
  66. define_symbolic_values(field->next, ev_name, field_name);
  67. }
  68. static void define_symbolic_field(const char *ev_name,
  69. const char *field_name)
  70. {
  71. dSP;
  72. ENTER;
  73. SAVETMPS;
  74. PUSHMARK(SP);
  75. XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
  76. XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
  77. PUTBACK;
  78. if (get_cv("main::define_symbolic_field", 0))
  79. call_pv("main::define_symbolic_field", G_SCALAR);
  80. SPAGAIN;
  81. PUTBACK;
  82. FREETMPS;
  83. LEAVE;
  84. }
  85. static void define_flag_value(const char *ev_name,
  86. const char *field_name,
  87. const char *field_value,
  88. const char *field_str)
  89. {
  90. unsigned long long value;
  91. dSP;
  92. value = eval_flag(field_value);
  93. ENTER;
  94. SAVETMPS;
  95. PUSHMARK(SP);
  96. XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
  97. XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
  98. XPUSHs(sv_2mortal(newSVuv(value)));
  99. XPUSHs(sv_2mortal(newSVpv(field_str, 0)));
  100. PUTBACK;
  101. if (get_cv("main::define_flag_value", 0))
  102. call_pv("main::define_flag_value", G_SCALAR);
  103. SPAGAIN;
  104. PUTBACK;
  105. FREETMPS;
  106. LEAVE;
  107. }
  108. static void define_flag_values(struct print_flag_sym *field,
  109. const char *ev_name,
  110. const char *field_name)
  111. {
  112. define_flag_value(ev_name, field_name, field->value, field->str);
  113. if (field->next)
  114. define_flag_values(field->next, ev_name, field_name);
  115. }
  116. static void define_flag_field(const char *ev_name,
  117. const char *field_name,
  118. const char *delim)
  119. {
  120. dSP;
  121. ENTER;
  122. SAVETMPS;
  123. PUSHMARK(SP);
  124. XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
  125. XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
  126. XPUSHs(sv_2mortal(newSVpv(delim, 0)));
  127. PUTBACK;
  128. if (get_cv("main::define_flag_field", 0))
  129. call_pv("main::define_flag_field", G_SCALAR);
  130. SPAGAIN;
  131. PUTBACK;
  132. FREETMPS;
  133. LEAVE;
  134. }
  135. static void define_event_symbols(struct event *event,
  136. const char *ev_name,
  137. struct print_arg *args)
  138. {
  139. switch (args->type) {
  140. case PRINT_NULL:
  141. break;
  142. case PRINT_ATOM:
  143. define_flag_value(ev_name, cur_field_name, "0",
  144. args->atom.atom);
  145. zero_flag_atom = 0;
  146. break;
  147. case PRINT_FIELD:
  148. if (cur_field_name)
  149. free(cur_field_name);
  150. cur_field_name = strdup(args->field.name);
  151. break;
  152. case PRINT_FLAGS:
  153. define_event_symbols(event, ev_name, args->flags.field);
  154. define_flag_field(ev_name, cur_field_name, args->flags.delim);
  155. define_flag_values(args->flags.flags, ev_name, cur_field_name);
  156. break;
  157. case PRINT_SYMBOL:
  158. define_event_symbols(event, ev_name, args->symbol.field);
  159. define_symbolic_field(ev_name, cur_field_name);
  160. define_symbolic_values(args->symbol.symbols, ev_name,
  161. cur_field_name);
  162. break;
  163. case PRINT_STRING:
  164. break;
  165. case PRINT_TYPE:
  166. define_event_symbols(event, ev_name, args->typecast.item);
  167. break;
  168. case PRINT_OP:
  169. if (strcmp(args->op.op, ":") == 0)
  170. zero_flag_atom = 1;
  171. define_event_symbols(event, ev_name, args->op.left);
  172. define_event_symbols(event, ev_name, args->op.right);
  173. break;
  174. default:
  175. /* we should warn... */
  176. return;
  177. }
  178. if (args->next)
  179. define_event_symbols(event, ev_name, args->next);
  180. }
  181. static inline struct event *find_cache_event(int type)
  182. {
  183. static char ev_name[256];
  184. struct event *event;
  185. if (events[type])
  186. return events[type];
  187. events[type] = event = trace_find_event(type);
  188. if (!event)
  189. return NULL;
  190. sprintf(ev_name, "%s::%s", event->system, event->name);
  191. define_event_symbols(event, ev_name, event->print_fmt.args);
  192. return event;
  193. }
  194. static void perl_process_event(int cpu, void *data,
  195. int size __attribute((unused)),
  196. unsigned long long nsecs, char *comm)
  197. {
  198. struct format_field *field;
  199. static char handler[256];
  200. unsigned long long val;
  201. unsigned long s, ns;
  202. struct event *event;
  203. int type;
  204. int pid;
  205. dSP;
  206. type = trace_parse_common_type(data);
  207. event = find_cache_event(type);
  208. if (!event)
  209. die("ug! no event found for type %d", type);
  210. pid = trace_parse_common_pid(data);
  211. sprintf(handler, "%s::%s", event->system, event->name);
  212. s = nsecs / NSECS_PER_SEC;
  213. ns = nsecs - s * NSECS_PER_SEC;
  214. scripting_context->event_data = data;
  215. ENTER;
  216. SAVETMPS;
  217. PUSHMARK(SP);
  218. XPUSHs(sv_2mortal(newSVpv(handler, 0)));
  219. XPUSHs(sv_2mortal(newSViv(PTR2IV(scripting_context))));
  220. XPUSHs(sv_2mortal(newSVuv(cpu)));
  221. XPUSHs(sv_2mortal(newSVuv(s)));
  222. XPUSHs(sv_2mortal(newSVuv(ns)));
  223. XPUSHs(sv_2mortal(newSViv(pid)));
  224. XPUSHs(sv_2mortal(newSVpv(comm, 0)));
  225. /* common fields other than pid can be accessed via xsub fns */
  226. for (field = event->format.fields; field; field = field->next) {
  227. if (field->flags & FIELD_IS_STRING) {
  228. int offset;
  229. if (field->flags & FIELD_IS_DYNAMIC) {
  230. offset = *(int *)(data + field->offset);
  231. offset &= 0xffff;
  232. } else
  233. offset = field->offset;
  234. XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0)));
  235. } else { /* FIELD_IS_NUMERIC */
  236. val = read_size(data + field->offset, field->size);
  237. if (field->flags & FIELD_IS_SIGNED) {
  238. XPUSHs(sv_2mortal(newSViv(val)));
  239. } else {
  240. XPUSHs(sv_2mortal(newSVuv(val)));
  241. }
  242. }
  243. }
  244. PUTBACK;
  245. if (get_cv(handler, 0))
  246. call_pv(handler, G_SCALAR);
  247. else if (get_cv("main::trace_unhandled", 0)) {
  248. XPUSHs(sv_2mortal(newSVpv(handler, 0)));
  249. XPUSHs(sv_2mortal(newSViv(PTR2IV(scripting_context))));
  250. XPUSHs(sv_2mortal(newSVuv(cpu)));
  251. XPUSHs(sv_2mortal(newSVuv(nsecs)));
  252. XPUSHs(sv_2mortal(newSViv(pid)));
  253. XPUSHs(sv_2mortal(newSVpv(comm, 0)));
  254. call_pv("main::trace_unhandled", G_SCALAR);
  255. }
  256. SPAGAIN;
  257. PUTBACK;
  258. FREETMPS;
  259. LEAVE;
  260. }
  261. static void run_start_sub(void)
  262. {
  263. dSP; /* access to Perl stack */
  264. PUSHMARK(SP);
  265. if (get_cv("main::trace_begin", 0))
  266. call_pv("main::trace_begin", G_DISCARD | G_NOARGS);
  267. }
  268. /*
  269. * Start trace script
  270. */
  271. static int perl_start_script(const char *script)
  272. {
  273. const char *command_line[2] = { "", NULL };
  274. command_line[1] = script;
  275. my_perl = perl_alloc();
  276. perl_construct(my_perl);
  277. if (perl_parse(my_perl, NULL, 2, (char **)command_line, (char **)NULL))
  278. return -1;
  279. perl_run(my_perl);
  280. if (SvTRUE(ERRSV))
  281. return -1;
  282. run_start_sub();
  283. fprintf(stderr, "perf trace started with Perl script %s\n\n", script);
  284. return 0;
  285. }
  286. /*
  287. * Stop trace script
  288. */
  289. static int perl_stop_script(void)
  290. {
  291. dSP; /* access to Perl stack */
  292. PUSHMARK(SP);
  293. if (get_cv("main::trace_end", 0))
  294. call_pv("main::trace_end", G_DISCARD | G_NOARGS);
  295. perl_destruct(my_perl);
  296. perl_free(my_perl);
  297. fprintf(stderr, "\nperf trace Perl script stopped\n");
  298. return 0;
  299. }
  300. static int perl_generate_script(const char *outfile)
  301. {
  302. struct event *event = NULL;
  303. struct format_field *f;
  304. char fname[PATH_MAX];
  305. int not_first, count;
  306. FILE *ofp;
  307. sprintf(fname, "%s.pl", outfile);
  308. ofp = fopen(fname, "w");
  309. if (ofp == NULL) {
  310. fprintf(stderr, "couldn't open %s\n", fname);
  311. return -1;
  312. }
  313. fprintf(ofp, "# perf trace event handlers, "
  314. "generated by perf trace -g perl\n");
  315. fprintf(ofp, "# Licensed under the terms of the GNU GPL"
  316. " License version 2\n\n");
  317. fprintf(ofp, "# The common_* event handler fields are the most useful "
  318. "fields common to\n");
  319. fprintf(ofp, "# all events. They don't necessarily correspond to "
  320. "the 'common_*' fields\n");
  321. fprintf(ofp, "# in the format files. Those fields not available as "
  322. "handler params can\n");
  323. fprintf(ofp, "# be retrieved using Perl functions of the form "
  324. "common_*($context).\n");
  325. fprintf(ofp, "# See Context.pm for the list of available "
  326. "functions.\n\n");
  327. fprintf(ofp, "use lib \"$ENV{'PERF_EXEC_PATH'}/scripts/perl/"
  328. "Perf-Trace-Util/lib\";\n");
  329. fprintf(ofp, "use lib \"./Perf-Trace-Util/lib\";\n");
  330. fprintf(ofp, "use Perf::Trace::Core;\n");
  331. fprintf(ofp, "use Perf::Trace::Context;\n");
  332. fprintf(ofp, "use Perf::Trace::Util;\n\n");
  333. fprintf(ofp, "sub trace_begin\n{\n\t# optional\n}\n\n");
  334. fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n\n");
  335. while ((event = trace_find_next_event(event))) {
  336. fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name);
  337. fprintf(ofp, "\tmy (");
  338. fprintf(ofp, "$event_name, ");
  339. fprintf(ofp, "$context, ");
  340. fprintf(ofp, "$common_cpu, ");
  341. fprintf(ofp, "$common_secs, ");
  342. fprintf(ofp, "$common_nsecs,\n");
  343. fprintf(ofp, "\t $common_pid, ");
  344. fprintf(ofp, "$common_comm,\n\t ");
  345. not_first = 0;
  346. count = 0;
  347. for (f = event->format.fields; f; f = f->next) {
  348. if (not_first++)
  349. fprintf(ofp, ", ");
  350. if (++count % 5 == 0)
  351. fprintf(ofp, "\n\t ");
  352. fprintf(ofp, "$%s", f->name);
  353. }
  354. fprintf(ofp, ") = @_;\n\n");
  355. fprintf(ofp, "\tprint_header($event_name, $common_cpu, "
  356. "$common_secs, $common_nsecs,\n\t "
  357. "$common_pid, $common_comm);\n\n");
  358. fprintf(ofp, "\tprintf(\"");
  359. not_first = 0;
  360. count = 0;
  361. for (f = event->format.fields; f; f = f->next) {
  362. if (not_first++)
  363. fprintf(ofp, ", ");
  364. if (count && count % 4 == 0) {
  365. fprintf(ofp, "\".\n\t \"");
  366. }
  367. count++;
  368. fprintf(ofp, "%s=", f->name);
  369. if (f->flags & FIELD_IS_STRING ||
  370. f->flags & FIELD_IS_FLAG ||
  371. f->flags & FIELD_IS_SYMBOLIC)
  372. fprintf(ofp, "%%s");
  373. else if (f->flags & FIELD_IS_SIGNED)
  374. fprintf(ofp, "%%d");
  375. else
  376. fprintf(ofp, "%%u");
  377. }
  378. fprintf(ofp, "\\n\",\n\t ");
  379. not_first = 0;
  380. count = 0;
  381. for (f = event->format.fields; f; f = f->next) {
  382. if (not_first++)
  383. fprintf(ofp, ", ");
  384. if (++count % 5 == 0)
  385. fprintf(ofp, "\n\t ");
  386. if (f->flags & FIELD_IS_FLAG) {
  387. if ((count - 1) % 5 != 0) {
  388. fprintf(ofp, "\n\t ");
  389. count = 4;
  390. }
  391. fprintf(ofp, "flag_str(\"");
  392. fprintf(ofp, "%s::%s\", ", event->system,
  393. event->name);
  394. fprintf(ofp, "\"%s\", $%s)", f->name,
  395. f->name);
  396. } else if (f->flags & FIELD_IS_SYMBOLIC) {
  397. if ((count - 1) % 5 != 0) {
  398. fprintf(ofp, "\n\t ");
  399. count = 4;
  400. }
  401. fprintf(ofp, "symbol_str(\"");
  402. fprintf(ofp, "%s::%s\", ", event->system,
  403. event->name);
  404. fprintf(ofp, "\"%s\", $%s)", f->name,
  405. f->name);
  406. } else
  407. fprintf(ofp, "$%s", f->name);
  408. }
  409. fprintf(ofp, ");\n");
  410. fprintf(ofp, "}\n\n");
  411. }
  412. fprintf(ofp, "sub trace_unhandled\n{\n\tmy ($event_name, $context, "
  413. "$common_cpu, $common_secs, $common_nsecs,\n\t "
  414. "$common_pid, $common_comm) = @_;\n\n");
  415. fprintf(ofp, "\tprint_header($event_name, $common_cpu, "
  416. "$common_secs, $common_nsecs,\n\t $common_pid, "
  417. "$common_comm);\n}\n\n");
  418. fprintf(ofp, "sub print_header\n{\n"
  419. "\tmy ($event_name, $cpu, $secs, $nsecs, $pid, $comm) = @_;\n\n"
  420. "\tprintf(\"%%-20s %%5u %%05u.%%09u %%8u %%-20s \",\n\t "
  421. "$event_name, $cpu, $secs, $nsecs, $pid, $comm);\n}");
  422. fclose(ofp);
  423. fprintf(stderr, "generated Perl script: %s\n", fname);
  424. return 0;
  425. }
  426. struct scripting_ops perl_scripting_ops = {
  427. .name = "Perl",
  428. .start_script = perl_start_script,
  429. .stop_script = perl_stop_script,
  430. .process_event = perl_process_event,
  431. .generate_script = perl_generate_script,
  432. };
  433. #ifdef NO_LIBPERL
  434. void setup_perl_scripting(void)
  435. {
  436. fprintf(stderr, "Perl scripting not supported."
  437. " Install libperl-dev[el] and rebuild perf to get it.\n");
  438. }
  439. #else
  440. void setup_perl_scripting(void)
  441. {
  442. int err;
  443. err = script_spec_register("Perl", &perl_scripting_ops);
  444. if (err)
  445. die("error registering Perl script extension");
  446. err = script_spec_register("pl", &perl_scripting_ops);
  447. if (err)
  448. die("error registering pl script extension");
  449. scripting_context = malloc(sizeof(struct scripting_context));
  450. }
  451. #endif