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