Beispiel #1
0
static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf,
				       size_t size, unsigned int width)
{
	const char *comm = thread__comm_str(he->thread);
	return repsep_snprintf(bf, size, "%*s:%5d", width - 6,
			       comm ?: "", he->thread->tid);
}
Beispiel #2
0
static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf,
				       size_t size, unsigned int width)
{
	const char *comm = thread__comm_str(he->thread);

	width = max(7U, width) - 6;
	return repsep_snprintf(bf, size, "%5d:%-*.*s", he->thread->tid,
			       width, width, comm ?: "");
}
Beispiel #3
0
static void python_process_general_event(struct perf_sample *sample,
					 struct perf_evsel *evsel,
					 struct thread *thread,
					 struct addr_location *al)
{
	PyObject *handler, *retval, *t, *dict;
	static char handler_name[64];
	unsigned n = 0;

	/*
	 * Use the MAX_FIELDS to make the function expandable, though
	 * currently there is only one item for the tuple.
	 */
	t = PyTuple_New(MAX_FIELDS);
	if (!t)
		Py_FatalError("couldn't create Python tuple");

	dict = PyDict_New();
	if (!dict)
		Py_FatalError("couldn't create Python dictionary");

	snprintf(handler_name, sizeof(handler_name), "%s", "process_event");

	handler = PyDict_GetItemString(main_dict, handler_name);
	if (!handler || !PyCallable_Check(handler))
		goto exit;

	pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
	pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize(
			(const char *)&evsel->attr, sizeof(evsel->attr)));
	pydict_set_item_string_decref(dict, "sample", PyString_FromStringAndSize(
			(const char *)sample, sizeof(*sample)));
	pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize(
			(const char *)sample->raw_data, sample->raw_size));
	pydict_set_item_string_decref(dict, "comm",
			PyString_FromString(thread__comm_str(thread)));
	if (al->map) {
		pydict_set_item_string_decref(dict, "dso",
			PyString_FromString(al->map->dso->name));
	}
	if (al->sym) {
		pydict_set_item_string_decref(dict, "symbol",
			PyString_FromString(al->sym->name));
	}

	PyTuple_SetItem(t, n++, dict);
	if (_PyTuple_Resize(&t, n) == -1)
		Py_FatalError("error resizing Python tuple");

	retval = PyObject_CallObject(handler, t);
	if (retval == NULL)
		handler_call_die(handler_name);
exit:
	Py_DECREF(dict);
	Py_DECREF(t);
}
Beispiel #4
0
static size_t syscall_arg__scnprintf_pid(char *bf, size_t size, struct syscall_arg *arg)
{
	int pid = arg->val;
	struct trace *trace = arg->trace;
	size_t printed = scnprintf(bf, size, "%d", pid);
	struct thread *thread = machine__findnew_thread(trace->host, pid, pid);

	if (thread != NULL) {
		if (!thread->comm_set)
			thread__set_comm_from_proc(thread);

		if (thread->comm_set)
			printed += scnprintf(bf + printed, size - printed,
					     " (%s)", thread__comm_str(thread));
		thread__put(thread);
	}

	return printed;
}
Beispiel #5
0
static void python_process_tracepoint(struct perf_sample *sample,
				      struct perf_evsel *evsel,
				      struct thread *thread,
				      struct addr_location *al)
{
	PyObject *handler, *retval, *context, *t, *obj, *dict = NULL;
	static char handler_name[256];
	struct format_field *field;
	unsigned long long val;
	unsigned long s, ns;
	struct event_format *event;
	unsigned n = 0;
	int pid;
	int cpu = sample->cpu;
	void *data = sample->raw_data;
	unsigned long long nsecs = sample->time;
	const char *comm = thread__comm_str(thread);

	t = PyTuple_New(MAX_FIELDS);
	if (!t)
		Py_FatalError("couldn't create Python tuple");

	event = find_cache_event(evsel);
	if (!event)
		die("ug! no event found for type %d", (int)evsel->attr.config);

	pid = raw_field_value(event, "common_pid", data);

	sprintf(handler_name, "%s__%s", event->system, event->name);

	handler = PyDict_GetItemString(main_dict, handler_name);
	if (handler && !PyCallable_Check(handler))
		handler = NULL;
	if (!handler) {
		dict = PyDict_New();
		if (!dict)
			Py_FatalError("couldn't create Python dict");
	}
	s = nsecs / NSECS_PER_SEC;
	ns = nsecs - s * NSECS_PER_SEC;

	scripting_context->event_data = data;
	scripting_context->pevent = evsel->tp_format->pevent;

	context = PyCObject_FromVoidPtr(scripting_context, NULL);

	PyTuple_SetItem(t, n++, PyString_FromString(handler_name));
	PyTuple_SetItem(t, n++, context);

