Linux Audio

Check our new training course

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