mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Joseph Schuchart <joseph.schuchart@tu-dresden.de>
To: Peter Zijlstra <a.p.zijlstra@chello.nl>,
	Paul Mackerras <paulus@samba.org>, Ingo Molnar <mingo@redhat.com>,
	Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Thomas Ilsche <thomas.ilsche@tu-dresden.de>,
	Joseph Schuchart <joseph.schuchart@tu-dresden.de>,
	linux-kernel@vger.kernel.org
Subject: [PATCH] Provide additional sample information to Python scripts
Date: Tue, 18 Feb 2014 09:43:24 +0100	[thread overview]
Message-ID: <53031D2C.2050009@tu-dresden.de> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 818 bytes --]

Good morning,

We have developed a patch for the perf Python scripting interface to
provide additional information about the pid, tid, and cpu of generic
events as well as information about the call-stack and resolved symbol
names. This provides scripts with a greater level of detail. The
mentioned information is already available to the scripting engine and
just has to be handed down. This is done by the attached patch. The
patch is based on Linux-3.13.3.

Please let me know if you have any questions on this.

Thanks
Joseph
-- 
Dipl. Inf. Joseph Schuchart
Computer Scientist

Technische Universität Dresden
Center for Information Services and High Performance Computing (ZIH)
01062 Dresden, Germany

Phone: +49 351 463-36494
Fax: +49 351 463-3773
E-Mail: joseph.schuchart@tu-dresden.de

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: perf_pythonscript_add_sample.patch --]
[-- Type: text/x-patch; name="perf_pythonscript_add_sample.patch", Size: 4624 bytes --]

Perf: Provide sample information and call-chain to Python script

Provide additional sample information on generic events to Python 
scripts, including pid, tid, and cpu for which the event was recorded.
Additionally, provide the call-stack recorded at each event with 
resolved symbols. At the moment, the pointer to the sample struct
is passed to scripts, which seems to be of little use. The patch
puts this information in dictionaries for easy access by Python
scripts. 

Signed-off-by: Joseph Schuchart <joseph.schuchart@tu-dresden.de>
Acked-by: Thomas Ilsche <thomas.ilsche@tu-dresden.de>

@@ -359,7 +359,7 @@ static void python_process_general_event
 					 struct thread *thread,
 					 struct addr_location *al)
 {
-	PyObject *handler, *retval, *t, *dict;
+	PyObject *handler, *retval, *t, *dict, *dict_sample;
 	static char handler_name[64];
 	unsigned n = 0;
 
@@ -375,6 +375,10 @@ static void python_process_general_event
 	if (!dict)
 		Py_FatalError("couldn't create Python dictionary");
 
+	dict_sample = PyDict_New();
+	if (!dict_sample)
+		Py_FatalError("couldn't create Python dictionary");
+
 	snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
 
 	handler = PyDict_GetItemString(main_dict, handler_name);
@@ -384,8 +388,76 @@ static void python_process_general_event
 	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)));
+
+	/* PID/TIDs are limited to 2^29, so we can safely use PyInt */
+	pydict_set_item_string_decref(dict_sample, "pid", PyInt_FromLong(sample->pid));
+	pydict_set_item_string_decref(dict_sample, "tid", PyInt_FromLong(sample->tid));
+	pydict_set_item_string_decref(dict_sample, "cpu", PyInt_FromLong(sample->cpu));
+	pydict_set_item_string_decref(dict_sample, "time", PyLong_FromUnsignedLongLong(sample->time));
+	pydict_set_item_string_decref(dict, "sample", dict_sample);
+
+	/* ip unwinding */
+
+	if (symbol_conf.use_callchain && sample->callchain) {
+		PyObject *pylist;
+
+		if (machine__resolve_callchain(machine, evsel, al->thread,
+						   sample, NULL, NULL, PERF_MAX_STACK_DEPTH) != 0) {
+			pr_err("Failed to resolve callchain. Skipping\n");
+			goto exit;
+		}
+		callchain_cursor_commit(&callchain_cursor);
+
+		pylist = PyList_New(0);
+		if (!pylist)
+			Py_FatalError("couldn't create Python list");
+
+		while (1) {
+			PyObject *pyelem;
+			struct callchain_cursor_node *node;
+			node = callchain_cursor_current(&callchain_cursor);
+			if (!node)
+				break;
+
+			pyelem = PyDict_New();
+			if (!pyelem)
+				Py_FatalError("couldn't create Python dictionary");
+
+
+			pydict_set_item_string_decref(pyelem, "ip", PyInt_FromLong(node->ip));
+
+			if (node->sym) {
+				PyObject *pysym  = PyDict_New();
+				if (!pysym)
+					Py_FatalError("couldn't create Python dictionary");
+				pydict_set_item_string_decref(pysym, "start",   PyInt_FromLong(node->sym->start));
+				pydict_set_item_string_decref(pysym, "end",     PyInt_FromLong(node->sym->end));
+				pydict_set_item_string_decref(pysym, "binding", PyInt_FromLong(node->sym->binding));
+				pydict_set_item_string_decref(pysym, "name",    PyString_FromStringAndSize(node->sym->name, node->sym->namelen));
+				pydict_set_item_string_decref(pyelem, "sym", pysym);
+				Py_DECREF(pysym);
+			}
+
+			if (node->map) {
+				struct map *map = node->map;
+				const char *dsoname = "[unknown]";
+				if (map && map->dso && (map->dso->name || map->dso->long_name)) {
+					if (symbol_conf.show_kernel_path && map->dso->long_name)
+						dsoname = map->dso->long_name;
+					else if (map->dso->name)
+						dsoname = map->dso->name;
+				}
+				pydict_set_item_string_decref(pyelem, "dso", PyString_FromString(dsoname));
+			}
+
+			callchain_cursor_advance(&callchain_cursor);
+			PyList_Append(pylist, pyelem);
+			Py_DECREF(pyelem);
+		}
+		PyDict_SetItemString(dict, "callstack", pylist);
+		Py_DECREF(pylist);
+	}
+
 	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",