	if (handler) {
		PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
		PyTuple_SetItem(t, n++, PyInt_FromLong(s));
		PyTuple_SetItem(t, n++, PyInt_FromLong(ns));
		PyTuple_SetItem(t, n++, PyInt_FromLong(pid));
		PyTuple_SetItem(t, n++, PyString_FromString(comm));
	} else {
		pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu));
		pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s));
		pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns));
		pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid));
		pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm));
	}
	for (field = event->format.fields; field; field = field->next) {
		if (field->flags & FIELD_IS_STRING) {
			int offset;
			if (field->flags & FIELD_IS_DYNAMIC) {
				offset = *(int *)(data + field->offset);
				offset &= 0xffff;
			} else
				offset = field->offset;
			obj = PyString_FromString((char *)data + offset);
		} else { /* FIELD_IS_NUMERIC */
			val = read_size(event, data + field->offset,
					field->size);
			if (field->flags & FIELD_IS_SIGNED) {
				if ((long long)val >= LONG_MIN &&
				    (long long)val <= LONG_MAX)
					obj = PyInt_FromLong(val);
				else
					obj = PyLong_FromLongLong(val);
			} else {
				if (val <= LONG_MAX)
					obj = PyInt_FromLong(val);
				else
					obj = PyLong_FromUnsignedLongLong(val);
			}
		}
		if (handler)
			PyTuple_SetItem(t, n++, obj);
		else
			pydict_set_item_string_decref(dict, field->name, obj);

	}
	if (!handler)
		PyTuple_SetItem(t, n++, dict);

	if (_PyTuple_Resize(&t, n) == -1)
		Py_FatalError("error resizing Python tuple");

	if (handler) {
		retval = PyObject_CallObject(handler, t);
		if (retval == NULL)
			handler_call_die(handler_name);
	} else {
		handler = PyDict_GetItemString(main_dict, "trace_unhandled");
		if (handler && PyCallable_Check(handler)) {

			retval = PyObject_CallObject(handler, t);
			if (retval == NULL)
				handler_call_die("trace_unhandled");
		}
		Py_DECREF(dict);
	}

	Py_DECREF(t);
}
Beispiel #6
0
static void perl_process_tracepoint(struct perf_sample *sample,
				    struct perf_evsel *evsel,
				    struct thread *thread)
{
	struct event_format *event = evsel->tp_format;
	struct format_field *field;
	static char handler[256];
	unsigned long long val;
	unsigned long s, ns;
	int pid;
	int cpu = sample->cpu;
	void *data = sample->raw_data;
	unsigned long long nsecs = sample->time;
	const char *comm = thread__comm_str(thread);

	dSP;

	if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
		return;

	if (!event)
		die("ug! no event found for type %" PRIu64, (u64)evsel->attr.config);

	pid = raw_field_value(event, "common_pid", data);

	sprintf(handler, "%s::%s", event->system, event->name);

	if (!test_and_set_bit(event->id, events_defined))
		define_event_symbols(event, handler, event->print_fmt.args);

	s = nsecs / NSECS_PER_SEC;
	ns = nsecs - s * NSECS_PER_SEC;

	scripting_context->event_data = data;
	scripting_context->pevent = evsel->tp_format->pevent;

	ENTER;
	SAVETMPS;
	PUSHMARK(SP);

	XPUSHs(sv_2mortal(newSVpv(handler, 0)));
	XPUSHs(sv_2mortal(newSViv(PTR2IV(scripting_context))));
	XPUSHs(sv_2mortal(newSVuv(cpu)));
	XPUSHs(sv_2mortal(newSVuv(s)));
	XPUSHs(sv_2mortal(newSVuv(ns)));
	XPUSHs(sv_2mortal(newSViv(pid)));
	XPUSHs(sv_2mortal(newSVpv(comm, 0)));

	/* common fields other than pid can be accessed via xsub fns */

	for (field = event->format.fields; field; field = field->next) {
		if (field->flags & FIELD_IS_STRING) {
			int offset;
			if (field->flags & FIELD_IS_DYNAMIC) {
				offset = *(int *)(data + field->offset);
				offset &= 0xffff;
			} else
				offset = field->offset;
			XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0)));
		} else { /* FIELD_IS_NUMERIC */
			val = read_size(event, data + field->offset,
					field->size);
			if (field->flags & FIELD_IS_SIGNED) {
				XPUSHs(sv_2mortal(newSViv(val)));
			} else {
				XPUSHs(sv_2mortal(newSVuv(val)));
			}
		}
	}

	PUTBACK;

	if (get_cv(handler, 0))
		call_pv(handler, G_SCALAR);
	else if (get_cv("main::trace_unhandled", 0)) {
		XPUSHs(sv_2mortal(newSVpv(handler, 0)));
		XPUSHs(sv_2mortal(newSViv(PTR2IV(scripting_context))));
		XPUSHs(sv_2mortal(newSVuv(cpu)));
		XPUSHs(sv_2mortal(newSVuv(nsecs)));
		XPUSHs(sv_2mortal(newSViv(pid)));
		XPUSHs(sv_2mortal(newSVpv(comm, 0)));
		call_pv("main::trace_unhandled", G_SCALAR);
	}
	SPAGAIN;
	PUTBACK;
	FREETMPS;
	LEAVE;
}