1 /* 2 * trace-event-python. Feed trace events to an embedded Python interpreter. 3 * 4 * Copyright (C) 2010 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 22 #include <Python.h> 23 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <errno.h> 28 29 #include "../../perf.h" 30 #include "../debug.h" 31 #include "../evsel.h" 32 #include "../util.h" 33 #include "../event.h" 34 #include "../thread.h" 35 #include "../trace-event.h" 36 #include "../machine.h" 37 38 PyMODINIT_FUNC initperf_trace_context(void); 39 40 #define FTRACE_MAX_EVENT \ 41 ((1 << (sizeof(unsigned short) * 8)) - 1) 42 43 struct event_format *events[FTRACE_MAX_EVENT]; 44 45 #define MAX_FIELDS 64 46 #define N_COMMON_FIELDS 7 47 48 extern struct scripting_context *scripting_context; 49 50 static char *cur_field_name; 51 static int zero_flag_atom; 52 53 static PyObject *main_module, *main_dict; 54 55 static void handler_call_die(const char *handler_name) NORETURN; 56 static void handler_call_die(const char *handler_name) 57 { 58 PyErr_Print(); 59 Py_FatalError("problem in Python trace event handler"); 60 // Py_FatalError does not return 61 // but we have to make the compiler happy 62 abort(); 63 } 64 65 /* 66 * Insert val into into the dictionary and decrement the reference counter. 67 * This is necessary for dictionaries since PyDict_SetItemString() does not 68 * steal a reference, as opposed to PyTuple_SetItem(). 69 */ 70 static void pydict_set_item_string_decref(PyObject *dict, const char *key, PyObject *val) 71 { 72 PyDict_SetItemString(dict, key, val); 73 Py_DECREF(val); 74 } 75 76 static void define_value(enum print_arg_type field_type, 77 const char *ev_name, 78 const char *field_name, 79 const char *field_value, 80 const char *field_str) 81 { 82 const char *handler_name = "define_flag_value"; 83 PyObject *handler, *t, *retval; 84 unsigned long long value; 85 unsigned n = 0; 86 87 if (field_type == PRINT_SYMBOL) 88 handler_name = "define_symbolic_value"; 89 90 t = PyTuple_New(4); 91 if (!t) 92 Py_FatalError("couldn't create Python tuple"); 93 94 value = eval_flag(field_value); 95 96 PyTuple_SetItem(t, n++, PyString_FromString(ev_name)); 97 PyTuple_SetItem(t, n++, PyString_FromString(field_name)); 98 PyTuple_SetItem(t, n++, PyInt_FromLong(value)); 99 PyTuple_SetItem(t, n++, PyString_FromString(field_str)); 100 101 handler = PyDict_GetItemString(main_dict, handler_name); 102 if (handler && PyCallable_Check(handler)) { 103 retval = PyObject_CallObject(handler, t); 104 if (retval == NULL) 105 handler_call_die(handler_name); 106 Py_DECREF(retval); 107 } 108 109 Py_DECREF(t); 110 } 111 112 static void define_values(enum print_arg_type field_type, 113 struct print_flag_sym *field, 114 const char *ev_name, 115 const char *field_name) 116 { 117 define_value(field_type, ev_name, field_name, field->value, 118 field->str); 119 120 if (field->next) 121 define_values(field_type, field->next, ev_name, field_name); 122 } 123 124 static void define_field(enum print_arg_type field_type, 125 const char *ev_name, 126 const char *field_name, 127 const char *delim) 128 { 129 const char *handler_name = "define_flag_field"; 130 PyObject *handler, *t, *retval; 131 unsigned n = 0; 132 133 if (field_type == PRINT_SYMBOL) 134 handler_name = "define_symbolic_field"; 135 136 if (field_type == PRINT_FLAGS) 137 t = PyTuple_New(3); 138 else 139 t = PyTuple_New(2); 140 if (!t) 141 Py_FatalError("couldn't create Python tuple"); 142 143 PyTuple_SetItem(t, n++, PyString_FromString(ev_name)); 144 PyTuple_SetItem(t, n++, PyString_FromString(field_name)); 145 if (field_type == PRINT_FLAGS) 146 PyTuple_SetItem(t, n++, PyString_FromString(delim)); 147 148 handler = PyDict_GetItemString(main_dict, handler_name); 149 if (handler && PyCallable_Check(handler)) { 150 retval = PyObject_CallObject(handler, t); 151 if (retval == NULL) 152 handler_call_die(handler_name); 153 Py_DECREF(retval); 154 } 155 156 Py_DECREF(t); 157 } 158 159 static void define_event_symbols(struct event_format *event, 160 const char *ev_name, 161 struct print_arg *args) 162 { 163 switch (args->type) { 164 case PRINT_NULL: 165 break; 166 case PRINT_ATOM: 167 define_value(PRINT_FLAGS, ev_name, cur_field_name, "0", 168 args->atom.atom); 169 zero_flag_atom = 0; 170 break; 171 case PRINT_FIELD: 172 free(cur_field_name); 173 cur_field_name = strdup(args->field.name); 174 break; 175 case PRINT_FLAGS: 176 define_event_symbols(event, ev_name, args->flags.field); 177 define_field(PRINT_FLAGS, ev_name, cur_field_name, 178 args->flags.delim); 179 define_values(PRINT_FLAGS, args->flags.flags, ev_name, 180 cur_field_name); 181 break; 182 case PRINT_SYMBOL: 183 define_event_symbols(event, ev_name, args->symbol.field); 184 define_field(PRINT_SYMBOL, ev_name, cur_field_name, NULL); 185 define_values(PRINT_SYMBOL, args->symbol.symbols, ev_name, 186 cur_field_name); 187 break; 188 case PRINT_HEX: 189 define_event_symbols(event, ev_name, args->hex.field); 190 define_event_symbols(event, ev_name, args->hex.size); 191 break; 192 case PRINT_STRING: 193 break; 194 case PRINT_TYPE: 195 define_event_symbols(event, ev_name, args->typecast.item); 196 break; 197 case PRINT_OP: 198 if (strcmp(args->op.op, ":") == 0) 199 zero_flag_atom = 1; 200 define_event_symbols(event, ev_name, args->op.left); 201 define_event_symbols(event, ev_name, args->op.right); 202 break; 203 default: 204 /* gcc warns for these? */ 205 case PRINT_BSTRING: 206 case PRINT_DYNAMIC_ARRAY: 207 case PRINT_FUNC: 208 case PRINT_BITMASK: 209 /* we should warn... */ 210 return; 211 } 212 213 if (args->next) 214 define_event_symbols(event, ev_name, args->next); 215 } 216 217 static inline struct event_format *find_cache_event(struct perf_evsel *evsel) 218 { 219 static char ev_name[256]; 220 struct event_format *event; 221 int type = evsel->attr.config; 222 223 /* 224 * XXX: Do we really need to cache this since now we have evsel->tp_format 225 * cached already? Need to re-read this "cache" routine that as well calls 226 * define_event_symbols() :-\ 227 */ 228 if (events[type]) 229 return events[type]; 230 231 events[type] = event = evsel->tp_format; 232 if (!event) 233 return NULL; 234 235 sprintf(ev_name, "%s__%s", event->system, event->name); 236 237 define_event_symbols(event, ev_name, event->print_fmt.args); 238 239 return event; 240 } 241 242 static PyObject *get_field_numeric_entry(struct event_format *event, 243 struct format_field *field, void *data) 244 { 245 bool is_array = field->flags & FIELD_IS_ARRAY; 246 PyObject *obj, *list = NULL; 247 unsigned long long val; 248 unsigned int item_size, n_items, i; 249 250 if (is_array) { 251 list = PyList_New(field->arraylen); 252 item_size = field->size / field->arraylen; 253 n_items = field->arraylen; 254 } else { 255 item_size = field->size; 256 n_items = 1; 257 } 258 259 for (i = 0; i < n_items; i++) { 260 261 val = read_size(event, data + field->offset + i * item_size, 262 item_size); 263 if (field->flags & FIELD_IS_SIGNED) { 264 if ((long long)val >= LONG_MIN && 265 (long long)val <= LONG_MAX) 266 obj = PyInt_FromLong(val); 267 else 268 obj = PyLong_FromLongLong(val); 269 } else { 270 if (val <= LONG_MAX) 271 obj = PyInt_FromLong(val); 272 else 273 obj = PyLong_FromUnsignedLongLong(val); 274 } 275 if (is_array) 276 PyList_SET_ITEM(list, i, obj); 277 } 278 if (is_array) 279 obj = list; 280 return obj; 281 } 282 283 284 static PyObject *python_process_callchain(struct perf_sample *sample, 285 struct perf_evsel *evsel, 286 struct addr_location *al) 287 { 288 PyObject *pylist; 289 290 pylist = PyList_New(0); 291 if (!pylist) 292 Py_FatalError("couldn't create Python list"); 293 294 if (!symbol_conf.use_callchain || !sample->callchain) 295 goto exit; 296 297 if (machine__resolve_callchain(al->machine, evsel, al->thread, 298 sample, NULL, NULL, 299 PERF_MAX_STACK_DEPTH) != 0) { 300 pr_err("Failed to resolve callchain. Skipping\n"); 301 goto exit; 302 } 303 callchain_cursor_commit(&callchain_cursor); 304 305 306 while (1) { 307 PyObject *pyelem; 308 struct callchain_cursor_node *node; 309 node = callchain_cursor_current(&callchain_cursor); 310 if (!node) 311 break; 312 313 pyelem = PyDict_New(); 314 if (!pyelem) 315 Py_FatalError("couldn't create Python dictionary"); 316 317 318 pydict_set_item_string_decref(pyelem, "ip", 319 PyLong_FromUnsignedLongLong(node->ip)); 320 321 if (node->sym) { 322 PyObject *pysym = PyDict_New(); 323 if (!pysym) 324 Py_FatalError("couldn't create Python dictionary"); 325 pydict_set_item_string_decref(pysym, "start", 326 PyLong_FromUnsignedLongLong(node->sym->start)); 327 pydict_set_item_string_decref(pysym, "end", 328 PyLong_FromUnsignedLongLong(node->sym->end)); 329 pydict_set_item_string_decref(pysym, "binding", 330 PyInt_FromLong(node->sym->binding)); 331 pydict_set_item_string_decref(pysym, "name", 332 PyString_FromStringAndSize(node->sym->name, 333 node->sym->namelen)); 334 pydict_set_item_string_decref(pyelem, "sym", pysym); 335 } 336 337 if (node->map) { 338 struct map *map = node->map; 339 const char *dsoname = "[unknown]"; 340 if (map && map->dso && (map->dso->name || map->dso->long_name)) { 341 if (symbol_conf.show_kernel_path && map->dso->long_name) 342 dsoname = map->dso->long_name; 343 else if (map->dso->name) 344 dsoname = map->dso->name; 345 } 346 pydict_set_item_string_decref(pyelem, "dso", 347 PyString_FromString(dsoname)); 348 } 349 350 callchain_cursor_advance(&callchain_cursor); 351 PyList_Append(pylist, pyelem); 352 Py_DECREF(pyelem); 353 } 354 355 exit: 356 return pylist; 357 } 358 359 360 static void python_process_tracepoint(struct perf_sample *sample, 361 struct perf_evsel *evsel, 362 struct thread *thread, 363 struct addr_location *al) 364 { 365 PyObject *handler, *retval, *context, *t, *obj, *callchain; 366 PyObject *dict = NULL; 367 static char handler_name[256]; 368 struct format_field *field; 369 unsigned long s, ns; 370 struct event_format *event; 371 unsigned n = 0; 372 int pid; 373 int cpu = sample->cpu; 374 void *data = sample->raw_data; 375 unsigned long long nsecs = sample->time; 376 const char *comm = thread__comm_str(thread); 377 378 t = PyTuple_New(MAX_FIELDS); 379 if (!t) 380 Py_FatalError("couldn't create Python tuple"); 381 382 event = find_cache_event(evsel); 383 if (!event) 384 die("ug! no event found for type %d", (int)evsel->attr.config); 385 386 pid = raw_field_value(event, "common_pid", data); 387 388 sprintf(handler_name, "%s__%s", event->system, event->name); 389 390 handler = PyDict_GetItemString(main_dict, handler_name); 391 if (handler && !PyCallable_Check(handler)) 392 handler = NULL; 393 if (!handler) { 394 dict = PyDict_New(); 395 if (!dict) 396 Py_FatalError("couldn't create Python dict"); 397 } 398 s = nsecs / NSECS_PER_SEC; 399 ns = nsecs - s * NSECS_PER_SEC; 400 401 scripting_context->event_data = data; 402 scripting_context->pevent = evsel->tp_format->pevent; 403 404 context = PyCObject_FromVoidPtr(scripting_context, NULL); 405 406 PyTuple_SetItem(t, n++, PyString_FromString(handler_name)); 407 PyTuple_SetItem(t, n++, context); 408 409 /* ip unwinding */ 410 callchain = python_process_callchain(sample, evsel, al); 411 412 if (handler) { 413 PyTuple_SetItem(t, n++, PyInt_FromLong(cpu)); 414 PyTuple_SetItem(t, n++, PyInt_FromLong(s)); 415 PyTuple_SetItem(t, n++, PyInt_FromLong(ns)); 416 PyTuple_SetItem(t, n++, PyInt_FromLong(pid)); 417 PyTuple_SetItem(t, n++, PyString_FromString(comm)); 418 PyTuple_SetItem(t, n++, callchain); 419 } else { 420 pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu)); 421 pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s)); 422 pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns)); 423 pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid)); 424 pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm)); 425 pydict_set_item_string_decref(dict, "common_callchain", callchain); 426 } 427 for (field = event->format.fields; field; field = field->next) { 428 if (field->flags & FIELD_IS_STRING) { 429 int offset; 430 if (field->flags & FIELD_IS_DYNAMIC) { 431 offset = *(int *)(data + field->offset); 432 offset &= 0xffff; 433 } else 434 offset = field->offset; 435 obj = PyString_FromString((char *)data + offset); 436 } else { /* FIELD_IS_NUMERIC */ 437 obj = get_field_numeric_entry(event, field, data); 438 } 439 if (handler) 440 PyTuple_SetItem(t, n++, obj); 441 else 442 pydict_set_item_string_decref(dict, field->name, obj); 443 444 } 445 446 if (!handler) 447 PyTuple_SetItem(t, n++, dict); 448 449 if (_PyTuple_Resize(&t, n) == -1) 450 Py_FatalError("error resizing Python tuple"); 451 452 if (handler) { 453 retval = PyObject_CallObject(handler, t); 454 if (retval == NULL) 455 handler_call_die(handler_name); 456 Py_DECREF(retval); 457 } else { 458 handler = PyDict_GetItemString(main_dict, "trace_unhandled"); 459 if (handler && PyCallable_Check(handler)) { 460 461 retval = PyObject_CallObject(handler, t); 462 if (retval == NULL) 463 handler_call_die("trace_unhandled"); 464 Py_DECREF(retval); 465 } 466 Py_DECREF(dict); 467 } 468 469 Py_DECREF(t); 470 } 471 472 static void python_process_general_event(struct perf_sample *sample, 473 struct perf_evsel *evsel, 474 struct thread *thread, 475 struct addr_location *al) 476 { 477 PyObject *handler, *retval, *t, *dict, *callchain, *dict_sample; 478 static char handler_name[64]; 479 unsigned n = 0; 480 481 /* 482 * Use the MAX_FIELDS to make the function expandable, though 483 * currently there is only one item for the tuple. 484 */ 485 t = PyTuple_New(MAX_FIELDS); 486 if (!t) 487 Py_FatalError("couldn't create Python tuple"); 488 489 dict = PyDict_New(); 490 if (!dict) 491 Py_FatalError("couldn't create Python dictionary"); 492 493 dict_sample = PyDict_New(); 494 if (!dict_sample) 495 Py_FatalError("couldn't create Python dictionary"); 496 497 snprintf(handler_name, sizeof(handler_name), "%s", "process_event"); 498 499 handler = PyDict_GetItemString(main_dict, handler_name); 500 if (!handler || !PyCallable_Check(handler)) 501 goto exit; 502 503 pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); 504 pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize( 505 (const char *)&evsel->attr, sizeof(evsel->attr))); 506 507 pydict_set_item_string_decref(dict_sample, "pid", 508 PyInt_FromLong(sample->pid)); 509 pydict_set_item_string_decref(dict_sample, "tid", 510 PyInt_FromLong(sample->tid)); 511 pydict_set_item_string_decref(dict_sample, "cpu", 512 PyInt_FromLong(sample->cpu)); 513 pydict_set_item_string_decref(dict_sample, "ip", 514 PyLong_FromUnsignedLongLong(sample->ip)); 515 pydict_set_item_string_decref(dict_sample, "time", 516 PyLong_FromUnsignedLongLong(sample->time)); 517 pydict_set_item_string_decref(dict_sample, "period", 518 PyLong_FromUnsignedLongLong(sample->period)); 519 pydict_set_item_string_decref(dict, "sample", dict_sample); 520 521 pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize( 522 (const char *)sample->raw_data, sample->raw_size)); 523 pydict_set_item_string_decref(dict, "comm", 524 PyString_FromString(thread__comm_str(thread))); 525 if (al->map) { 526 pydict_set_item_string_decref(dict, "dso", 527 PyString_FromString(al->map->dso->name)); 528 } 529 if (al->sym) { 530 pydict_set_item_string_decref(dict, "symbol", 531 PyString_FromString(al->sym->name)); 532 } 533 534 /* ip unwinding */ 535 callchain = python_process_callchain(sample, evsel, al); 536 pydict_set_item_string_decref(dict, "callchain", callchain); 537 538 PyTuple_SetItem(t, n++, dict); 539 if (_PyTuple_Resize(&t, n) == -1) 540 Py_FatalError("error resizing Python tuple"); 541 542 retval = PyObject_CallObject(handler, t); 543 if (retval == NULL) 544 handler_call_die(handler_name); 545 Py_DECREF(retval); 546 exit: 547 Py_DECREF(dict); 548 Py_DECREF(t); 549 } 550 551 static void python_process_event(union perf_event *event __maybe_unused, 552 struct perf_sample *sample, 553 struct perf_evsel *evsel, 554 struct thread *thread, 555 struct addr_location *al) 556 { 557 switch (evsel->attr.type) { 558 case PERF_TYPE_TRACEPOINT: 559 python_process_tracepoint(sample, evsel, thread, al); 560 break; 561 /* Reserve for future process_hw/sw/raw APIs */ 562 default: 563 python_process_general_event(sample, evsel, thread, al); 564 } 565 } 566 567 static int run_start_sub(void) 568 { 569 PyObject *handler, *retval; 570 int err = 0; 571 572 main_module = PyImport_AddModule("__main__"); 573 if (main_module == NULL) 574 return -1; 575 Py_INCREF(main_module); 576 577 main_dict = PyModule_GetDict(main_module); 578 if (main_dict == NULL) { 579 err = -1; 580 goto error; 581 } 582 Py_INCREF(main_dict); 583 584 handler = PyDict_GetItemString(main_dict, "trace_begin"); 585 if (handler == NULL || !PyCallable_Check(handler)) 586 goto out; 587 588 retval = PyObject_CallObject(handler, NULL); 589 if (retval == NULL) 590 handler_call_die("trace_begin"); 591 592 Py_DECREF(retval); 593 return err; 594 error: 595 Py_XDECREF(main_dict); 596 Py_XDECREF(main_module); 597 out: 598 return err; 599 } 600 601 /* 602 * Start trace script 603 */ 604 static int python_start_script(const char *script, int argc, const char **argv) 605 { 606 const char **command_line; 607 char buf[PATH_MAX]; 608 int i, err = 0; 609 FILE *fp; 610 611 command_line = malloc((argc + 1) * sizeof(const char *)); 612 command_line[0] = script; 613 for (i = 1; i < argc + 1; i++) 614 command_line[i] = argv[i - 1]; 615 616 Py_Initialize(); 617 618 initperf_trace_context(); 619 620 PySys_SetArgv(argc + 1, (char **)command_line); 621 622 fp = fopen(script, "r"); 623 if (!fp) { 624 sprintf(buf, "Can't open python script \"%s\"", script); 625 perror(buf); 626 err = -1; 627 goto error; 628 } 629 630 err = PyRun_SimpleFile(fp, script); 631 if (err) { 632 fprintf(stderr, "Error running python script %s\n", script); 633 goto error; 634 } 635 636 err = run_start_sub(); 637 if (err) { 638 fprintf(stderr, "Error starting python script %s\n", script); 639 goto error; 640 } 641 642 free(command_line); 643 644 return err; 645 error: 646 Py_Finalize(); 647 free(command_line); 648 649 return err; 650 } 651 652 /* 653 * Stop trace script 654 */ 655 static int python_stop_script(void) 656 { 657 PyObject *handler, *retval; 658 int err = 0; 659 660 handler = PyDict_GetItemString(main_dict, "trace_end"); 661 if (handler == NULL || !PyCallable_Check(handler)) 662 goto out; 663 664 retval = PyObject_CallObject(handler, NULL); 665 if (retval == NULL) 666 handler_call_die("trace_end"); 667 Py_DECREF(retval); 668 out: 669 Py_XDECREF(main_dict); 670 Py_XDECREF(main_module); 671 Py_Finalize(); 672 673 return err; 674 } 675 676 static int python_generate_script(struct pevent *pevent, const char *outfile) 677 { 678 struct event_format *event = NULL; 679 struct format_field *f; 680 char fname[PATH_MAX]; 681 int not_first, count; 682 FILE *ofp; 683 684 sprintf(fname, "%s.py", outfile); 685 ofp = fopen(fname, "w"); 686 if (ofp == NULL) { 687 fprintf(stderr, "couldn't open %s\n", fname); 688 return -1; 689 } 690 fprintf(ofp, "# perf script event handlers, " 691 "generated by perf script -g python\n"); 692 693 fprintf(ofp, "# Licensed under the terms of the GNU GPL" 694 " License version 2\n\n"); 695 696 fprintf(ofp, "# The common_* event handler fields are the most useful " 697 "fields common to\n"); 698 699 fprintf(ofp, "# all events. They don't necessarily correspond to " 700 "the 'common_*' fields\n"); 701 702 fprintf(ofp, "# in the format files. Those fields not available as " 703 "handler params can\n"); 704 705 fprintf(ofp, "# be retrieved using Python functions of the form " 706 "common_*(context).\n"); 707 708 fprintf(ofp, "# See the perf-trace-python Documentation for the list " 709 "of available functions.\n\n"); 710 711 fprintf(ofp, "import os\n"); 712 fprintf(ofp, "import sys\n\n"); 713 714 fprintf(ofp, "sys.path.append(os.environ['PERF_EXEC_PATH'] + \\\n"); 715 fprintf(ofp, "\t'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')\n"); 716 fprintf(ofp, "\nfrom perf_trace_context import *\n"); 717 fprintf(ofp, "from Core import *\n\n\n"); 718 719 fprintf(ofp, "def trace_begin():\n"); 720 fprintf(ofp, "\tprint \"in trace_begin\"\n\n"); 721 722 fprintf(ofp, "def trace_end():\n"); 723 fprintf(ofp, "\tprint \"in trace_end\"\n\n"); 724 725 while ((event = trace_find_next_event(pevent, event))) { 726 fprintf(ofp, "def %s__%s(", event->system, event->name); 727 fprintf(ofp, "event_name, "); 728 fprintf(ofp, "context, "); 729 fprintf(ofp, "common_cpu,\n"); 730 fprintf(ofp, "\tcommon_secs, "); 731 fprintf(ofp, "common_nsecs, "); 732 fprintf(ofp, "common_pid, "); 733 fprintf(ofp, "common_comm,\n\t"); 734 fprintf(ofp, "common_callchain, "); 735 736 not_first = 0; 737 count = 0; 738 739 for (f = event->format.fields; f; f = f->next) { 740 if (not_first++) 741 fprintf(ofp, ", "); 742 if (++count % 5 == 0) 743 fprintf(ofp, "\n\t"); 744 745 fprintf(ofp, "%s", f->name); 746 } 747 fprintf(ofp, "):\n"); 748 749 fprintf(ofp, "\t\tprint_header(event_name, common_cpu, " 750 "common_secs, common_nsecs,\n\t\t\t" 751 "common_pid, common_comm)\n\n"); 752 753 fprintf(ofp, "\t\tprint \""); 754 755 not_first = 0; 756 count = 0; 757 758 for (f = event->format.fields; f; f = f->next) { 759 if (not_first++) 760 fprintf(ofp, ", "); 761 if (count && count % 3 == 0) { 762 fprintf(ofp, "\" \\\n\t\t\""); 763 } 764 count++; 765 766 fprintf(ofp, "%s=", f->name); 767 if (f->flags & FIELD_IS_STRING || 768 f->flags & FIELD_IS_FLAG || 769 f->flags & FIELD_IS_ARRAY || 770 f->flags & FIELD_IS_SYMBOLIC) 771 fprintf(ofp, "%%s"); 772 else if (f->flags & FIELD_IS_SIGNED) 773 fprintf(ofp, "%%d"); 774 else 775 fprintf(ofp, "%%u"); 776 } 777 778 fprintf(ofp, "\" %% \\\n\t\t("); 779 780 not_first = 0; 781 count = 0; 782 783 for (f = event->format.fields; f; f = f->next) { 784 if (not_first++) 785 fprintf(ofp, ", "); 786 787 if (++count % 5 == 0) 788 fprintf(ofp, "\n\t\t"); 789 790 if (f->flags & FIELD_IS_FLAG) { 791 if ((count - 1) % 5 != 0) { 792 fprintf(ofp, "\n\t\t"); 793 count = 4; 794 } 795 fprintf(ofp, "flag_str(\""); 796 fprintf(ofp, "%s__%s\", ", event->system, 797 event->name); 798 fprintf(ofp, "\"%s\", %s)", f->name, 799 f->name); 800 } else if (f->flags & FIELD_IS_SYMBOLIC) { 801 if ((count - 1) % 5 != 0) { 802 fprintf(ofp, "\n\t\t"); 803 count = 4; 804 } 805 fprintf(ofp, "symbol_str(\""); 806 fprintf(ofp, "%s__%s\", ", event->system, 807 event->name); 808 fprintf(ofp, "\"%s\", %s)", f->name, 809 f->name); 810 } else 811 fprintf(ofp, "%s", f->name); 812 } 813 814 fprintf(ofp, ")\n\n"); 815 816 fprintf(ofp, "\t\tfor node in common_callchain:"); 817 fprintf(ofp, "\n\t\t\tif 'sym' in node:"); 818 fprintf(ofp, "\n\t\t\t\tprint \"\\t[%%x] %%s\" %% (node['ip'], node['sym']['name'])"); 819 fprintf(ofp, "\n\t\t\telse:"); 820 fprintf(ofp, "\n\t\t\t\tprint \"\t[%%x]\" %% (node['ip'])\n\n"); 821 fprintf(ofp, "\t\tprint \"\\n\"\n\n"); 822 823 } 824 825 fprintf(ofp, "def trace_unhandled(event_name, context, " 826 "event_fields_dict):\n"); 827 828 fprintf(ofp, "\t\tprint ' '.join(['%%s=%%s'%%(k,str(v))" 829 "for k,v in sorted(event_fields_dict.items())])\n\n"); 830 831 fprintf(ofp, "def print_header(" 832 "event_name, cpu, secs, nsecs, pid, comm):\n" 833 "\tprint \"%%-20s %%5u %%05u.%%09u %%8u %%-20s \" %% \\\n\t" 834 "(event_name, cpu, secs, nsecs, pid, comm),\n"); 835 836 fclose(ofp); 837 838 fprintf(stderr, "generated Python script: %s\n", fname); 839 840 return 0; 841 } 842 843 struct scripting_ops python_scripting_ops = { 844 .name = "Python", 845 .start_script = python_start_script, 846 .stop_script = python_stop_script, 847 .process_event = python_process_event, 848 .generate_script = python_generate_script, 849 }; 850