@@ -407,6 +479,7 @@ static void python_process_general_event
 	if (retval == NULL)
 		handler_call_die(handler_name);
 exit:
+	Py_DECREF(dict_sample);
 	Py_DECREF(dict);
 	Py_DECREF(t);
 }

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4860 bytes --]

             reply	other threads:[~2014-02-18  9:01 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-18  8:43 Joseph Schuchart [this message]
2014-03-07 14:18 ` Arnaldo Carvalho de Melo
2014-03-12 15:29   ` Thomas Ilsche
2014-03-12 18:39     ` Arnaldo Carvalho de Melo
2014-04-03  8:57   ` Joseph Schuchart
2014-05-29  6:01     ` Namhyung Kim
2014-06-04 12:07       ` Joseph Schuchart
2014-06-04 12:07       ` [PATCH 1/3] Add missing calls to Py_DECREF Joseph Schuchart
2014-06-04 14:44         ` Namhyung Kim
2014-06-04 12:07       ` [PATCH 2/3] Add callchain to generic and tracepoint events Joseph Schuchart
2014-06-04 14:46         ` Namhyung Kim
2014-07-07 17:17         ` Jiri Olsa
2014-07-09  7:40           ` [PATCH 1/3] perf script: Add missing calls to Py_DECREF for return values Joseph Schuchart
2014-07-09  8:14             ` Namhyung Kim
2014-07-09  7:40           ` [PATCH 2/3] perf script: Add callchain to generic and tracepoint events Joseph Schuchart
2014-07-09  8:15             ` Namhyung Kim
2014-07-09 11:27             ` Jiri Olsa
2014-07-09 11:43               ` Joseph Schuchart
2014-07-09 11:49                 ` Jiri Olsa
2014-07-09 14:16                   ` Joseph Schuchart
2014-07-09 14:16                   ` [PATCH 1/3] perf script: Add missing calls to Py_DECREF Joseph Schuchart
2014-07-09 19:07                     ` Arnaldo Carvalho de Melo
2014-07-18  4:22                     ` [tip:perf/core] perf script: Add missing calls to Py_DECREF for return values tip-bot for Joseph Schuchart
2014-07-09 14:16                   ` [PATCH 2/3] perf script: Add callchain to generic and tracepoint events Joseph Schuchart
2014-07-09 19:09                     ` Arnaldo Carvalho de Melo
2014-07-09 19:12                       ` Arnaldo Carvalho de Melo
2014-07-09 19:29                         ` Arnaldo Carvalho de Melo
2014-07-10 11:50                           ` Joseph Schuchart
2014-07-10 11:50                           ` Joseph Schuchart
2014-07-18  4:22                             ` [tip:perf/core] " tip-bot for Joseph Schuchart
2014-07-10 11:50                           ` [PATCH 3/3] perf script: Provide additional sample information on generic events Joseph Schuchart
2014-07-18  4:23                             ` [tip:perf/core] " tip-bot for Joseph Schuchart
2014-07-09 14:16                   ` [PATCH 3/3] " Joseph Schuchart
2014-07-09  7:40           ` Joseph Schuchart
2014-07-09  8:16             ` Namhyung Kim
2014-06-04 12:07       ` [PATCH 3/3] " Joseph Schuchart
2014-06-04 14:55         ` Namhyung Kim

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53031D2C.2050009@tu-dresden.de \
    --to=joseph.schuchart@tu-dresden.de \
    --cc=a.p.zijlstra@chello.nl \
    --cc=acme@ghostprotocols.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=paulus@samba.org \
    --cc=thomas.ilsche@tu-dresden.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome