diff options
Diffstat (limited to 'Documentation')
46 files changed, 5458 insertions, 0 deletions
diff --git a/Documentation/.gitignore b/Documentation/.gitignore new file mode 100644 index 0000000..bdc8252 --- /dev/null +++ b/Documentation/.gitignore @@ -0,0 +1,3 @@ +*.m +*.3 +*.html diff --git a/Documentation/Makefile b/Documentation/Makefile new file mode 100644 index 0000000..39f2be4 --- /dev/null +++ b/Documentation/Makefile @@ -0,0 +1,221 @@ +include ../scripts/utilities.mak +include ../scripts/utils.mk + +# This Makefile and manpage XSL files were taken from tools/perf/Documentation +# and modified for libtraceevent. + +MAN3_TXT= \ + $(wildcard libtraceevent-*.txt) \ + libtraceevent.txt + +MAN_TXT = $(MAN3_TXT) +_MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT)) +_MAN_HTML=$(patsubst %.txt,%.html,$(MAN_TXT)) +_DOC_MAN3=$(patsubst %.txt,%.m,$(MAN3_TXT)) + +OUTPUT := $(obj)/Documentation/ + +MAN_XML=$(addprefix $(OUTPUT),$(_MAN_XML)) +MAN_HTML=$(addprefix $(OUTPUT),$(_MAN_HTML)) +DOC_MAN3=$(addprefix $(OUTPUT),$(_DOC_MAN3)) + +# Make the path relative to DESTDIR, not prefix +ifndef DESTDIR +prefix?=$(HOME) +endif +bindir?=$(prefix)/bin +htmldir?=$(prefix)/share/doc/libtraceevent-doc +pdfdir?=$(prefix)/share/doc/libtraceevent-doc +mandir?=$(prefix)/share/man +man3dir=$(mandir)/man3 + +ASCIIDOC=asciidoc +ASCIIDOC_EXTRA = --unsafe -f asciidoc.conf +ASCIIDOC_HTML = xhtml11 +MANPAGE_XSL = manpage-normal.xsl +XMLTO_EXTRA = +INSTALL?=install +RM ?= rm -f + +ifdef USE_ASCIIDOCTOR +ASCIIDOC = asciidoctor +ASCIIDOC_EXTRA = -a compat-mode +ASCIIDOC_EXTRA += -I. -rasciidoctor-extensions +ASCIIDOC_EXTRA += -a mansource="libtraceevent" -a manmanual="libtraceevent Manual" +ASCIIDOC_HTML = xhtml5 +endif + +XMLTO=xmlto + +_tmp_tool_path := $(call get-executable,$(ASCIIDOC)) +ifeq ($(_tmp_tool_path),) + missing_tools = $(ASCIIDOC) +endif + +ifndef USE_ASCIIDOCTOR +_tmp_tool_path := $(call get-executable,$(XMLTO)) +ifeq ($(_tmp_tool_path),) + missing_tools += $(XMLTO) +endif +endif + +# +# For asciidoc ... +# -7.1.2, no extra settings are needed. +# 8.0-, set ASCIIDOC8. +# + +# +# For docbook-xsl ... +# -1.68.1, set ASCIIDOC_NO_ROFF? (based on changelog from 1.73.0) +# 1.69.0, no extra settings are needed? +# 1.69.1-1.71.0, set DOCBOOK_SUPPRESS_SP? +# 1.71.1, no extra settings are needed? +# 1.72.0, set DOCBOOK_XSL_172. +# 1.73.0-, set ASCIIDOC_NO_ROFF +# + +# +# If you had been using DOCBOOK_XSL_172 in an attempt to get rid +# of 'the ".ft C" problem' in your generated manpages, and you +# instead ended up with weird characters around callouts, try +# using ASCIIDOC_NO_ROFF instead (it works fine with ASCIIDOC8). +# + +ifdef ASCIIDOC8 +ASCIIDOC_EXTRA += -a asciidoc7compatible +endif +ifdef DOCBOOK_XSL_172 +ASCIIDOC_EXTRA += -a libtraceevent-asciidoc-no-roff +MANPAGE_XSL = manpage-1.72.xsl +else + ifdef ASCIIDOC_NO_ROFF + # docbook-xsl after 1.72 needs the regular XSL, but will not + # pass-thru raw roff codes from asciidoc.conf, so turn them off. + ASCIIDOC_EXTRA += -a libtraceevent-asciidoc-no-roff + endif +endif +ifdef MAN_BOLD_LITERAL +XMLTO_EXTRA += -m manpage-bold-literal.xsl +endif +ifdef DOCBOOK_SUPPRESS_SP +XMLTO_EXTRA += -m manpage-suppress-sp.xsl +endif + +SHELL_PATH ?= $(SHELL) +# Shell quote; +SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) + +DESTDIR ?= +DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' + +export DESTDIR DESTDIR_SQ + +# +# Please note that there is a minor bug in asciidoc. +# The version after 6.0.3 _will_ include the patch found here: +# http://marc.theaimsgroup.com/?l=libtraceevent&m=111558757202243&w=2 +# +# Until that version is released you may have to apply the patch +# yourself - yes, all 6 characters of it! +# +QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir +QUIET_SUBDIR1 = + +ifneq ($(findstring $(MAKEFLAGS),w),w) +PRINT_DIR = --no-print-directory +else # "make -w" +NO_SUBDIR = : +endif + +ifneq ($(findstring $(MAKEFLAGS),s),s) +ifneq ($(V),1) + QUIET_ASCIIDOC = @echo ' ASCIIDOC '$@; + QUIET_XMLTO = @echo ' XMLTO '$@; + QUIET_SUBDIR0 = +@subdir= + QUIET_SUBDIR1 = ;$(NO_SUBDIR) \ + echo ' SUBDIR ' $$subdir; \ + $(MAKE) $(PRINT_DIR) -C $$subdir + export V +endif +endif + +all: html man + +man: man3 +man3: $(DOC_MAN3) + +html: $(MAN_HTML) + +$(MAN_HTML) $(DOC_MAN3): asciidoc.conf + +install: install-man install-html + +check-man-tools: +ifdef missing_tools + $(error "You need to install $(missing_tools) for man pages") +endif + +$(OUTPUT)install-%.3: $(OUTPUT)%.3 + $(Q)$(call do_install,$<,$(man3dir),644) + +do-install-man: man $(patsubst $(OUTPUT)%,$(OUTPUT)install-%,$(wildcard $(OUTPUT)*.3)) + +install-man: check-man-tools man + $(Q)$(MAKE) -C . do-install-man + +install-%.txt: $(OUTPUT)%.html + $(Q)$(call do_install,$<,$(htmldir),644) + +do-install-html: html $(addprefix install-,$(wildcard *.txt)) + +install-html: check-man-tools html do-install-html + +uninstall: uninstall-man uninstall-html + +uninstall-man: + $(call QUIET_UNINST, Documentation-man) \ + $(Q)$(RM) $(addprefix $(DESTDIR)$(man3dir)/,$(DOC_MAN3)) + +uninstall-html: + $(call QUIET_UNINST, Documentation-html) \ + $(Q)$(RM) $(addprefix $(DESTDIR)$(htmldir)/,$(MAN_HTML)) + +ifdef missing_tools + DO_INSTALL_MAN = $(warning Please install $(missing_tools) to have the man pages installed) +else + DO_INSTALL_MAN = do-install-man +endif + +CLEAN_FILES = \ + $(MAN_XML) $(addsuffix +,$(MAN_XML)) \ + $(MAN_HTML) $(addsuffix +,$(MAN_HTML)) \ + $(DOC_MAN3) $(OUTPUT)*.3 $(OUTPUT)*.m + +clean: + $(call QUIET_CLEAN, Documentation) $(RM) $(CLEAN_FILES) + +ifdef USE_ASCIIDOCTOR +$(OUTPUT)%.3 : $(OUTPUT)%.txt + $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ + $(ASCIIDOC) -b manpage -d manpage \ + $(ASCIIDOC_EXTRA) -alibtraceevent_version=$(EVENT_PARSE_VERSION) -o $@+ $< && \ + mv $@+ $@ +endif + +$(OUTPUT)%.m : $(OUTPUT)%.xml + $(QUIET_XMLTO)$(RM) $@ && \ + $(XMLTO) -o $(OUTPUT). -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<; \ + touch $@ + +$(OUTPUT)%.xml : %.txt + $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ + $(ASCIIDOC) -b docbook -d manpage \ + $(ASCIIDOC_EXTRA) -alibtraceevent_version=$(EVENT_PARSE_VERSION) -o $@+ $< && \ + mv $@+ $@ + +$(MAN_HTML): $(OUTPUT)%.html : %.txt + $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ + $(ASCIIDOC) -b $(ASCIIDOC_HTML) -d manpage \ + $(ASCIIDOC_EXTRA) -alibtraceevent_version=$(EVENT_PARSE_VERSION) -o $@+ $< && \ + mv $@+ $@ diff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf new file mode 100644 index 0000000..0759571 --- /dev/null +++ b/Documentation/asciidoc.conf @@ -0,0 +1,120 @@ +## linktep: macro +# +# Usage: linktep:command[manpage-section] +# +# Note, {0} is the manpage section, while {target} is the command. +# +# Show TEP link as: <command>(<section>); if section is defined, else just show +# the command. + +[macros] +(?su)[\\]?(?P<name>linktep):(?P<target>\S*?)\[(?P<attrlist>.*?)\]= + +[attributes] +asterisk=* +plus=+ +caret=^ +startsb=[ +endsb=] +tilde=~ + +ifdef::backend-docbook[] +[linktep-inlinemacro] +{0%{target}} +{0#<citerefentry>} +{0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>} +{0#</citerefentry>} +endif::backend-docbook[] + +ifdef::backend-docbook[] +ifndef::tep-asciidoc-no-roff[] +# "unbreak" docbook-xsl v1.68 for manpages. v1.69 works with or without this. +# v1.72 breaks with this because it replaces dots not in roff requests. +[listingblock] +<example><title>{title}</title> +<literallayout> +ifdef::doctype-manpage[] + .ft C +endif::doctype-manpage[] +| +ifdef::doctype-manpage[] + .ft +endif::doctype-manpage[] +</literallayout> +{title#}</example> +endif::tep-asciidoc-no-roff[] + +ifdef::tep-asciidoc-no-roff[] +ifdef::doctype-manpage[] +# The following two small workarounds insert a simple paragraph after screen +[listingblock] +<example><title>{title}</title> +<literallayout> +| +</literallayout><simpara></simpara> +{title#}</example> + +[verseblock] +<formalpara{id? id="{id}"}><title>{title}</title><para> +{title%}<literallayout{id? id="{id}"}> +{title#}<literallayout> +| +</literallayout> +{title#}</para></formalpara> +{title%}<simpara></simpara> +endif::doctype-manpage[] +endif::tep-asciidoc-no-roff[] +endif::backend-docbook[] + +ifdef::doctype-manpage[] +ifdef::backend-docbook[] +[header] +template::[header-declarations] +<refentry> +<refmeta> +<refentrytitle>{mantitle}</refentrytitle> +<manvolnum>{manvolnum}</manvolnum> +<refmiscinfo class="source">libtraceevent</refmiscinfo> +<refmiscinfo class="version">{libtraceevent_version}</refmiscinfo> +<refmiscinfo class="manual">libtraceevent Manual</refmiscinfo> +</refmeta> +<refnamediv> + <refname>{manname1}</refname> + <refname>{manname2}</refname> + <refname>{manname3}</refname> + <refname>{manname4}</refname> + <refname>{manname5}</refname> + <refname>{manname6}</refname> + <refname>{manname7}</refname> + <refname>{manname8}</refname> + <refname>{manname9}</refname> + <refname>{manname10}</refname> + <refname>{manname11}</refname> + <refname>{manname12}</refname> + <refname>{manname13}</refname> + <refname>{manname14}</refname> + <refname>{manname15}</refname> + <refname>{manname16}</refname> + <refname>{manname17}</refname> + <refname>{manname18}</refname> + <refname>{manname19}</refname> + <refname>{manname20}</refname> + <refname>{manname21}</refname> + <refname>{manname22}</refname> + <refname>{manname23}</refname> + <refname>{manname24}</refname> + <refname>{manname25}</refname> + <refname>{manname26}</refname> + <refname>{manname27}</refname> + <refname>{manname28}</refname> + <refname>{manname29}</refname> + <refname>{manname30}</refname> + <refpurpose>{manpurpose}</refpurpose> +</refnamediv> +endif::backend-docbook[] +endif::doctype-manpage[] + +ifdef::backend-xhtml11[] +[linktep-inlinemacro] +<a href="{target}.html">{target}{0?({0})}</a> +endif::backend-xhtml11[] diff --git a/Documentation/libtraceevent-commands.txt b/Documentation/libtraceevent-commands.txt new file mode 100644 index 0000000..cea3001 --- /dev/null +++ b/Documentation/libtraceevent-commands.txt @@ -0,0 +1,153 @@ +libtraceevent(3) +================ + +NAME +---- +tep_register_comm, tep_override_comm, tep_is_pid_registered, +tep_data_comm_from_pid, tep_data_pid_from_comm, tep_cmdline_pid - +Manage pid to process name mappings. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +int *tep_register_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, int _pid_); +int *tep_override_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, int _pid_); +bool *tep_is_pid_registered*(struct tep_handle pass:[*]_tep_, int _pid_); +const char pass:[*]*tep_data_comm_from_pid*(struct tep_handle pass:[*]_pevent_, int _pid_); +struct cmdline pass:[*]*tep_data_pid_from_comm*(struct tep_handle pass:[*]_pevent_, const char pass:[*]_comm_, struct cmdline pass:[*]_next_); +int *tep_cmdline_pid*(struct tep_handle pass:[*]_pevent_, struct cmdline pass:[*]_cmdline_); +-- + +DESCRIPTION +----------- +These functions can be used to handle the mapping between pid and process name. +The library builds a cache of these mappings, which is used to display the name +of the process, instead of its pid. This information can be retrieved from +tracefs/saved_cmdlines file. + +The *tep_register_comm()* function registers a _pid_ / process name mapping. +If a command with the same _pid_ is already registered, an error is returned. +The _pid_ argument is the process ID, the _comm_ argument is the process name, +_tep_ is the event context. The _comm_ is duplicated internally. + +The *tep_override_comm()* function registers a _pid_ / process name mapping. +If a process with the same pid is already registered, the process name string is +udapted with the new one. The _pid_ argument is the process ID, the _comm_ +argument is the process name, _tep_ is the event context. The _comm_ is +duplicated internally. + +The *tep_is_pid_registered()* function checks if a pid has a process name +mapping registered. The _pid_ argument is the process ID, _tep_ is the event +context. + +The *tep_data_comm_from_pid()* function returns the process name for a given +pid. The _pid_ argument is the process ID, _tep_ is the event context. +The returned string should not be freed, but will be freed when the _tep_ +handler is closed. + +The *tep_data_pid_from_comm()* function returns a pid for a given process name. +The _comm_ argument is the process name, _tep_ is the event context. +The argument _next_ is the cmdline structure to search for the next pid. +As there may be more than one pid for a given process, the result of this call +can be passed back into a recurring call in the _next_ parameter, to search for +the next pid. If _next_ is NULL, it will return the first pid associated with +the _comm_. The function performs a linear search, so it may be slow. + +The *tep_cmdline_pid()* function returns the pid associated with a given +_cmdline_. The _tep_ argument is the event context. + +RETURN VALUE +------------ +*tep_register_comm()* function returns 0 on success. In case of an error -1 is +returned and errno is set to indicate the cause of the problem: ENOMEM, if there +is not enough memory to duplicate the _comm_ or EEXIST if a mapping for this +_pid_ is already registered. + +*tep_override_comm()* function returns 0 on success. In case of an error -1 is +returned and errno is set to indicate the cause of the problem: ENOMEM, if there +is not enough memory to duplicate the _comm_. + +*tep_is_pid_registered()* function returns true if the _pid_ has a process name +mapped to it, false otherwise. + +*tep_data_comm_from_pid()* function returns the process name as string, or the +string "<...>" if there is no mapping for the given pid. + +*tep_data_pid_from_comm()* function returns a pointer to a struct cmdline, that +holds a pid for a given process, or NULL if none is found. This result can be +passed back into a recurring call as the _next_ parameter of the function. + +*tep_cmdline_pid()* functions returns the pid for the give cmdline. If _cmdline_ + is NULL, then -1 is returned. + +EXAMPLE +------- +The following example registers pid for command "ls", in context of event _tep_ +and performs various searches for pid / process name mappings: +[source,c] +-- +#include <event-parse.h> +... +int ret; +int ls_pid = 1021; +struct tep_handle *tep = tep_alloc(); +... + ret = tep_register_comm(tep, "ls", ls_pid); + if (ret != 0 && errno == EEXIST) + ret = tep_override_comm(tep, "ls", ls_pid); + if (ret != 0) { + /* Failed to register pid / command mapping */ + } +... + if (tep_is_pid_registered(tep, ls_pid) == 0) { + /* Command mapping for ls_pid is not registered */ + } +... + const char *comm = tep_data_comm_from_pid(tep, ls_pid); + if (comm) { + /* Found process name for ls_pid */ + } +... + int pid; + struct cmdline *cmd = tep_data_pid_from_comm(tep, "ls", NULL); + while (cmd) { + pid = tep_cmdline_pid(tep, cmd); + /* Found pid for process "ls" */ + cmd = tep_data_pid_from_comm(tep, "ls", cmd); + } +-- +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-cpus.txt b/Documentation/libtraceevent-cpus.txt new file mode 100644 index 0000000..aff4223 --- /dev/null +++ b/Documentation/libtraceevent-cpus.txt @@ -0,0 +1,77 @@ +libtraceevent(3) +================ + +NAME +---- +tep_get_cpus, tep_set_cpus - Get / set the number of CPUs, which have a tracing +buffer representing it. Note, the buffer may be empty. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +int *tep_get_cpus*(struct tep_handle pass:[*]_tep_); +void *tep_set_cpus*(struct tep_handle pass:[*]_tep_, int _cpus_); +-- + +DESCRIPTION +----------- +The *tep_get_cpus()* function gets the number of CPUs, which have a tracing +buffer representing it. The _tep_ argument is trace event parser context. + +The *tep_set_cpus()* function sets the number of CPUs, which have a tracing +buffer representing it. The _tep_ argument is trace event parser context. +The _cpu_ argument is the number of CPUs with tracing data. + +RETURN VALUE +------------ +The *tep_get_cpus()* functions returns the number of CPUs, which have tracing +data recorded. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... + tep_set_cpus(tep, 5); +... + printf("We have tracing data for %d CPUs", tep_get_cpus(tep)); +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-debug.txt b/Documentation/libtraceevent-debug.txt new file mode 100644 index 0000000..ff1d06d --- /dev/null +++ b/Documentation/libtraceevent-debug.txt @@ -0,0 +1,95 @@ +libtraceevent(3) +================ + +NAME +---- +tep_print_printk, tep_print_funcs, tep_set_test_filters, tep_plugin_print_options - +Print libtraceevent internal information. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* +*#include <trace-seq.h>* + +void *tep_print_printk*(struct tep_handle pass:[*]tep); +void *tep_print_funcs*(struct tep_handle pass:[*]tep); +void *tep_set_test_filters*(struct tep_handle pass:[*]tep, int test_filters); +void *tep_plugin_print_options*(struct trace_seq pass:[*]s); +-- + +DESCRIPTION +----------- +The *tep_print_printk()* function prints the printk string formats that were +stored for this tracing session. The _tep_ argument is trace event parser context. + +The *tep_print_funcs()* function prints the stored function name to address mapping +for this tracing session. The _tep_ argument is trace event parser context. + +The *tep_set_test_filters()* function sets a flag to test a filter string. If this +flag is set, when *tep_filter_add_filter_str()* API as called, it will print the filter +string instead of adding it. The _tep_ argument is trace event parser context. +The _test_filters_ argument is the test flag that will be set. + +The *tep_plugin_print_options()* function writes a list of the registered plugin options +into _s_. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +#include <trace-seq.h> +... +struct tep_handle *tep = tep_alloc(); +... + tep_print_printk(tep); +... + tep_print_funcs(tep); +... +struct tep_event_filter *filter = tep_filter_alloc(tep); + tep_set_test_filters(tep, 1); + tep_filter_add_filter_str(filter, "sched/sched_wakeup:target_cpu==1"); + tep_set_test_filters(tep, 0); + tep_filter_free(filter); +... +struct trace_seq seq; +trace_seq_init(&seq); + + tep_plugin_print_options(&s); +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-endian_read.txt b/Documentation/libtraceevent-endian_read.txt new file mode 100644 index 0000000..372d52a --- /dev/null +++ b/Documentation/libtraceevent-endian_read.txt @@ -0,0 +1,78 @@ +libtraceevent(3) +================ + +NAME +---- +tep_read_number - Reads a number from raw data. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +unsigned long long *tep_read_number*(struct tep_handle pass:[*]_tep_, const void pass:[*]_ptr_, int _size_); +-- + +DESCRIPTION +----------- +The *tep_read_number()* function reads an integer from raw data, taking into +account the endianness of the raw data and the current host. The _tep_ argument +is the trace event parser context. The _ptr_ is a pointer to the raw data, where +the integer is, and the _size_ is the size of the integer. + +RETURN VALUE +------------ +The *tep_read_number()* function returns the integer in the byte order of +the current host. In case of an error, 0 is returned. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... +void process_record(struct tep_record *record) +{ + int offset = 24; + int data = tep_read_number(tep, record->data + offset, 4); + + /* Read the 4 bytes at the offset 24 of data as an integer */ +} +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-event_find.txt b/Documentation/libtraceevent-event_find.txt new file mode 100644 index 0000000..56d76b1 --- /dev/null +++ b/Documentation/libtraceevent-event_find.txt @@ -0,0 +1,103 @@ +libtraceevent(3) +================ + +NAME +---- +tep_find_event,tep_find_event_by_name,tep_find_event_by_record - +Find events by given key. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +struct tep_event pass:[*]*tep_find_event*(struct tep_handle pass:[*]_tep_, int _id_); +struct tep_event pass:[*]*tep_find_event_by_name*(struct tep_handle pass:[*]_tep_, const char pass:[*]_sys_, const char pass:[*]_name_); +struct tep_event pass:[*]*tep_find_event_by_record*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_record_); +-- + +DESCRIPTION +----------- +This set of functions can be used to search for an event, based on a given +criteria. All functions require a pointer to a _tep_, trace event parser +context. + +The *tep_find_event()* function searches for an event by given event _id_. The +event ID is assigned dynamically and can be viewed in event's format file, +"ID" field. + +The *tep_find_event_by_name()* function searches for an event by given +event _name_, under the system _sys_. If the _sys_ is NULL (not specified), +the first event with _name_ is returned. + +The tep_find_event_by_record()* function searches for an event from a given +_record_. + +RETURN VALUE +------------ +All these functions return a pointer to the found event, or NULL if there is no +such event. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... +struct tep_event *event; + +event = tep_find_event(tep, 1857); +if (event == NULL) { + /* There is no event with ID 1857 */ +} + +event = tep_find_event_by_name(tep, "kvm", "kvm_exit"); +if (event == NULL) { + /* There is no kvm_exit event, from kvm system */ +} + +void event_from_record(struct tep_record *record) +{ + struct tep_event *event = tep_find_event_by_record(tep, record); + if (event == NULL) { + /* There is no event from given record */ + } +} +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-event_get.txt b/Documentation/libtraceevent-event_get.txt new file mode 100644 index 0000000..488f176 --- /dev/null +++ b/Documentation/libtraceevent-event_get.txt @@ -0,0 +1,99 @@ +libtraceevent(3) +================ + +NAME +---- +tep_get_event, tep_get_first_event, tep_get_events_count - Access events. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +struct tep_event pass:[*]*tep_get_event*(struct tep_handle pass:[*]_tep_, int _index_); +struct tep_event pass:[*]*tep_get_first_event*(struct tep_handle pass:[*]_tep_); +int *tep_get_events_count*(struct tep_handle pass:[*]_tep_); +-- + +DESCRIPTION +----------- +The *tep_get_event()* function returns a pointer to event at the given _index_. +The _tep_ argument is trace event parser context, the _index_ is the index of +the requested event. + +The *tep_get_first_event()* function returns a pointer to the first event. +As events are stored in an array, this function returns the pointer to the +beginning of the array. The _tep_ argument is trace event parser context. + +The *tep_get_events_count()* function returns the number of the events +in the array. The _tep_ argument is trace event parser context. + +RETURN VALUE +------------ +The *tep_get_event()* returns a pointer to the event located at _index_. +NULL is returned in case of error, in case there are no events or _index_ is +out of range. + +The *tep_get_first_event()* returns a pointer to the first event. NULL is +returned in case of error, or in case there are no events. + +The *tep_get_events_count()* returns the number of the events. 0 is +returned in case of error, or in case there are no events. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... +int i,count = tep_get_events_count(tep); +struct tep_event *event, *events = tep_get_first_event(tep); + +if (events == NULL) { + /* There are no events */ +} else { + for (i = 0; i < count; i++) { + event = (events+i); + /* process events[i] */ + } + + /* Get the last event */ + event = tep_get_event(tep, count-1); +} +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-event_list.txt b/Documentation/libtraceevent-event_list.txt new file mode 100644 index 0000000..a958b18 --- /dev/null +++ b/Documentation/libtraceevent-event_list.txt @@ -0,0 +1,122 @@ +libtraceevent(3) +================ + +NAME +---- +tep_list_events, tep_list_events_copy - +Get list of events, sorted by given criteria. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +enum *tep_event_sort_type* { + _TEP_EVENT_SORT_ID_, + _TEP_EVENT_SORT_NAME_, + _TEP_EVENT_SORT_SYSTEM_, +}; + +struct tep_event pass:[*]pass:[*]*tep_list_events*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_); +struct tep_event pass:[*]pass:[*]*tep_list_events_copy*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_); +-- + +DESCRIPTION +----------- +The *tep_list_events()* function returns an array of pointers to the events, +sorted by the _sort_type_ criteria. The last element of the array is NULL. +The returned memory must not be freed, it is managed by the library. +The function is not thread safe. The _tep_ argument is trace event parser +context. The _sort_type_ argument is the required sort criteria: +[verse] +-- + _TEP_EVENT_SORT_ID_ - sort by the event ID. + _TEP_EVENT_SORT_NAME_ - sort by the event (name, system, id) triplet. + _TEP_EVENT_SORT_SYSTEM_ - sort by the event (system, name, id) triplet. +-- + +The *tep_list_events_copy()* is a thread safe version of _tep_list_events()_. +It has the same behavior, but the returned array is allocated internally and +must be freed by the caller. Note that the content of the array must not be +freed (see the EXAMPLE below). + +RETURN VALUE +------------ +The *tep_list_events()* function returns an array of pointers to events. +In case of an error, NULL is returned. The returned array must not be freed, +it is managed by the library. + +The *tep_list_events_copy()* function returns an array of pointers to events. +In case of an error, NULL is returned. The returned array must be freed by +the caller. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... +int i; +struct tep_event_format **events; + +i=0; +events = tep_list_events(tep, TEP_EVENT_SORT_ID); +if (events == NULL) { + /* Failed to get the events, sorted by ID */ +} else { + while(events[i]) { + /* walk through the list of the events, sorted by ID */ + i++; + } +} + +i=0; +events = tep_list_events_copy(tep, TEP_EVENT_SORT_NAME); +if (events == NULL) { + /* Failed to get the events, sorted by name */ +} else { + while(events[i]) { + /* walk through the list of the events, sorted by name */ + i++; + } + free(events); +} + +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-event_print.txt b/Documentation/libtraceevent-event_print.txt new file mode 100644 index 0000000..6a5946a --- /dev/null +++ b/Documentation/libtraceevent-event_print.txt @@ -0,0 +1,130 @@ +libtraceevent(3) +================ + +NAME +---- +tep_print_event - Writes event information into a trace sequence. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* +*#include <trace-seq.h>* + +void *tep_print_event*(struct tep_handle pass:[*]_tep_, struct trace_seqpass:[*]_s_, struct tep_record pass:[*]_record_, const char pass:[*]_fmt_, _..._) +-- + +DESCRIPTION +----------- + +The *tep_print_event()* function parses the event information of the given +_record_ and writes it into the trace sequence _s_, according to the format +string _fmt_. The desired information is specified after the format string. +The _fmt_ is printf-like format string, following arguments are supported: +[verse] +-- + TEP_PRINT_PID, "%d" - PID of the event. + TEP_PRINT_CPU, "%d" - Event CPU. + TEP_PRINT_COMM, "%s" - Event command string. + TEP_PRINT_NAME, "%s" - Event name. + TEP_PRINT_LATENCY, "%s" - Latency of the event. It prints 4 or more + fields - interrupt state, scheduling state, + current context, and preemption count. + Field 1 is the interrupt enabled state: + d : Interrupts are disabled + . : Interrupts are enabled + X : The architecture does not support this + information + Field 2 is the "need resched" state. + N : The task is set to call the scheduler when + possible, as another higher priority task + may need to be scheduled in. + . : The task is not set to call the scheduler. + Field 3 is the context state. + . : Normal context + s : Soft interrupt context + h : Hard interrupt context + H : Hard interrupt context which triggered + during soft interrupt context. + z : NMI context + Z : NMI context which triggered during hard + interrupt context + Field 4 is the preemption count. + . : The preempt count is zero. + On preemptible kernels (where the task can be scheduled + out in arbitrary locations while in kernel context), the + preempt count, when non zero, will prevent the kernel + from scheduling out the current task. The preempt count + number is displayed when it is not zero. + Depending on the kernel, it may show other fields + (lock depth, or migration disabled, which are unique to + specialized kernels). + TEP_PRINT_TIME, %d - event time stamp. A divisor and precision can be + specified as part of this format string: + "%precision.divisord". Example: + "%3.1000d" - divide the time by 1000 and print the first + 3 digits before the dot. Thus, the time stamp + "123456000" will be printed as "123.456" + TEP_PRINT_INFO, "%s" - event information. + TEP_PRINT_INFO_RAW, "%s" - event information, in raw format. + +-- +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +#include <trace-seq.h> +... +struct trace_seq seq; +trace_seq_init(&seq); +struct tep_handle *tep = tep_alloc(); +... +void print_my_event(struct tep_record *record) +{ + trace_seq_reset(&seq); + tep_print_event(tep, s, record, "%16s-%-5d [%03d] %s %6.1000d %s %s", + TEP_PRINT_COMM, TEP_PRINT_PID, TEP_PRINT_CPU, + TEP_PRINT_LATENCY, TEP_PRINT_TIME, TEP_PRINT_NAME, + TEP_PRINT_INFO); +} +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*trace-seq.h* + Header file to include in order to have access to trace sequences related APIs. + Trace sequences are used to allow a function to call several other functions + to create a string of data to use. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-field_find.txt b/Documentation/libtraceevent-field_find.txt new file mode 100644 index 0000000..5e4071c --- /dev/null +++ b/Documentation/libtraceevent-field_find.txt @@ -0,0 +1,118 @@ +libtraceevent(3) +================ + +NAME +---- +tep_find_common_field, tep_find_field, tep_find_any_field - +Search for a field in an event. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +struct tep_format_field pass:[*]*tep_find_common_field*(struct tep_event pass:[*]_event_, const char pass:[*]_name_); +struct tep_format_field pass:[*]*tep_find_field*(struct tep_event_ormat pass:[*]_event_, const char pass:[*]_name_); +struct tep_format_field pass:[*]*tep_find_any_field*(struct tep_event pass:[*]_event_, const char pass:[*]_name_); +-- + +DESCRIPTION +----------- +These functions search for a field with given name in an event. The field +returned can be used to find the field content from within a data record. + +The *tep_find_common_field()* function searches for a common field with _name_ +in the _event_. + +The *tep_find_field()* function searches for an event specific field with +_name_ in the _event_. + +The *tep_find_any_field()* function searches for any field with _name_ in the +_event_. + +RETURN VALUE +------------ +The _tep_find_common_field(), *tep_find_field()* and _tep_find_any_field()_ +functions return a pointer to the found field, or NULL in case there is no field +with the requested name. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +void get_htimer_info(struct tep_handle *tep, struct tep_record *record) +{ + struct tep_format_field *field; + struct tep_event *event; + long long softexpires; + int mode; + int pid; + + event = tep_find_event_by_name(tep, "timer", "hrtimer_start"); + + field = tep_find_common_field(event, "common_pid"); + if (field == NULL) { + /* Cannot find "common_pid" field in the event */ + } else { + /* Get pid from the data record */ + pid = tep_read_number(tep, record->data + field->offset, + field->size); + } + + field = tep_find_field(event, "softexpires"); + if (field == NULL) { + /* Cannot find "softexpires" event specific field in the event */ + } else { + /* Get softexpires parameter from the data record */ + softexpires = tep_read_number(tep, record->data + field->offset, + field->size); + } + + field = tep_find_any_field(event, "mode"); + if (field == NULL) { + /* Cannot find "mode" field in the event */ + } else + { + /* Get mode parameter from the data record */ + mode = tep_read_number(tep, record->data + field->offset, + field->size); + } +} +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-field_get_val.txt b/Documentation/libtraceevent-field_get_val.txt new file mode 100644 index 0000000..6a5f1cd --- /dev/null +++ b/Documentation/libtraceevent-field_get_val.txt @@ -0,0 +1,122 @@ +libtraceevent(3) +================ + +NAME +---- +tep_get_any_field_val, tep_get_common_field_val, tep_get_field_val, +tep_get_field_raw - Get value of a field. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* +*#include <trace-seq.h>* + +int *tep_get_any_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); +int *tep_get_common_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); +int *tep_get_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); +void pass:[*]*tep_get_field_raw*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int pass:[*]_len_, int _err_); +-- + +DESCRIPTION +----------- +These functions can be used to find a field and retrieve its value. + +The *tep_get_any_field_val()* function searches in the _record_ for a field +with _name_, part of the _event_. If the field is found, its value is stored in +_val_. If there is an error and _err_ is not zero, then an error string is +written into _s_. + +The *tep_get_common_field_val()* function does the same as +*tep_get_any_field_val()*, but searches only in the common fields. This works +for any event as all events include the common fields. + +The *tep_get_field_val()* function does the same as *tep_get_any_field_val()*, +but searches only in the event specific fields. + +The *tep_get_field_raw()* function searches in the _record_ for a field with +_name_, part of the _event_. If the field is found, a pointer to where the field +exists in the record's raw data is returned. The size of the data is stored in +_len_. If there is an error and _err_ is not zero, then an error string is +written into _s_. + +RETURN VALUE +------------ +The *tep_get_any_field_val()*, *tep_get_common_field_val()* and +*tep_get_field_val()* functions return 0 on success, or -1 in case of an error. + +The *tep_get_field_raw()* function returns a pointer to field's raw data, and +places the length of this data in _len_. In case of an error NULL is returned. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +#include <trace-seq.h> +... +struct tep_handle *tep = tep_alloc(); +... +struct tep_event *event = tep_find_event_by_name(tep, "kvm", "kvm_exit"); +... +void process_record(struct tep_record *record) +{ + int len; + char *comm; + struct tep_event *event; + unsigned long long val; + + event = tep_find_event_by_record(tep, record); + if (event != NULL) { + if (tep_get_common_field_val(NULL, event, "common_type", + record, &val, 0) == 0) { + /* Got the value of common type field */ + } + if (tep_get_field_val(NULL, event, "pid", record, &val, 0) == 0) { + /* Got the value of pid specific field */ + } + comm = tep_get_field_raw(NULL, event, "comm", record, &len, 0); + if (comm != NULL) { + /* Got a pointer to the comm event specific field */ + } + } +} +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*trace-seq.h* + Header file to include in order to have access to trace sequences + related APIs. Trace sequences are used to allow a function to call + several other functions to create a string of data to use. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-field_print.txt b/Documentation/libtraceevent-field_print.txt new file mode 100644 index 0000000..3844fd1 --- /dev/null +++ b/Documentation/libtraceevent-field_print.txt @@ -0,0 +1,135 @@ +libtraceevent(3) +================ + +NAME +---- +tep_print_field_content, tep_print_fields, tep_print_num_field, tep_print_func_field, tep_record_print_fields, tep_record_print_selected_fields - +Print the field content. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* +*#include <trace-seq.h>* + +void *tep_print_field_content*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, int size, struct tep_format_field pass:[*]_field_); +void *tep_print_fields*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, int _size_, struct tep_event pass:[*]_event_); +int *tep_print_num_field*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int _err_); +int *tep_print_func_field*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int _err_); +void *tep_record_print_fields*(struct trace_seq pass:[*]_s_, struct tep_record pass:[*]_record_, struct tep_event pass:[*]_event_); +void *tep_record_print_selected_fields*(struct trace_seq pass:[*]_s_, struct tep_record pass:[*]_record_, struct tep_event pass:[*]_event_, int _select_mask_); +-- + +DESCRIPTION +----------- +These functions print recorded field's data, according to the field's type. + +The *tep_print_field_content()* function extracts from the recorded raw _data_ value of +the _field_ and prints it into _s_, according to the field type. + +The *tep_print_fields()* prints each field name followed by the record's field +value according to the field's type: +[verse] +-- +"field1_name=field1_value field2_name=field2_value ..." +-- +It iterates all fields of the _event_, and calls *tep_print_field_content()* for each of +them. + +The *tep_print_num_field()* function prints a numeric field with given format +string. A search is performed in the _event_ for a field with _name_. If such +field is found, its value is extracted from the _record_ and is printed in the +_s_, according to the given format string _fmt_. If the argument _err_ is +non-zero, and an error occures - it is printed in the _s_. + +The *tep_print_func_field()* function prints a function field with given format +string. A search is performed in the _event_ for a field with _name_. If such +field is found, its value is extracted from the _record_. The value is assumed +to be a function address, and a search is perform to find the name of this +function. The function name (if found) and its address are printed in the _s_, +according to the given format string _fmt_. If the argument _err_ is non-zero, +and an error occures - it is printed in _s_. + +The *tep_record_print_fields()* prints the field's name followed by its value +for all record's field. + +The *tep_record_print_selected_fields()* prints the field's name followed by +its value for selected subset of record field. The fields to be printed are +defined by the _select_mask_ bit mask. + +RETURN VALUE +------------ +The *tep_print_num_field()* and *tep_print_func_field()* functions return 1 +on success, -1 in case of an error or 0 if the print buffer _s_ is full. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +#include <trace-seq.h> +... +struct tep_handle *tep = tep_alloc(); +... +struct trace_seq seq; +trace_seq_init(&seq); +struct tep_event *event = tep_find_event_by_name(tep, "timer", "hrtimer_start"); +... +void process_record(struct tep_record *record) +{ + struct tep_format_field *field_pid = tep_find_common_field(event, "common_pid"); + + trace_seq_reset(&seq); + + /* Print the value of "common_pid" */ + tep_print_field_content(&seq, record->data, record->size, field_pid); + + /* Print all fields of the "hrtimer_start" event */ + tep_print_fields(&seq, record->data, record->size, event); + + /* Print the value of "expires" field with custom format string */ + tep_print_num_field(&seq, " timer expires in %llu ", event, "expires", record, 0); + + /* Print the address and the name of "function" field with custom format string */ + tep_print_func_field(&seq, " timer function is %s ", event, "function", record, 0); + } + ... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*trace-seq.h* + Header file to include in order to have access to trace sequences related APIs. + Trace sequences are used to allow a function to call several other functions + to create a string of data to use. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-field_read.txt b/Documentation/libtraceevent-field_read.txt new file mode 100644 index 0000000..cc322fb --- /dev/null +++ b/Documentation/libtraceevent-field_read.txt @@ -0,0 +1,81 @@ +libtraceevent(3) +================ + +NAME +---- +tep_read_number_field - Reads a number from raw data. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +int *tep_read_number_field*(struct tep_format_field pass:[*]_field_, const void pass:[*]_data_, unsigned long long pass:[*]_value_); +-- + +DESCRIPTION +----------- +The *tep_read_number_field()* function reads the value of the _field_ from the +raw _data_ and stores it in the _value_. The function sets the _value_ according +to the endianness of the raw data and the current machine and stores it in +_value_. + +RETURN VALUE +------------ +The *tep_read_number_field()* function retunrs 0 in case of success, or -1 in +case of an error. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... +struct tep_event *event = tep_find_event_by_name(tep, "timer", "hrtimer_start"); +... +void process_record(struct tep_record *record) +{ + unsigned long long pid; + struct tep_format_field *field_pid = tep_find_common_field(event, "common_pid"); + + if (tep_read_number_field(field_pid, record->data, &pid) != 0) { + /* Failed to get "common_pid" value */ + } +} +... +-- +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-fields.txt b/Documentation/libtraceevent-fields.txt new file mode 100644 index 0000000..99b302f --- /dev/null +++ b/Documentation/libtraceevent-fields.txt @@ -0,0 +1,105 @@ +libtraceevent(3) +================ + +NAME +---- +tep_event_common_fields, tep_event_fields - Get a list of fields for an event. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +struct tep_format_field pass:[*]pass:[*]*tep_event_common_fields*(struct tep_event pass:[*]_event_); +struct tep_format_field pass:[*]pass:[*]*tep_event_fields*(struct tep_event pass:[*]_event_); +-- + +DESCRIPTION +----------- +The *tep_event_common_fields()* function returns an array of pointers to common +fields for the _event_. The array is allocated in the function and must be freed +by free(). The last element of the array is NULL. + +The *tep_event_fields()* function returns an array of pointers to event specific +fields for the _event_. The array is allocated in the function and must be freed +by free(). The last element of the array is NULL. + +RETURN VALUE +------------ +Both *tep_event_common_fields()* and *tep_event_fields()* functions return +an array of pointers to tep_format_field structures in case of success, or +NULL in case of an error. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... +int i; +struct tep_format_field **fields; +struct tep_event *event = tep_find_event_by_name(tep, "kvm", "kvm_exit"); +if (event != NULL) { + fields = tep_event_common_fields(event); + if (fields != NULL) { + i = 0; + while (fields[i]) { + /* + walk through the list of the common fields + of the kvm_exit event + */ + i++; + } + free(fields); + } + fields = tep_event_fields(event); + if (fields != NULL) { + i = 0; + while (fields[i]) { + /* + walk through the list of the event specific + fields of the kvm_exit event + */ + i++; + } + free(fields); + } +} +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-file_endian.txt b/Documentation/libtraceevent-file_endian.txt new file mode 100644 index 0000000..4d13227 --- /dev/null +++ b/Documentation/libtraceevent-file_endian.txt @@ -0,0 +1,91 @@ +libtraceevent(3) +================ + +NAME +---- +tep_is_file_bigendian, tep_set_file_bigendian - Get / set the endianness of the +raw data being accessed by the tep handler. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +enum *tep_endian* { + TEP_LITTLE_ENDIAN = 0, + TEP_BIG_ENDIAN +}; + +bool *tep_is_file_bigendian*(struct tep_handle pass:[*]_tep_); +void *tep_set_file_bigendian*(struct tep_handle pass:[*]_tep_, enum tep_endian _endian_); + +-- +DESCRIPTION +----------- +The *tep_is_file_bigendian()* function gets the endianness of the raw data, +being accessed by the tep handler. The _tep_ argument is trace event parser +context. + +The *tep_set_file_bigendian()* function sets the endianness of raw data being +accessed by the tep handler. The _tep_ argument is trace event parser context. +[verse] +-- +The _endian_ argument is the endianness: + _TEP_LITTLE_ENDIAN_ - the raw data is in little endian format, + _TEP_BIG_ENDIAN_ - the raw data is in big endian format. +-- +RETURN VALUE +------------ +The *tep_is_file_bigendian()* function returns true if the data is in bigendian +format, false otherwise. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... + tep_set_file_bigendian(tep, TEP_LITTLE_ENDIAN); +... + if (tep_is_file_bigendian(tep)) { + /* The raw data is in big endian */ + } else { + /* The raw data is in little endian */ + } +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-filter.txt b/Documentation/libtraceevent-filter.txt new file mode 100644 index 0000000..f3eacf6 --- /dev/null +++ b/Documentation/libtraceevent-filter.txt @@ -0,0 +1,209 @@ +libtraceevent(3) +================ + +NAME +---- +tep_filter_alloc, tep_filter_free, tep_filter_reset, tep_filter_make_string, +tep_filter_copy, tep_filter_compare, tep_filter_match, tep_event_filtered, +tep_filter_remove_event, tep_filter_strerror, tep_filter_add_filter_str - +Event filter related APIs. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +struct tep_event_filter pass:[*]*tep_filter_alloc*(struct tep_handle pass:[*]_tep_); +void *tep_filter_free*(struct tep_event_filter pass:[*]_filter_); +void *tep_filter_reset*(struct tep_event_filter pass:[*]_filter_); +enum tep_errno *tep_filter_add_filter_str*(struct tep_event_filter pass:[*]_filter_, const char pass:[*]_filter_str_); +int *tep_event_filtered*(struct tep_event_filter pass:[*]_filter_, int _event_id_); +int *tep_filter_remove_event*(struct tep_event_filter pass:[*]_filter_, int _event_id_); +enum tep_errno *tep_filter_match*(struct tep_event_filter pass:[*]_filter_, struct tep_record pass:[*]_record_); +int *tep_filter_copy*(struct tep_event_filter pass:[*]_dest_, struct tep_event_filter pass:[*]_source_); +int *tep_filter_compare*(struct tep_event_filter pass:[*]_filter1_, struct tep_event_filter pass:[*]_filter2_); +char pass:[*]*tep_filter_make_string*(struct tep_event_filter pass:[*]_filter_, int _event_id_); +int *tep_filter_strerror*(struct tep_event_filter pass:[*]_filter_, enum tep_errno _err_, char pass:[*]buf, size_t _buflen_); +-- + +DESCRIPTION +----------- +Filters can be attached to traced events. They can be used to filter out various +events when outputting them. Each event can be filtered based on its parameters, +described in the event's format file. This set of functions can be used to +create, delete, modify and attach event filters. + +The *tep_filter_alloc()* function creates a new event filter. The _tep_ argument +is the trace event parser context. + +The *tep_filter_free()* function frees an event filter and all resources that it +had used. + +The *tep_filter_reset()* function removes all rules from an event filter and +resets it. + +The *tep_filter_add_filter_str()* function adds a new rule to the _filter_. The +_filter_str_ argument is the filter string, that contains the rule. + +The *tep_event_filtered()* function checks if the event with _event_id_ has +_filter_. + +The *tep_filter_remove_event()* function removes a _filter_ for an event with +_event_id_. + +The *tep_filter_match()* function tests if a _record_ matches given _filter_. + +The *tep_filter_copy()* function copies a _source_ filter into a _dest_ filter. + +The *tep_filter_compare()* function compares two filers - _filter1_ and _filter2_. + +The *tep_filter_make_string()* function constructs a string, displaying +the _filter_ contents for given _event_id_. + +The *tep_filter_strerror()* function copies the _filter_ error buffer into the +given _buf_ with the size _buflen_. If the error buffer is empty, in the _buf_ +is copied a string, describing the error _err_. + +RETURN VALUE +------------ +The *tep_filter_alloc()* function returns a pointer to the newly created event +filter, or NULL in case of an error. + +The *tep_filter_add_filter_str()* function returns 0 if the rule was +successfully added or a negative error code. Use *tep_filter_strerror()* to see +actual error message in case of an error. + +The *tep_event_filtered()* function returns 1 if the filter is found for given +event, or 0 otherwise. + +The *tep_filter_remove_event()* function returns 1 if the vent was removed, or +0 if the event was not found. + +The *tep_filter_match()* function returns _tep_errno_, according to the result: +[verse] +-- +_pass:[TEP_ERRNO__FILTER_MATCH]_ - filter found for event, the record matches. +_pass:[TEP_ERRNO__FILTER_MISS]_ - filter found for event, the record does not match. +_pass:[TEP_ERRNO__FILTER_NOT_FOUND]_ - no filter found for record's event. +_pass:[TEP_ERRNO__NO_FILTER]_ - no rules in the filter. +-- +or any other _tep_errno_, if an error occurred during the test. + +The *tep_filter_copy()* function returns 0 on success or -1 if not all rules + were copied. + +The *tep_filter_compare()* function returns 1 if the two filters hold the same +content, or 0 if they do not. + +The *tep_filter_make_string()* function returns a string, which must be freed +with free(), or NULL in case of an error. + +The *tep_filter_strerror()* function returns 0 if message was filled +successfully, or -1 in case of an error. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... +char errstr[200]; +int ret; + +struct tep_event_filter *filter = tep_filter_alloc(tep); +struct tep_event_filter *filter1 = tep_filter_alloc(tep); +ret = tep_filter_add_filter_str(filter, "sched/sched_wakeup:target_cpu==1"); +if(ret < 0) { + tep_filter_strerror(filter, ret, errstr, sizeof(errstr)); + /* Failed to add a new rule to the filter, the error string is in errstr */ +} +if (tep_filter_copy(filter1, filter) != 0) { + /* Failed to copy filter in filter1 */ +} +... +if (tep_filter_compare(filter, filter1) != 1) { + /* Both filters are different */ +} +... +void process_record(struct tep_handle *tep, struct tep_record *record) +{ + struct tep_event *event; + char *fstring; + + event = tep_find_event_by_record(tep, record); + + if (tep_event_filtered(filter, event->id) == 1) { + /* The event has filter */ + fstring = tep_filter_make_string(filter, event->id); + if (fstring != NULL) { + /* The filter for the event is in fstring */ + free(fstring); + } + } + + switch (tep_filter_match(filter, record)) { + case TEP_ERRNO__FILTER_MATCH: + /* The filter matches the record */ + break; + case TEP_ERRNO__FILTER_MISS: + /* The filter does not match the record */ + break; + case TEP_ERRNO__FILTER_NOT_FOUND: + /* No filter found for record's event */ + break; + case TEP_ERRNO__NO_FILTER: + /* There are no rules in the filter */ + break + default: + /* An error occurred during the test */ + break; + } + + if (tep_filter_remove_event(filter, event->id) == 1) { + /* The event was removed from the filter */ + } +} + +... +tep_filter_reset(filter); +... +tep_filter_free(filter); +tep_filter_free(filter1); +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-func_apis.txt b/Documentation/libtraceevent-func_apis.txt new file mode 100644 index 0000000..1b836a1 --- /dev/null +++ b/Documentation/libtraceevent-func_apis.txt @@ -0,0 +1,168 @@ +libtraceevent(3) +================ + +NAME +---- +tep_set_function_resolver, tep_reset_function_resolver, tep_register_function, tep_register_print_string, +tep_get_function_count - function related tep APIs + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +typedef char pass:[*](*tep_func_resolver_t*)(void pass:[*]_priv_, unsigned long long pass:[*]_addrp_, char pass:[**]_modp_); +int *tep_set_function_resolver*(struct tep_handle pass:[*]_tep_, tep_func_resolver_t pass:[*]_func_, void pass:[*]_priv_); +void *tep_reset_function_resolver*(struct tep_handle pass:[*]_tep_); +int *tep_register_function*(struct tep_handle pass:[*]_tep_, char pass:[*]_name_, unsigned long long _addr_, char pass:[*]_mod_); +int *tep_register_print_string*(struct tep_handle pass:[*]_tep_, const char pass:[*]_fmt_, unsigned long long _addr_); +int *tep_get_function_count*(struct tep_handle *_tep_) +-- + +DESCRIPTION +----------- +Some tools may have already a way to resolve the kernel functions. These APIs +allow them to keep using it instead of duplicating all the entries inside. + +The _tep_func_resolver_t_ type is the prototype of the alternative kernel +functions resolver. This function receives a pointer to its custom context +(set with the *tep_set_function_resolver()* call ) and the address of a kernel +function, which has to be resolved. In case of success, it should return +the name of the function and its module (if any) in _modp_. + +The *tep_set_function_resolver()* function registers _func_ as an alternative +kernel functions resolver. The _tep_ argument is trace event parser context. +The _priv_ argument is a custom context of the _func_ function. The function +resolver is used by the APIs *tep_find_function*(3), +*tep_find_function_address*(3), and *tep_print_func_field()* to resolve +a function address to a function name. + +The *tep_reset_function_resolver()* function resets the kernel functions +resolver to the default function. The _tep_ argument is trace event parser +context. + + +These APIs can be used to find function name and start address, by given +address. The given address does not have to be exact, it will select +the function that would contain it. + +The *tep_register_function()* function registers a function name mapped to an +address and (optional) module. This mapping is used in case the function tracer +or events have "%pS" parameter in its format string. It is common to pass in +the kallsyms function names with their corresponding addresses with this +function. The _tep_ argument is the trace event parser context. The _name_ is +the name of the function, the string is copied internally. The _addr_ is the +start address of the function. The _mod_ is the kernel module the function may +be in (NULL for none). + +The *tep_register_print_string()* function registers a string by the address +it was stored in the kernel. Some strings internal to the kernel with static +address are passed to certain events. The "%s" in the event's format field +which has an address needs to know what string would be at that address. The +tep_register_print_string() supplies the parsing with the mapping between kernel +addresses and those strings. The _tep_ argument is the trace event parser +context. The _fmt_ is the string to register, it is copied internally. +The _addr_ is the address the string was located at. + +*tep_get_function_count*() returns the number of registered functions in a tep handler. + +RETURN VALUE +------------ +The *tep_set_function_resolver()* function returns 0 in case of success, or -1 +in case of an error. + +The *tep_register_function()* function returns 0 in case of success. In case of +an error -1 is returned, and errno is set to the appropriate error number. + +The *tep_register_print_string()* function returns 0 in case of success. In case +of an error -1 is returned, and errno is set to the appropriate error number. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... +char *my_resolve_kernel_addr(void *context, + unsigned long long *addrp, char **modp) +{ + struct db *function_database = context; + struct symbol *sym = sql_lookup(function_database, *addrp); + + if (!sym) + return NULL; + + *modp = sym->module_name; + return sym->name; +} + +void show_function( unsigned long long addr) +{ + unsigned long long fstart; + const char *fname; + + if (tep_set_function_resolver(tep, my_resolve_kernel_addr, + function_database) != 0) { + /* failed to register my_resolve_kernel_addr */ + } + + /* These APIs use my_resolve_kernel_addr() to resolve the addr */ + fname = tep_find_function(tep, addr); + fstart = tep_find_function_address(tep, addr); + + /* + addr is in function named fname, starting at fstart address, + at offset (addr - fstart) + */ + + tep_reset_function_resolver(tep); + +} +... + if (tep_register_function(tep, "kvm_exit", + (unsigned long long) 0x12345678, "kvm") != 0) { + /* Failed to register kvm_exit address mapping */ + } +... + if (tep_register_print_string(tep, "print string", + (unsigned long long) 0x87654321, NULL) != 0) { + /* Failed to register "print string" address mapping */ + } +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-func_find.txt b/Documentation/libtraceevent-func_find.txt new file mode 100644 index 0000000..26fac68 --- /dev/null +++ b/Documentation/libtraceevent-func_find.txt @@ -0,0 +1,131 @@ +libtraceevent(3) +================ + +NAME +---- +tep_find_function,tep_find_function_address,tep_find_function_info - Find function name / start address. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +const char pass:[*]*tep_find_function*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); +unsigned long long *tep_find_function_address*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); +int *tep_find_function_info*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_, const char pass:[**]_name_, + unsigned long long pass:[*]_start_, unsigned long pass:[*]_size_); +-- + +DESCRIPTION +----------- +These functions can be used to find function name and start address, by given +address. The given address does not have to be exact, it will select the function +that would contain it. + +The *tep_find_function()* function returns the function name, which contains the +given address _addr_. The _tep_ argument is the trace event parser context. + +The *tep_find_function_address()* function returns the function start address, +by given address _addr_. The _addr_ does not have to be exact, it will select the +function that would contain it. The _tep_ argument is the trace event parser context. + +The *tep_find_function_info()* function retrieves the _name_, starting address (_start_), +and the function text _size_ of the function at _address_, if it is found. Note, +if the _tep_ handle has a function resolver (used by perf), then _size_ is set to +zero. + +RETURN VALUE +------------ +The *tep_find_function()* function returns the function name, or NULL in case +it cannot be found. + +The *tep_find_function_address()* function returns the function start address, +or 0 in case it cannot be found. + +The *tep_find_function_info()* function returns 1 if a function is found for the +given address, or 0 if it is not. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... +void show_function_name(unsigned long long addr) +{ + const char *fname = tep_find_function(tep, addr); + + if (fname) + printf("Found function %s at 0x%0llx\n", fname, addr); + else + printf("No function found at 0x%0llx\n", addr); +} + +void show_function_start_addr(unsigned long long addr) +{ + const char *fname = tep_find_function(tep, addr); + unsigned long long fstart; + + if (!fname) { + printf("No function found at 0x%0llx\n", addr); + return; + } + + fstart = tep_find_function_address(tep, addr); + printf("Function %s at 0x%llx starts at 0x%0llx\n", + fname, addr, fstart); +} + +void show_function_info(unsigned long long addr) +{ + const char *fname; + unsigned long long fstart; + unsigned long size; + + ret = tep_find_function_info(tep, addr, &fname, &fstart, &size); + if (!ret) { + printf("No function found at 0x%0lx\n", addr); + return; + } + + printf("Function %s at 0x%lx starts at 0x%0lx and is %ld in size\n", + fname, addr, fstart, size); +} +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-handle.txt b/Documentation/libtraceevent-handle.txt new file mode 100644 index 0000000..64528eb --- /dev/null +++ b/Documentation/libtraceevent-handle.txt @@ -0,0 +1,108 @@ +libtraceevent(3) +================ + +NAME +---- +tep_alloc, tep_free,tep_ref, tep_unref,tep_get_ref, tep_kbuffer - Create, destroy, manage +references of trace event parser context. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +struct tep_handle pass:[*]*tep_alloc*(void); +void *tep_free*(struct tep_handle pass:[*]_tep_); +void *tep_ref*(struct tep_handle pass:[*]_tep_); +void *tep_unref*(struct tep_handle pass:[*]_tep_); +int *tep_get_ref*(struct tep_handle pass:[*]_tep_); +-- + +DESCRIPTION +----------- +These are the main functions to create and destroy tep_handle - the main +structure, representing the trace event parser context. This context is used as +the input parameter of most library APIs. + +The *tep_alloc()* function allocates and initializes the tep context. + +The *tep_free()* function will decrement the reference of the _tep_ handler. +When there is no more references, then it will free the handler, as well +as clean up all its resources that it had used. The argument _tep_ is +the pointer to the trace event parser context. + +The *tep_ref()* function adds a reference to the _tep_ handler. + +The *tep_unref()* function removes a reference from the _tep_ handler. When +the last reference is removed, the _tep_ is destroyed, and all resources that +it had used are cleaned up. + +The *tep_ref_get()* functions gets the current references of the _tep_ handler. + +The *tep_kbuffer()* function allocates a kbuffer descriptor that can be used to +parse raw data that is represented by the _tep_ handle descriptor. It must be freed +with *kbuf_free(3)*. + +RETURN VALUE +------------ +*tep_alloc()* returns a pointer to a newly created tep_handle structure. +NULL is returned in case there is not enough free memory to allocate it. + +*tep_ref_get()* returns the current references of _tep_. +If _tep_ is NULL, 0 is returned. + +*tep_kbuffer()* returns a kbuffer descriptor that can parse the raw data that +represents the tep handle. Must be freed with *kbuf_free(3)*. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> + +... +struct tep_handle *tep = tep_alloc(); +... +int ref = tep_get_ref(tep); +tep_ref(tep); +if ( (ref+1) != tep_get_ref(tep)) { + /* Something wrong happened, the counter is not incremented by 1 */ +} +tep_unref(tep); +... +tep_free(tep); +... +-- +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-header_page.txt b/Documentation/libtraceevent-header_page.txt new file mode 100644 index 0000000..31b66e0 --- /dev/null +++ b/Documentation/libtraceevent-header_page.txt @@ -0,0 +1,102 @@ +libtraceevent(3) +================ + +NAME +---- +tep_get_header_page_size, tep_get_header_timestamp_size, tep_is_old_format - +Get the data stored in the header page, in kernel context. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +int *tep_get_header_page_size*(struct tep_handle pass:[*]_tep_); +int *tep_get_header_timestamp_size*(struct tep_handle pass:[*]_tep_); +bool *tep_is_old_format*(struct tep_handle pass:[*]_tep_); +-- +DESCRIPTION +----------- +These functions retrieve information from kernel context, stored in tracefs +events/header_page. Old kernels do not have header page info, so default values +from user space context are used. + +The *tep_get_header_page_size()* function returns the size of a long integer, +in kernel context. The _tep_ argument is trace event parser context. +This information is retrieved from tracefs events/header_page, "commit" field. + +The *tep_get_header_timestamp_size()* function returns the size of timestamps, +in kernel context. The _tep_ argument is trace event parser context. This +information is retrieved from tracefs events/header_page, "timestamp" field. + +The *tep_is_old_format()* function returns true if the kernel predates +the addition of events/header_page, otherwise it returns false. + +RETURN VALUE +------------ +The *tep_get_header_page_size()* function returns the size of a long integer, +in bytes. + +The *tep_get_header_timestamp_size()* function returns the size of timestamps, +in bytes. + +The *tep_is_old_format()* function returns true, if an old kernel is used to +generate the tracing data, which has no event/header_page. If the kernel is new, +or _tep_ is NULL, false is returned. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... + int longsize; + int timesize; + bool old; + + longsize = tep_get_header_page_size(tep); + timesize = tep_get_header_timestamp_size(tep); + old = tep_is_old_format(tep); + + printf ("%s kernel is used to generate the tracing data.\n", + old?"Old":"New"); + printf("The size of a long integer is %d bytes.\n", longsize); + printf("The timestamps size is %d bytes.\n", timesize); +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-host_endian.txt b/Documentation/libtraceevent-host_endian.txt new file mode 100644 index 0000000..76d309a --- /dev/null +++ b/Documentation/libtraceevent-host_endian.txt @@ -0,0 +1,104 @@ +libtraceevent(3) +================ + +NAME +---- +tep_is_bigendian, tep_is_local_bigendian, tep_set_local_bigendian - Get / set +the endianness of the local machine. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +enum *tep_endian* { + TEP_LITTLE_ENDIAN = 0, + TEP_BIG_ENDIAN +}; + +int *tep_is_bigendian*(void); +bool *tep_is_local_bigendian*(struct tep_handle pass:[*]_tep_); +void *tep_set_local_bigendian*(struct tep_handle pass:[*]_tep_, enum tep_endian _endian_); +-- + +DESCRIPTION +----------- + +The *tep_is_bigendian()* gets the endianness of the machine, executing +the function. + +The *tep_is_local_bigendian()* function gets the endianness of the local +machine, saved in the _tep_ handler. The _tep_ argument is the trace event +parser context. This API is a bit faster than *tep_is_bigendian()*, as it +returns cached endianness of the local machine instead of checking it each time. + +The *tep_set_local_bigendian()* function sets the endianness of the local +machine in the _tep_ handler. The _tep_ argument is trace event parser context. +The _endian_ argument is the endianness: +[verse] +-- + _TEP_LITTLE_ENDIAN_ - the machine is little endian, + _TEP_BIG_ENDIAN_ - the machine is big endian. +-- + +RETURN VALUE +------------ +The *tep_is_bigendian()* function returns non zero if the endianness of the +machine, executing the code, is big endian and zero otherwise. + +The *tep_is_local_bigendian()* function returns true, if the endianness of the +local machine, saved in the _tep_ handler, is big endian, or false otherwise. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... + if (tep_is_bigendian()) + tep_set_local_bigendian(tep, TEP_BIG_ENDIAN); + else + tep_set_local_bigendian(tep, TEP_LITTLE_ENDIAN); +... + if (tep_is_local_bigendian(tep)) + printf("This machine you are running on is bigendian\n"); + else + printf("This machine you are running on is little endian\n"); + +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-kbuffer-create.txt b/Documentation/libtraceevent-kbuffer-create.txt new file mode 100644 index 0000000..12e5d6c --- /dev/null +++ b/Documentation/libtraceevent-kbuffer-create.txt @@ -0,0 +1,207 @@ +libtraceevent(3) +================ + +NAME +---- +kbuffer_alloc, kbuffer_free, kbuffer_load_subbuffer, kbuffer_subbuffer_size, kbuffer_start_of_data - Creating of kbuffer element to parse +the Linux kernel tracing ring buffer + +SYNOPSIS +-------- +[verse] +-- +*#include <kbuffer.h>* + +enum kbuffer_endian { + KBUFFER_ENDIAN_BIG, + KBUFFER_ENDIAN_LITTLE, + KBUFFER_ENDIAN_SAME_AS_HOST, +}; + +enum kbuffer_long_size { + KBUFFER_LSIZE_4, + KBUFFER_LSIZE_8, + KBUFFER_LSIZE_SAME_AS_HOST, +}; + +struct kbuffer; +struct tep_handle; + +struct kbuffer pass:[*]*kbuffer_alloc*(enum kbuffer_long_size _size_, enum kbuffer_endian _endian_); +void *kbuffer_free*(struct kbuffer pass:[*]_kbuf_); +int *kbuffer_load_subbuffer*(struct kbuffer pass:[*]_kbuf_, void pass:[*]_subbuffer_); +int *kbuffer_subbuffer_size*(struct kbuffer pass:[*]_kbuf); +int *kbuffer_start_of_data*(struct kbuffer pass:[*]_kbuf_); +-- + +DESCRIPTION +----------- +These functions create a _kbuffer_ handle that can be used to parse the raw sub buffers +of the Linux kernel tracing ring buffer. The ring buffer is found in the tracefs +directory, and can be retrieved by *tracefs_instance_get_file(3)* at +*per_cpu/cpuX/trace_pipe_raw* where *X* is replaced by the per CPU number of +the specified ring buffer. The ring buffer inside the kernel is split up per +CPU, such that the raw ring buffer must be retrieved per CPU as well. + +The *kbuffer_alloc()* will create a descriptor that can be used to manage a sub buffer +read by the ring buffer. The _size_ parameter denotes what the word size is +for the given buffer (note, this works from reading raw data from machines other +than the machine that is calling this function). The _endian_ denotes the endian +for the machine. + +If _endian_ is set to _KBUFFER_ENDIAN_SAME_AS_HOST_ the endian will be set to the same +as the host endianess, which is useful when the application is reading the +ring buffer data directly from the same machine it is running on. + +If _size_ is set to _KBUFFER_LSIZE_SAME_AS_HOST_, if the word size is 8, it will +set the kbuffer descriptor to long size of 8. But if the size is 4, then it +will then perform a *uname(2)* call, and if the _machine_ field has the string "64" +in it, it will be set to 8 byte long size and not 4 byte. This is because the +ring buffer long size is dependent on the kernel and not user space. + +The *kbuffer_free()* function will free the resources created by *kbuffer_alloc()*. + +The *kbuffer_load_subbuffer()* will take a _subbuffer_ which is a raw data blob +from the tracefs *trace_pipe_raw* file. The Linux tracing ring buffer is broken up +into sub buffers. Each sub buffer is as stand alone data segment that has all the +information to split out the individual events and time stamps. This sub buffer +is what kbuffer uses to walk the events. + +The *kbuffer_subbuffer_size()* returns the location of the end of the last event +on the sub-buffer. It does not return the size of the sub-buffer itself. + +The *kbuffer_start_of_data()* function returns the offset of where the actual +data load of the sub-buffer begins. + +RETURN VALUE +------------ +*kbuffer_alloc()* returns an allocated kbuffer descriptor or NULL on error. +The returned descriptor must be freed with *kbuffer_free()* + +*kbuffer_load_subbuffer()* returns 0 on success and -1 on error. + +*kbuffer_subbuffer_size()* returns the index on the subbuffer where the end +of the last event is located. + +*kbuffer_start_of_data()* returns the offset of where the data begins on the +sub-buffer loaded in _kbuf_. + +EXAMPLE +------- +[source,c] +-- +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/stat.h> + +#include <kbuffer.h> + +int main (int argc, char **argv) +{ + unsigned long long ts; + struct kbuffer *kbuf; + struct stat st; + char *buf; + void *event; + int ret; + int fd; + int i = 0; + + if (argc < 2) { + printf("usage: %s raw-subbuffer-page\n", argv[0]); + printf(" Try: dd count=1 bs=4096 if=/sys/kernel/tracing/per_cpu/cpu0/trace_pipe_raw of=/tmp/file\n"); + exit(0); + } + + if (stat(argv[1], &st) < 0) { + perror("stat"); + exit(-1); + } + + buf = malloc(st.st_size); + if (!buf) { + perror("Allocating buffer"); + exit(-1); + } + + fd = open(argv[1], O_RDONLY); + if (fd < 0) { + perror(argv[1]); + exit(-1); + } + + ret = read(fd, buf, st.st_size); + if (ret < 0) { + perror("Reading buffer"); + exit(-1); + } + close(fd); + + kbuf = kbuffer_alloc(KBUFFER_ENDIAN_SAME_AS_HOST, + KBUFFER_LSIZE_SAME_AS_HOST); + if (!kbuf) { + perror("Creating kbuffer"); + exit(-1); + } + ret = kbuffer_load_subbuffer(kbuf, buf); + if (ret < 0) { + perror("Loading sub bufer"); + exit(-1); + } + + if (kbuffer_subbuffer_size(kbuf) > st.st_size) { + fprintf(stderr, "kbuffer is bigger than raw size %d > %ld\n", + kbuffer_subbuffer_size(kbuf), st.st_size); + exit(-1); + } + + printf("Kbuffer data starts at %d\n", kbuffer_start_of_data(kbuf)); + do { + event = kbuffer_read_event(kbuf, &ts); + if (event) { + printf(" event %3d ts:%lld\n", i++, ts); + event = kbuffer_next_event(kbuf, NULL); + } + } while (event); + + if (!event) + printf("Finished sub buffer\n"); + + kbuffer_free(kbuf); + + return 0; +} +-- +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-kbuffer-read.txt b/Documentation/libtraceevent-kbuffer-read.txt new file mode 100644 index 0000000..68184ad --- /dev/null +++ b/Documentation/libtraceevent-kbuffer-read.txt @@ -0,0 +1,246 @@ +libtraceevent(3) +================ + +NAME +---- +kbuffer_read_event, kbuffer_next_event, kbuffer_missed_events, kbuffer_event_size, kbuffer_curr_size, +kbuffer_curr_offset, kbuffer_curr_index - +Functions to read through the kbuffer sub buffer. + +SYNOPSIS +-------- +[verse] +-- +*#include <kbuffer.h>* + +void pass:[*]*kbuffer_read_event*(struct kbuffer pass:[*]_kbuf_, unsigned long long pass:[*]_ts_); +void pass:[*]*kbuffer_next_event*(struct kbuffer pass:[*]_kbuf_, unsigned long long pass:[*]_ts_); +void pass:[*]*kbuffer_read_at_offset*(struct kbuffer pass:[*]_kbuf_, int _offset_, unsigned long long pass:[*]_ts_); +int *kbuffer_missed_events*(struct kbuffer pass:[*]_kbuf_); +int *kbuffer_event_size*(struct kbuffer pass:[*]_kbuf_); +int *kbuffer_curr_size*(struct kbuffer pass:[*]_kbuf_); +int *kbuffer_curr_offset*(struct kbuffer pass:[*]_kbuf_); +int *kbuffer_curr_index*(struct kbuffer pass:[*]_kbuf_); +-- + +DESCRIPTION +----------- +The function *kbuffer_read_event()* reads the next event in the _kbuf_ descriptor +and if _ts_ is non NULL, will place its timestamp into it. This does not modify the _kbuf_ +descriptor, and calling this function mulitple times will return the same result. + +The function *kbuffer_next_event()* will return the next event in the _kbuf_ descriptor. +It will also set the _ts_ to the timestamp of the returned event. NULL is returned +if there are no more events and _ts_ will be undefined. Note, if this is called directly +after a *kbuffer_load_subbuffer()* then it will likely give an unexpected result, as it +will return the second event and not the first event. Usually this function is only used +to move to the next event and to know if there's any more events to read, and +*kbuffer_read_event()* is always called first. + +The function *kbuffer_read_at_offset()* returns the event located at a given _offset_ from +the beginning of the sub-buffer. This offset can be retrieved by *kbuffer_curr_offset()*. +If _ts_ points to an unsigned long long, then it will be set to the event at the given +offset's timestamp. + +If the sub-buffer had missed events before it, then *kbuffer_missed_events()* will return +the non zero. If it returns -1, that means there were missed events, but the exact number +of missed events is unknown. If it returns a positive number, then the number of missed events +is the return value. + +The *kbuffer_event_size()* function returns the size of the data portion of the current event +(the one that would be returned by *kbuffer_read_event()*. + +The *kbuffer_curr_size()* function returns the entire record size of the current event +(the one that would be returned by *kbuffer_read_event()*. The difference here is that the +return value includes the size of the event record meta data that is not part of what +is returned by *kbuffer_read_event()*. + +The *kbuffer_curr_offset()* function returns the offset from the beginning of the sub-buffer +of where the current event's meta data for the record begins. The first event will +not be at offset zero. This offset can be used to retrieve the event with +*kbuffer_read_at_offset()*. + +The *kbuffer_curr_index()* function returns the index from the beginning of the data +portion of the sub-buffer where the current evnet's meta data is located. +The first event will likely be zero, but may not be if there's a timestamp attached to it. + +RETURN VALUE +------------ +*kbuffer_read_event()* returns the event that the _kbuf_ descriptor is currently at, +or NULL if the last event was passed (by *kbuffer_next_event()*). + +*kbuffer_next_event()* returns the next event after the current event or NULL if there +are no more events. + +*kbuffer_read_at_offset()* returns the event at a given _offset_ from the start of +the sub-buffer stored in _kbuf_, or NULL if there exists no event. Note, _offset_ +only needs to be an offset that lands on the record, or is at the start of it. It does +not need to be exactly at the beginning of the record. + +*kbuffer_missed_events()* returns 0 if there were no missed events before loaded sub-buffer. +Returns -1 if there were an unknown number of missed events, or if the number of missed events +is known, that number will be returned. + +*kbuffer_event_size()* returns the size of the data payload of the current event of _kbuf_. + +*kbuffer_curr_size()* returns the size of the entire record of the current event of _kbuf_. +This includes the size of the meta data for that record. + +*kbuf_curr_offset()* returns the offset of the current record from the beginning of the _kbuf_ +sub-buffer. + +*kbuf_curr_index()* returns the index of the current record from the beginning of the _kbuf_ +data section. + +EXAMPLE +------- +[source,c] +-- +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/stat.h> + +#include <kbuffer.h> + +int main (int argc, char **argv) +{ + unsigned long long ts; + struct kbuffer *kbuf; + struct stat st; + char *buf; + void *event; + int save_offset = -1; + int record_size; + int offset; + int index; + int size; + int ret; + int fd; + int i = 0; + + if (argc < 2) { + printf("usage: %s raw-subbuffer-page\n", argv[0]); + printf(" Try: dd count=1 bs=4096 if=/sys/kernel/tracing/per_cpu/cpu0/trace_pipe_raw of=/tmp/file\n"); + exit(0); + } + + if (stat(argv[1], &st) < 0) { + perror("stat"); + exit(-1); + } + + buf = malloc(st.st_size); + if (!buf) { + perror("Allocating buffer"); + exit(-1); + } + + fd = open(argv[1], O_RDONLY); + if (fd < 0) { + perror(argv[1]); + exit(-1); + } + + ret = read(fd, buf, st.st_size); + if (ret < 0) { + perror("Reading buffer"); + exit(-1); + } + close(fd); + + kbuf = kbuffer_alloc(KBUFFER_ENDIAN_SAME_AS_HOST, + KBUFFER_LSIZE_SAME_AS_HOST); + if (!kbuf) { + perror("Creating kbuffer"); + exit(-1); + } + ret = kbuffer_load_subbuffer(kbuf, buf); + if (ret < 0) { + perror("Loading sub bufer"); + exit(-1); + } + + if (kbuffer_subbuffer_size(kbuf) > st.st_size) { + fprintf(stderr, "kbuffer is bigger than raw size %d > %ld\n", + kbuffer_subbuffer_size(kbuf), st.st_size); + exit(-1); + } + + ret = kbuffer_missed_events(kbuf); + if (ret) { + if (ret > 0) + printf("Missed %d events before this buffer\n", ret); + else + printf("Missed unknown number of events before this buffer\n"); + } + do { + event = kbuffer_read_event(kbuf, &ts); + if (event) { + record_size = kbuffer_curr_size(kbuf); + offset = kbuffer_curr_offset(kbuf); + index = kbuffer_curr_index(kbuf); + size = kbuffer_event_size(kbuf); + + if (i == 20) + save_offset = offset; + printf(" event %3d ts:%lld\trecord_size:%d size:%d\tindex:%d offset:%d\n", + i++, ts, record_size, size, index, offset); + event = kbuffer_next_event(kbuf, NULL); + } + } while (event); + + if (!event) + printf("Finished sub buffer\n"); + + if (save_offset > 0) { + event = kbuffer_read_at_offset(kbuf, save_offset, &ts); + if (!event) { + fprintf(stderr, "Funny, can't find event 20 at offset %d\n", save_offset); + exit(-1); + } + record_size = kbuffer_curr_size(kbuf); + offset = kbuffer_curr_offset(kbuf); + index = kbuffer_curr_index(kbuf); + size = kbuffer_event_size(kbuf); + + printf("\n saved event 20 ts:%lld\trecord_size:%d size:%d\tindex:%d offset:%d\n\n", + ts, record_size, size, index, offset); + } + kbuffer_free(kbuf); + + return 0; +} +-- +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-kbuffer-timestamp.txt b/Documentation/libtraceevent-kbuffer-timestamp.txt new file mode 100644 index 0000000..d7de225 --- /dev/null +++ b/Documentation/libtraceevent-kbuffer-timestamp.txt @@ -0,0 +1,208 @@ +libtraceevent(3) +================ + +NAME +---- +kbuffer_timestamp, kbuffer_subbuf_timestamp - +Functions that read various data of a kbuffer descriptor + +SYNOPSIS +-------- +[verse] +-- +*#include <kbuffer.h>* + +unsigned long long *kbuffer_timestamp*(struct kbuffer pass:[*]_kbuf_); +unsigned long long *kbuffer_subbuf_timestamp*(struct kbuffer pass:[*]_kbuf_, void pass:[*]_subbuf_); +-- + +DESCRIPTION +----------- +The function *kbuffer_timestamp()* returns the timestamp of the current event of _kbuf_. + +The function *kbuffer_subbuf_timestamp()* returns the timestamp for the sub-buffer +that was loaded in _kbuf_. This usually is (but not guaranteed to be) the timestamp +of the first event on the sub-buffer. + +The function *kbuffer_start_of_data()* returns the offset of where the delta + +RETURN VALUE +------------ +*kbuffer_read_event()* returns the event that the _kbuf_ descriptor is currently at, +or NULL if the last event was passed (by *kbuffer_next_event()*). + +*kbuffer_next_event()* returns the next event after the current event or NULL if there +are no more events. + +*kbuffer_read_at_offset()* returns the event at a given _offset_ from the start of +the sub-buffer stored in _kbuf_, or NULL if there exists no event. Note, _offset_ +only needs to be an offset that lands on the record, or is at the start of it. It does +not need to be exactly at the beginning of the record. + +*kbuffer_missed_events()* returns 0 if there were no missed events before loaded sub-buffer. +Returns -1 if there were an unknown number of missed events, or if the number of missed events +is known, that number will be returned. + +*kbuffer_event_size()* returns the size of the data payload of the current event of _kbuf_. + +*kbuffer_curr_size()* returns the size of the entire record of the current event of _kbuf_. +This includes the size of the meta data for that record. + +*kbuf_curr_offset()* returns the offset of the current record from the beginning of the _kbuf_ +sub-buffer. + +*kbuf_curr_index()* returns the index of the current record from the beginning of the _kbuf_ +data section. + +EXAMPLE +------- +[source,c] +-- +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/stat.h> + +#include <kbuffer.h> + +int main (int argc, char **argv) +{ + unsigned long long ts; + struct kbuffer *kbuf; + struct stat st; + char *buf; + void *event; + int save_offset = -1; + int record_size; + int offset; + int index; + int size; + int ret; + int fd; + int i = 0; + + if (argc < 2) { + printf("usage: %s raw-subbuffer-page\n", argv[0]); + printf(" Try: dd count=1 bs=4096 if=/sys/kernel/tracing/per_cpu/cpu0/trace_pipe_raw of=/tmp/file\n"); + exit(0); + } + + if (stat(argv[1], &st) < 0) { + perror("stat"); + exit(-1); + } + + buf = malloc(st.st_size); + if (!buf) { + perror("Allocating buffer"); + exit(-1); + } + + fd = open(argv[1], O_RDONLY); + if (fd < 0) { + perror(argv[1]); + exit(-1); + } + + ret = read(fd, buf, st.st_size); + if (ret < 0) { + perror("Reading buffer"); + exit(-1); + } + close(fd); + + kbuf = kbuffer_alloc(KBUFFER_ENDIAN_SAME_AS_HOST, + KBUFFER_LSIZE_SAME_AS_HOST); + if (!kbuf) { + perror("Creating kbuffer"); + exit(-1); + } + ret = kbuffer_load_subbuffer(kbuf, buf); + if (ret < 0) { + perror("Loading sub bufer"); + exit(-1); + } + + if (kbuffer_subbuffer_size(kbuf) > st.st_size) { + fprintf(stderr, "kbuffer is bigger than raw size %d > %ld\n", + kbuffer_subbuffer_size(kbuf), st.st_size); + exit(-1); + } + + ret = kbuffer_missed_events(kbuf); + if (ret) { + if (ret > 0) + printf("Missed %d events before this buffer\n", ret); + else + printf("Missed unknown number of events before this buffer\n"); + } + do { + event = kbuffer_read_event(kbuf, &ts); + if (event) { + record_size = kbuffer_curr_size(kbuf); + offset = kbuffer_curr_offset(kbuf); + index = kbuffer_curr_index(kbuf); + size = kbuffer_event_size(kbuf); + + if (i == 20) + save_offset = offset; + printf(" event %3d ts:%lld\trecord_size:%d size:%d\tindex:%d offset:%d\n", + i++, ts, record_size, size, index, offset); + event = kbuffer_next_event(kbuf, NULL); + } + } while (event); + + if (!event) + printf("Finished sub buffer\n"); + + if (save_offset > 0) { + event = kbuffer_read_at_offset(kbuf, save_offset, &ts); + if (!event) { + fprintf(stderr, "Funny, can't find event 20 at offset %d\n", save_offset); + exit(-1); + } + record_size = kbuffer_curr_size(kbuf); + offset = kbuffer_curr_offset(kbuf); + index = kbuffer_curr_index(kbuf); + size = kbuffer_event_size(kbuf); + + printf("\n saved event 20 ts:%lld\trecord_size:%d size:%d\tindex:%d offset:%d\n\n", + ts, record_size, size, index, offset); + } + kbuffer_free(kbuf); + + return 0; +} +-- +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-kvm-plugin.txt b/Documentation/libtraceevent-kvm-plugin.txt new file mode 100644 index 0000000..a02e786 --- /dev/null +++ b/Documentation/libtraceevent-kvm-plugin.txt @@ -0,0 +1,252 @@ +libtraceevent(3) +================ + +NAME +---- +tep_plugin_kvm_get_func, tep_plugin_kvm_put_func - Add function name for instruction pointer of kvm plugin + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +const char pass:[*]*tep_plugin_kvm_get_func*(struct tep_event pass:[*]event, + struct tep_record pass:[*]record, + unsigned long long pass:[*]paddr); +void *tep_plugin_kvm_put_func*(const char pass:[*]func); +-- + +DESCRIPTION +----------- +The functions *tep_plugin_kvm_get_func()* and *tep_plugin_kvm_put_func()* +are not to be called by an application, but instead are to be defined by +an application. + +Certain events (like kvm_exit and kvm_entry) have the instruction pointer +of where in the guest the context changed from guest to host. As the host +only knows the instruction pointer and does not have information about what +function in the guest that instruction pointer belongs to, it can only print +the address. + +But the application may have more information about the guest, and know where +the guest was when the exit occurred, and also even know the function name +of that address. + +The KVM plugin for libtraceevent is called on these events, and then calls +*tep_plugin_kvm_get_func()* to see if that function can resolve the instruction +pointer address to a real function name. If the return is non NULL, it will +print the function in the output for that event. + +These functions are currently defined as weak functions within the plugin, as +to not require them to be defined elsewhere. For an application to override +the weak function, it will need to define the function in a file that gets +compiled with *-rdynamic*. That will tell the dynamic linker to examine that +object file and use function names to resolve weak functions in other shared +objects (in this case the KVM plugin shared object). + +If the application defines *tep_plugin_kvm_get_func()*, it must use the above +prototype. The _event_ will hold the KVM event that has the instruction pointer +field. The _record_ will be the instance of that event. The application's function +does not need to use these parameters, but they may be useful for finding the +function name for the address. The _paddr_ is a pointer to a 64 bit value (where +only 32 bits may be used on 32 bit machines). This value is the instruction +pointer to look up. If the application knows the start address of the function +as well, it can set _paddr_ to that address, and the KVM plugin will also +append a "+offset" to the function name where the offset is the original +value in _paddr_ minus the value in _paddr_ when it is called. Finally, +the application should return the function name as a nul terminated string +if one is found. + +If the returned string of *tep_plugin_kvm_get_func()* was allocated, the KVM plugin +will call *tep_plugin_kvm_put_func()* when it is through with it, passing the +value returned by *tep_plugin_kvm_get_func()* as _func_. This allows the application +to free it if necessary. + +RETURN VALUE +------------ +The *tep_plugin_kvm_get_func()* is not to be called by the application but instead +is to be defined by the application. It should return a nul terminated string representing +the function for the given instruction pointer passed to it by reference in _paddr_. It +can then optionally update the _paddr_ to a value that holds the start of the function. +The string returned may be freed by the *tep_plugin_kvm_put_func()* that the application +should define to clean up the string. + +The below example needs to be compiled with the *-rdynamic* flag so that the dynamic +linker can resolve the *tep_plugin_kvm_get_func()* and *tep_plugin_kvm_put_func()* functions. + +When run against a trace.dat file produced by *trace-cmd(1)* recording the kvm_exit and +kvm_entry events on a guest, and then the guest's /proc/kallsyms file is passed as the +second parameter, the output produced will look something like: + +[source,c] +-- +CPU 0/KVM-20407 83156.177626 [000] kvm_exit reason APIC_ACCESS rip 0xffffffffb0056ee2 exit native_apic_mem_write+0x2 info 10b0 0 +CPU 0/KVM-20407 83156.177632 [000] kvm_entry vcpu 0 rip 0xffffffffb0056ee8 enter native_apic_mem_write+0x8 +-- + +But without those callbacks, it would look like: + +[source,c] +-- +CPU 0/KVM-20407 83156.177626 [000] kvm_exit reason APIC_ACCESS rip 0xffffffffb0056ee2 info 10b0 0 +CPU 0/KVM-20407 83156.177632 [000] kvm_entry vcpu 0 rip 0xffffffffb0056ee8 +-- + +EXAMPLE +------- +[source,c] +-- +#include <stdio.h> +#include <stdlib.h> +#include <event-parse.h> +#include <trace-cmd.h> +#include <sys/stat.h> + +static struct tep_handle *tep; + +const char *tep_plugin_kvm_get_func(struct tep_event *event, struct tep_record *record, + unsigned long long *paddr) +{ + const char *func; + char *event_func; + char *ename; + + func = tep_find_function(tep, *paddr); + if (!func) + return NULL; + + if (strcmp(event->name, "kvm_exit") == 0) + ename = "exit"; + else + ename = "enter"; + + /* + * Normally, passing back func directly is sufficient and then + * tep_plugin_kvm_put_func() would not be required. But this example + * is showing how to handle allocation of the returned string. + */ + event_func = malloc(strlen(ename) + strlen(func) + 2); + if (!event_func) + return NULL; + sprintf(event_func, "%s %s", ename, func); + + *paddr = tep_find_function_address(tep, *paddr); + + return event_func; +} + +void tep_plugin_kvm_put_func(const char *func) +{ + char *f = (char *)func; + + free(f); +} + +static int show_event(struct tracecmd_input *handle, struct tep_event *event, + struct tep_record *record, int cpu, void *data) +{ + static struct trace_seq seq; + tep = data; + + if (!seq.buffer) + trace_seq_init(&seq); + + trace_seq_reset(&seq); + tep_print_event(tracecmd_get_tep(handle), &seq, record, + "%s-%d\t%6.1000d [%03d] %s\t%s\n", + TEP_PRINT_COMM, TEP_PRINT_PID, + TEP_PRINT_TIME, TEP_PRINT_CPU, + TEP_PRINT_NAME, TEP_PRINT_INFO); + trace_seq_terminate(&seq); + trace_seq_do_printf(&seq); + return 0; +} + +int main(int argc, char **argv) +{ + struct tracecmd_input *handle; + struct tep_handle *guest_tep; + struct stat st; + FILE *fp; + char *buf; + + if (argc < 3) { + printf("usage: trace.dat guest_kallsyms_file\n"); + exit(-1); + } + + handle = tracecmd_open(argv[1], 0); + if (!handle) { + perror(argv[1]); + exit(-1); + } + + /* Just for kallsyms parsing */ + guest_tep = tep_alloc(); + if (!guest_tep) + exit(-1); + + if (stat(argv[2], &st) < 0) { + perror(argv[2]); + exit(-1); + } + + buf = malloc(st.st_size + 1); + if (!buf) + exit(-1); + + fp = fopen(argv[2], "r"); + if (!fp) { + perror(argv[2]); + exit(-1); + } + + if (fread(buf, st.st_size, 1, fp) < 0) { + perror(argv[2]); + exit(-1); + } + + buf[st.st_size] = '\0'; + + if (tep_parse_kallsyms(guest_tep, buf) < 0) { + printf("Failed to parse %s\n", argv[2]); + exit(-1); + } + free(buf); + + tracecmd_follow_event(handle, "kvm", "kvm_exit", show_event, guest_tep); + tracecmd_follow_event(handle, "kvm", "kvm_entry", show_event, guest_tep); + + tracecmd_iterate_events(handle, NULL, 0, NULL, NULL); + + tep_free(guest_tep); + tracecmd_close(handle); +} +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-log.txt b/Documentation/libtraceevent-log.txt new file mode 100644 index 0000000..a236e2a --- /dev/null +++ b/Documentation/libtraceevent-log.txt @@ -0,0 +1,90 @@ +libtraceevent(3) +================ + +NAME +---- +tep_set_loglevel - Set log level of the library + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +enum *tep_loglevel* { + TEP_LOG_NONE = 0, + TEP_LOG_CRITICAL, + TEP_LOG_ERROR, + TEP_LOG_WARNING, + TEP_LOG_INFO, + TEP_LOG_DEBUG, + TEP_LOG_ALL +}; + +int *tep_set_loglevel*(enum tep_loglevel _level_); + +-- +DESCRIPTION +----------- +The *tep_set_loglevel()* function sets the level of the library logs that will be printed +on the console. Library log levels are: +[verse] +-- + _TEP_LOG_NONE_ - Do not print any logs. + _TEP_LOG_CRITICAL_ - Print critical logs, problem that may cause a crash. + _TEP_LOG_ERROR_ - Print error logs, problem that could break the main logic of an API. + _TEP_LOG_WARNING_ - Print warnings, problem that could limit the result of an API. + _TEP_LOG_INFO_ - Print information about normal execution of an API. + _TEP_LOG_DEBUG_ - Print debug information. + _TEP_LOG_ALL_ - Print logs from all levels. +-- +Setting the log level to specific value means that logs from the previous levels will be printed +too. For example _TEP_LOG_WARNING_ will print any logs with severity _TEP_LOG_WARNING_, +_TEP_LOG_ERROR_ and _TEP_LOG_CRITICAL_. The default log level is _TEP_LOG_CRITICAL_. + + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> + +tep_set_loglevel(TEP_LOG_ALL); +... +/* call libtraceevent APIs and observe any logs they produce */ +... +tep_set_loglevel(TEP_LOG_CRITICAL); +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-long_size.txt b/Documentation/libtraceevent-long_size.txt new file mode 100644 index 0000000..c4b358a --- /dev/null +++ b/Documentation/libtraceevent-long_size.txt @@ -0,0 +1,78 @@ +libtraceevent(3) +================ + +NAME +---- +tep_get_long_size, tep_set_long_size - Get / set the size of a long integer on +the machine, where the trace is generated, in bytes + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +int *tep_get_long_size*(strucqt tep_handle pass:[*]_tep_); +void *tep_set_long_size*(struct tep_handle pass:[*]_tep_, int _long_size_); +-- + +DESCRIPTION +----------- +The *tep_get_long_size()* function returns the size of a long integer on the machine, +where the trace is generated. The _tep_ argument is trace event parser context. + +The *tep_set_long_size()* function sets the size of a long integer on the machine, +where the trace is generated. The _tep_ argument is trace event parser context. +The _long_size_ is the size of a long integer, in bytes. + +RETURN VALUE +------------ +The *tep_get_long_size()* function returns the size of a long integer on the machine, +where the trace is generated, in bytes. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... +tep_set_long_size(tep, 4); +... +int long_size = tep_get_long_size(tep); +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-page_size.txt b/Documentation/libtraceevent-page_size.txt new file mode 100644 index 0000000..6d0dd36 --- /dev/null +++ b/Documentation/libtraceevent-page_size.txt @@ -0,0 +1,90 @@ +libtraceevent(3) +================ + +NAME +---- +tep_get_page_size, tep_set_page_size, tep_get_sub_buffer_size - Get / set the size of a memory page on +the machine, where the trace is generated + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +int *tep_get_page_size*(struct tep_handle pass:[*]_tep_); +void *tep_set_page_size*(struct tep_handle pass:[*]_tep_, int _page_size_); +int *tep_get_sub_buffer_size*(struct tep_handle pass:[*]_tep_); +-- + +DESCRIPTION +----------- +The *tep_get_page_size()* function returns the size of a memory page on +the machine, where the trace is generated. The _tep_ argument is trace +event parser context. + +The *tep_set_page_size()* function stores in the _tep_ context the size of a +memory page on the machine, where the trace is generated. +The _tep_ argument is trace event parser context. +The _page_size_ argument is the size of a memory page, in bytes. + +The *tep_get_sub_buffer_size()* returns the size of each "sub buffer" of the +ring buffer. The Linux kernel ring buffer is broken up into sections called +sub buffers. This returns the size of those buffers. + +RETURN VALUE +------------ +The *tep_get_page_size()* function returns size of the memory page, in bytes. + +The *tep_get_sub_buffer_size()* function returns the number of bytes each sub +buffer is made up of. + +EXAMPLE +------- +[source,c] +-- +#include <unistd.h> +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... + int page_size = getpagesize(); + + tep_set_page_size(tep, page_size); + + printf("The page size for this machine is %d\n", tep_get_page_size(tep)); + +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-parse-files.txt b/Documentation/libtraceevent-parse-files.txt new file mode 100644 index 0000000..bb2facb --- /dev/null +++ b/Documentation/libtraceevent-parse-files.txt @@ -0,0 +1,149 @@ +libtraceevent(3) +================ + +NAME +---- +tep_parse_saved_cmdlines, tep_parse_printk_formats, tep_parse_kallsyms +- Parsing functions to load mappings + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +int *tep_parse_saved_cmdlines*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_); +int *tep_parse_printk_formats*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_); +int *tep_parse_kallsyms*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_); +-- + +DESCRIPTION +----------- +*tep_parse_saved_cmdlines()* is a helper function to parse content in the tracefs +file system of the "saved_cmdlines" file (stored in a string buffer passed in by _buf_) +and loads the mapping of the process IDs (pid) to the comm names in the +_tep_ handler. The events store the pid and this is used to be able to show the +process names associated to those process ids. It parses the string _buf_ that +holds the content of saved_cmdlines and ends with a nul character ('\0'). + +*tep_parse_printk_formats()* is a helper function to parse content in the tracefs +file system of the "printk_formats" file (stored in a string buffer passed in by _buf_) +and loads the mapping of addresses of strings that may be referenced by events. +Events only store the address of constant strings in the kernel, and the mapping +of their address to the string is exported to user space in the printk_formats +file. It parses the string _buf_ that holds the content of printk_formats and +ends with a nul character ('\0'). + +*tep_parse_kallsyms()* is a helper function to parse the Linux kernel /proc/kallsyms format +(stored in a string buffer passed in by _buf_) and load the functions into the +_tep_ handler such that function IP addresses can be mapped to their name when +parsing events with %pS in the print format field. It parses the string _buf_ that +holds the content of /proc/kallsyms and ends with a nul character ('\0'). + +RETURN VALUE +------------ +The *tep_parse_saved_cmdlines*() function returns 0 in case of success, or -1 +in case of an error. + +The *tep_parse_printk_formats*() function returns 0 in case of success, or -1 +in case of an error. + +The *tep_parse_kallsyms*() function returns 0 in case of success, or -1 +in case of an error. + +EXAMPLE +------- +[source,c] +-- +... +#include <event-parse.h> +#include <tracefs.h> +#include <stdlib.h> + +int load_cmdlines(struct tep_handle *tep) +{ + char *buf = NULL; + int r; + + buf = tracefs_instance_file_read(NULL, "saved_cmdlines", NULL); + if (!buf) + return -1; + r = tep_parse_saved_cmdlines(tep, buf); + free(buf); + return r; +} + +int load_print_strings(struct tep_handle *tep) +{ + char *buf = NULL; + int r; + + buf = tracefs_instance_file_read(NULL, "printk_formats", NULL); + if (!buf) + return -1; + r = tep_parse_printk_formats(tep, buf); + free(buf); + return r; +} + +int load_kallsyms(struct tep_handle *tep) +{ + char *line = NULL; + char *buf = NULL; + size_t sz = 0; + FILE *fp; + int len = 0; + int r; + + fp = fopen("/proc/kallsyms", "r"); + while ((r = getline(&line, &sz, fp)) >= 0) { + buf = realloc(buf, len + r + 1); + memcpy(buf + len, line, r); + len += r; + } + free(line); + fclose(fp); + if (!buf) + return -1; + buf[len] = 0; + + r = tep_parse_kallsyms(tep, buf); + free(buf); + return r; +} +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1), *tep_register_comm*(3), *tep_register_function*(3), +*tep_register_print_string*(3) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, coauthor of *libtraceevent*. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-parse_event.txt b/Documentation/libtraceevent-parse_event.txt new file mode 100644 index 0000000..466d157 --- /dev/null +++ b/Documentation/libtraceevent-parse_event.txt @@ -0,0 +1,90 @@ +libtraceevent(3) +================ + +NAME +---- +tep_parse_event, tep_parse_format - Parse the event format information + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +enum tep_errno *tep_parse_event*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_, unsigned long _size_, const char pass:[*]_sys_); +enum tep_errno *tep_parse_format*(struct tep_handle pass:[*]_tep_, struct tep_event pass:[*]pass:[*]_eventp_, const char pass:[*]_buf_, unsigned long _size_, const char pass:[*]_sys_); +-- + +DESCRIPTION +----------- +The *tep_parse_event()* function parses the event format and creates an event +structure to quickly parse raw data for a given event. The _tep_ argument is +the trace event parser context. The created event structure is stored in the +_tep_ context. The _buf_ argument is a buffer with _size_, where the event +format data is. The event format data can be taken from +tracefs/events/.../.../format files. The _sys_ argument is the system of +the event. + +The *tep_parse_format()* function does the same as *tep_parse_event()*. The only +difference is in the extra _eventp_ argument, where the newly created event +structure is returned. + +RETURN VALUE +------------ +Both *tep_parse_event()* and *tep_parse_format()* functions return 0 on success, +or TEP_ERRNO__... in case of an error. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... +char *buf; +int size; +struct tep_event *event = NULL; +buf = read_file("/sys/kernel/tracing/events/ftrace/print/format", &size); +if (tep_parse_event(tep, buf, size, "ftrace") != 0) { + /* Failed to parse the ftrace print format */ +} + +if (tep_parse_format(tep, &event, buf, size, "ftrace") != 0) { + /* Failed to parse the ftrace print format */ +} +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-parse_head.txt b/Documentation/libtraceevent-parse_head.txt new file mode 100644 index 0000000..22b0a4f --- /dev/null +++ b/Documentation/libtraceevent-parse_head.txt @@ -0,0 +1,82 @@ +libtraceevent(3) +================ + +NAME +---- +tep_parse_header_page - Parses the data stored in the header page. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +int *tep_parse_header_page*(struct tep_handle pass:[*]_tep_, char pass:[*]_buf_, unsigned long _size_, int _long_size_); +-- + +DESCRIPTION +----------- +The *tep_parse_header_page()* function parses the header page data from _buf_, +and initializes the _tep_, trace event parser context, with it. The buffer +_buf_ is with _size_, and is supposed to be copied from +tracefs/events/header_page. + +Some old kernels do not have header page info, in this case the +*tep_parse_header_page()* function can be called with _size_ equal to 0. The +_tep_ context is initialized with default values. The _long_size_ can be used in +this use case, to set the size of a long integer to be used. + +RETURN VALUE +------------ +The *tep_parse_header_page()* function returns 0 in case of success, or -1 +in case of an error. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... +char *buf; +int size; +buf = read_file("/sys/kernel/tracing/events/header_page", &size); +if (tep_parse_header_page(tep, buf, size, sizeof(unsigned long)) != 0) { + /* Failed to parse the header page */ +} +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-plugins.txt b/Documentation/libtraceevent-plugins.txt new file mode 100644 index 0000000..4ca78d4 --- /dev/null +++ b/Documentation/libtraceevent-plugins.txt @@ -0,0 +1,150 @@ +libtraceevent(3) +================ + +NAME +---- +tep_load_plugins, tep_unload_plugins, tep_load_plugins_hook, tep_add_plugin_path, +tep_plugin_add_option - Load / unload traceevent plugins. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +struct tep_plugin_list pass:[*]*tep_load_plugins*(struct tep_handle pass:[*]_tep_); +void *tep_unload_plugins*(struct tep_plugin_list pass:[*]_plugin_list_, struct tep_handle pass:[*]_tep_); +void *tep_load_plugins_hook*(struct tep_handle pass:[*]_tep_, const char pass:[*]_suffix_, + void (pass:[*]_load_plugin_)(struct tep_handle pass:[*]tep, + const char pass:[*]path, + const char pass:[*]name, + void pass:[*]data), + void pass:[*]_data_); +int *tep_add_plugin_path*(struct tep_handle pass:[*]tep, char pass:[*]path, + enum tep_plugin_load_priority prio); +int *tep_plugin_add_option*(const char pass:[*]_name_, const char pass:[*]_val_); +-- + +DESCRIPTION +----------- +The *tep_load_plugins()* function loads all plugins, located in the plugin +directories. The _tep_ argument is trace event parser context. +The plugin directories are : +[verse] +-- + - Directories, specified in _tep_->plugins_dir with priority TEP_PLUGIN_FIRST + - System's plugin directory, defined at the library compile time. It + depends on the library installation prefix and usually is + _(install_preffix)/lib/traceevent/plugins_ + - Directory, defined by the environment variable _TRACEEVENT_PLUGIN_DIR_ + - User's plugin directory, located at _~/.local/lib/traceevent/plugins_ + - Directories, specified in _tep_->plugins_dir with priority TEP_PLUGIN_LAST +-- +Loading of plugins can be controlled by the _tep_flags_, using the +*tep_set_flag()* API: +[verse] +-- + _TEP_DISABLE_SYS_PLUGINS_ - do not load plugins, located in + the system's plugin directory. + _TEP_DISABLE_PLUGINS_ - do not load any plugins. +-- +The *tep_set_flag()* API needs to be called before *tep_load_plugins()*, if +loading of all plugins is not the desired case. + +The *tep_unload_plugins()* function unloads the plugins, previously loaded by +*tep_load_plugins()*. The _tep_ argument is trace event parser context. The +_plugin_list_ is the list of loaded plugins, returned by +the *tep_load_plugins()* function. + +The *tep_load_plugins_hook()* function walks through all directories with plugins +and calls user specified *load_plugin()* hook for each plugin file. Only files +with given _suffix_ are considered to be plugins. The _data_ is a user specified +context, passed to *load_plugin()*. Directories and the walk order are the same +as in *tep_load_plugins()* API. + +The *tep_add_plugin_path()* functions adds additional directories with plugins in +the _tep_->plugins_dir list. It must be called before *tep_load_plugins()* in order +for the plugins from the new directories to be loaded. The _tep_ argument is +the trace event parser context. The _path_ is the full path to the new plugin +directory. The _prio_ argument specifies the loading priority order for the +new directory of plugins. The loading priority is important in case of different +versions of the same plugin located in multiple plugin directories.The last loaded +plugin wins. The priority can be: +[verse] +-- + _TEP_PLUGIN_FIRST_ - Load plugins from this directory first + _TEP_PLUGIN_LAST_ - Load plugins from this directory last +-- +Where the plugins in TEP_PLUGIN_LAST" will take precedence over the +plugins in the other directories. + +The *tep_plugin_add_option()* sets options defined by a plugin. The _name_ is the +name of the option to set to _val_. Plugins can add options to change its behavior +and *tep_plugin_add_option()* is used by the application to make those modifications. + + +RETURN VALUE +------------ +The *tep_load_plugins()* function returns a list of successfully loaded plugins, +or NULL in case no plugins are loaded. +The *tep_add_plugin_path()* function returns -1 in case of an error, 0 otherwise. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... +tep_add_plugin_path(tep, "~/dev_plugins", TEP_PLUGIN_LAST); +... +struct tep_plugin_list *plugins = tep_load_plugins(tep); +if (plugins == NULL) { + /* no plugins are loaded */ +} +... +tep_unload_plugins(plugins, tep); +... +void print_plugin(struct tep_handle *tep, const char *path, + const char *name, void *data) +{ + pritnf("Found libtraceevent plugin %s/%s\n", path, name); +} +... +tep_load_plugins_hook(tep, ".so", print_plugin, NULL); +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1), *tep_set_flag*(3) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-record_parse.txt b/Documentation/libtraceevent-record_parse.txt new file mode 100644 index 0000000..dbc3a76 --- /dev/null +++ b/Documentation/libtraceevent-record_parse.txt @@ -0,0 +1,137 @@ +libtraceevent(3) +================ + +NAME +---- +tep_data_type, tep_data_pid,tep_data_preempt_count, tep_data_flags - +Extract common fields from a record. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +enum *trace_flag_type* { + _TRACE_FLAG_IRQS_OFF_, + _TRACE_FLAG_IRQS_NOSUPPORT_, + _TRACE_FLAG_NEED_RESCHED_, + _TRACE_FLAG_HARDIRQ_, + _TRACE_FLAG_SOFTIRQ_, +}; + +int *tep_data_type*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); +int *tep_data_pid*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); +int *tep_data_preempt_count*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); +int *tep_data_flags*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); +-- + +DESCRIPTION +----------- +This set of functions can be used to extract common fields from a record. + +The *tep_data_type()* function gets the event id from the record _rec_. +It reads the "common_type" field. The _tep_ argument is the trace event parser +context. + +The *tep_data_pid()* function gets the process id from the record _rec_. +It reads the "common_pid" field. The _tep_ argument is the trace event parser +context. + +The *tep_data_preempt_count()* function gets the preemption count from the +record _rec_. It reads the "common_preempt_count" field. The _tep_ argument is +the trace event parser context. + +The *tep_data_flags()* function gets the latency flags from the record _rec_. +It reads the "common_flags" field. The _tep_ argument is the trace event parser +context. Supported latency flags are: +[verse] +-- + _TRACE_FLAG_IRQS_OFF_, Interrupts are disabled. + _TRACE_FLAG_IRQS_NOSUPPORT_, Reading IRQ flag is not supported by the architecture. + _TRACE_FLAG_NEED_RESCHED_, Task needs rescheduling. + _TRACE_FLAG_HARDIRQ_, Hard IRQ is running. + _TRACE_FLAG_SOFTIRQ_, Soft IRQ is running. +-- + +RETURN VALUE +------------ +The *tep_data_type()* function returns an integer, representing the event id. + +The *tep_data_pid()* function returns an integer, representing the process id + +The *tep_data_preempt_count()* function returns an integer, representing the +preemption count. + +The *tep_data_flags()* function returns an integer, representing the latency +flags. Look at the _trace_flag_type_ enum for supported flags. + +All these functions in case of an error return a negative integer. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... +void process_record(struct tep_record *record) +{ + int data; + + data = tep_data_type(tep, record); + if (data >= 0) { + /* Got the ID of the event */ + } + + data = tep_data_pid(tep, record); + if (data >= 0) { + /* Got the process ID */ + } + + data = tep_data_preempt_count(tep, record); + if (data >= 0) { + /* Got the preemption count */ + } + + data = tep_data_flags(tep, record); + if (data >= 0) { + /* Got the latency flags */ + } +} +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-reg_event_handler.txt b/Documentation/libtraceevent-reg_event_handler.txt new file mode 100644 index 0000000..90ab7f0 --- /dev/null +++ b/Documentation/libtraceevent-reg_event_handler.txt @@ -0,0 +1,156 @@ +libtraceevent(3) +================ + +NAME +---- +tep_register_event_handler, tep_unregister_event_handler - Register / +unregisters a callback function to parse an event information. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +enum *tep_reg_handler* { + _TEP_REGISTER_SUCCESS_, + _TEP_REGISTER_SUCCESS_OVERWRITE_, +}; + +int *tep_register_event_handler*(struct tep_handle pass:[*]_tep_, int _id_, const char pass:[*]_sys_name_, const char pass:[*]_event_name_, tep_event_handler_func _func_, void pass:[*]_context_); +int *tep_unregister_event_handler*(struct tep_handle pass:[*]tep, int id, const char pass:[*]sys_name, const char pass:[*]event_name, tep_event_handler_func func, void pass:[*]_context_); + +typedef int (*pass:[*]tep_event_handler_func*)(struct trace_seq pass:[*]s, struct tep_record pass:[*]record, struct tep_event pass:[*]event, void pass:[*]context); +-- + +DESCRIPTION +----------- +The *tep_register_event_handler()* function registers a handler function, +which is going to be called to parse the information for a given event. +The _tep_ argument is the trace event parser context. The _id_ argument is +the id of the event. The _sys_name_ argument is the name of the system, +the event belongs to. The _event_name_ argument is the name of the event. +If _id_ is >= 0, it is used to find the event, otherwise _sys_name_ and +_event_name_ are used. The _func_ is a pointer to the function, which is going +to be called to parse the event information. The _context_ argument is a pointer +to the context data, which will be passed to the _func_. If a handler function +for the same event is already registered, it will be overridden with the new +one. This mechanism allows a developer to override the parsing of a given event. +If for some reason the default print format is not sufficient, the developer +can register a function for an event to be used to parse the data instead. + +The *tep_unregister_event_handler()* function unregisters the handler function, +previously registered with *tep_register_event_handler()*. The _tep_ argument +is the trace event parser context. The _id_, _sys_name_, _event_name_, _func_, +and _context_ are the same arguments, as when the callback function _func_ was +registered. + +The _tep_event_handler_func_ is the type of the custom event handler +function. The _s_ argument is the trace sequence, it can be used to create a +custom string, describing the event. A _record_ to get the event from is passed +as input parameter and also the _event_ - the handle to the record's event. The +_context_ is custom context, set when the custom event handler is registered. + +RETURN VALUE +------------ +The *tep_register_event_handler()* function returns _TEP_REGISTER_SUCCESS_ +if the new handler is registered successfully or +_TEP_REGISTER_SUCCESS_OVERWRITE_ if an existing handler is overwritten. +If there is not enough memory to complete the registration, +TEP_ERRNO__MEM_ALLOC_FAILED is returned. + +The *tep_unregister_event_handler()* function returns 0 if _func_ was removed +successful or, -1 if the event was not found. + +The _tep_event_handler_func_ should return -1 in case of an error, +or 0 otherwise. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +#include <trace-seq.h> +... +struct tep_handle *tep = tep_alloc(); +... +int timer_expire_handler(struct trace_seq *s, struct tep_record *record, + struct tep_event *event, void *context) +{ + trace_seq_printf(s, "hrtimer="); + + if (tep_print_num_field(s, "0x%llx", event, "timer", record, 0) == -1) + tep_print_num_field(s, "0x%llx", event, "hrtimer", record, 1); + + trace_seq_printf(s, " now="); + + tep_print_num_field(s, "%llu", event, "now", record, 1); + + tep_print_func_field(s, " function=%s", event, "function", record, 0); + + return 0; +} +... + int ret; + + ret = tep_register_event_handler(tep, -1, "timer", "hrtimer_expire_entry", + timer_expire_handler, NULL); + if (ret < 0) { + char buf[32]; + + tep_strerror(tep, ret, buf, 32) + printf("Failed to register handler for hrtimer_expire_entry: %s\n", buf); + } else { + switch (ret) { + case TEP_REGISTER_SUCCESS: + printf ("Registered handler for hrtimer_expire_entry\n"); + break; + case TEP_REGISTER_SUCCESS_OVERWRITE: + printf ("Overwrote handler for hrtimer_expire_entry\n"); + break; + } + } +... + ret = tep_unregister_event_handler(tep, -1, "timer", "hrtimer_expire_entry", + timer_expire_handler, NULL); + if ( ret ) + printf ("Failed to unregister handler for hrtimer_expire_entry\n"); + +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*trace-seq.h* + Header file to include in order to have access to trace sequences + related APIs. Trace sequences are used to allow a function to call + several other functions to create a string of data to use. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-reg_print_func.txt b/Documentation/libtraceevent-reg_print_func.txt new file mode 100644 index 0000000..b3c8491 --- /dev/null +++ b/Documentation/libtraceevent-reg_print_func.txt @@ -0,0 +1,155 @@ +libtraceevent(3) +================ + +NAME +---- +tep_register_print_function,tep_unregister_print_function - +Registers / Unregisters a helper function. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +enum *tep_func_arg_type* { + TEP_FUNC_ARG_VOID, + TEP_FUNC_ARG_INT, + TEP_FUNC_ARG_LONG, + TEP_FUNC_ARG_STRING, + TEP_FUNC_ARG_PTR, + TEP_FUNC_ARG_MAX_TYPES +}; + +typedef unsigned long long (*pass:[*]tep_func_handler*)(struct trace_seq pass:[*]s, unsigned long long pass:[*]args); + +int *tep_register_print_function*(struct tep_handle pass:[*]_tep_, tep_func_handler _func_, enum tep_func_arg_type _ret_type_, char pass:[*]_name_, _..._); +int *tep_unregister_print_function*(struct tep_handle pass:[*]_tep_, tep_func_handler _func_, char pass:[*]_name_); +-- + +DESCRIPTION +----------- +Some events may have helper functions in the print format arguments. +This allows a plugin to dynamically create a way to process one of +these functions. + +The *tep_register_print_function()* registers such helper function. The _tep_ +argument is the trace event parser context. The _func_ argument is a pointer +to the helper function. The _ret_type_ argument is the return type of the +helper function, value from the _tep_func_arg_type_ enum. The _name_ is the name +of the helper function, as seen in the print format arguments. The _..._ is a +variable list of _tep_func_arg_type_ enums, the _func_ function arguments. +This list must end with _TEP_FUNC_ARG_VOID_. See 'EXAMPLE' section. + +The *tep_unregister_print_function()* unregisters a helper function, previously +registered with *tep_register_print_function()*. The _tep_ argument is the +trace event parser context. The _func_ and _name_ arguments are the same, used +when the helper function was registered. + +The _tep_func_handler_ is the type of the helper function. The _s_ argument is +the trace sequence, it can be used to create a custom string. +The _args_ is a list of arguments, defined when the helper function was +registered. + +RETURN VALUE +------------ +The *tep_register_print_function()* function returns 0 in case of success. +In case of an error, TEP_ERRNO_... code is returned. + +The *tep_unregister_print_function()* returns 0 in case of success, or -1 in +case of an error. + +EXAMPLE +------- +Some events have internal functions calls, that appear in the print format +output. For example "tracefs/events/i915/g4x_wm/format" has: +[source,c] +-- +print fmt: "pipe %c, frame=%u, scanline=%u, wm %d/%d/%d, sr %s/%d/%d/%d, hpll %s/%d/%d/%d, fbc %s", + ((REC->pipe) + 'A'), REC->frame, REC->scanline, REC->primary, + REC->sprite, REC->cursor, yesno(REC->cxsr), REC->sr_plane, + REC->sr_cursor, REC->sr_fbc, yesno(REC->hpll), REC->hpll_plane, + REC->hpll_cursor, REC->hpll_fbc, yesno(REC->fbc) +-- +Notice the call to function *yesno()* in the print arguments. In the kernel +context, this function has the following implementation: +[source,c] +-- +static const char *yesno(int x) +{ + static const char *yes = "yes"; + static const char *no = "no"; + + return x ? yes : no; +} +-- +The user space event parser has no idea how to handle this *yesno()* function. +The *tep_register_print_function()* API can be used to register a user space +helper function, mapped to the kernel's *yesno()*: +[source,c] +-- +#include <event-parse.h> +#include <trace-seq.h> +... +struct tep_handle *tep = tep_alloc(); +... +static const char *yes_no_helper(int x) +{ + return x ? "yes" : "no"; +} +... + if ( tep_register_print_function(tep, + yes_no_helper, + TEP_FUNC_ARG_STRING, + "yesno", + TEP_FUNC_ARG_INT, + TEP_FUNC_ARG_VOID) != 0) { + /* Failed to register yes_no_helper function */ + } + +/* + Now, when the event parser encounters this yesno() function, it will know + how to handle it. +*/ +... + if (tep_unregister_print_function(tep, yes_no_helper, "yesno") != 0) { + /* Failed to unregister yes_no_helper function */ + } +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*trace-seq.h* + Header file to include in order to have access to trace sequences + related APIs. Trace sequences are used to allow a function to call + several other functions to create a string of data to use. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-set_flag.txt b/Documentation/libtraceevent-set_flag.txt new file mode 100644 index 0000000..c11dd00 --- /dev/null +++ b/Documentation/libtraceevent-set_flag.txt @@ -0,0 +1,104 @@ +libtraceevent(3) +================ + +NAME +---- +tep_set_flag, tep_clear_flag, tep_test_flag - +Manage flags of trace event parser context. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +enum *tep_flag* { + _TEP_NSEC_OUTPUT_, + _TEP_DISABLE_SYS_PLUGINS_, + _TEP_DISABLE_PLUGINS_ +}; +void *tep_set_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); +void *tep_clear_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); +bool *tep_test_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); +-- + +DESCRIPTION +----------- +Trace event parser context flags are defined in *enum tep_flag*: +[verse] +-- +_TEP_NSEC_OUTPUT_ - print event's timestamp in nano seconds, instead of micro seconds. +_TEP_DISABLE_SYS_PLUGINS_ - disable plugins, located in system's plugin + directory. This directory is defined at library compile + time, and usually depends on library installation + prefix: (install_preffix)/lib/traceevent/plugins +_TEP_DISABLE_PLUGINS_ - disable all library plugins: + - in system's plugin directory + - in directory, defined by the environment variable _TRACEEVENT_PLUGIN_DIR_ + - in user's home directory, _~/.traceevent/plugins_ +-- +Note: plugin related flags must me set before calling *tep_load_plugins()* API. + +The *tep_set_flag()* function sets _flag_ to _tep_ context. + +The *tep_clear_flag()* function clears _flag_ from _tep_ context. + +The *tep_test_flag()* function tests if _flag_ is set to _tep_ context. + +RETURN VALUE +------------ +*tep_test_flag()* function returns true if _flag_ is set, false otherwise. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... +/* Print timestamps in nanoseconds */ +tep_set_flag(tep, TEP_NSEC_OUTPUT); +... +if (tep_test_flag(tep, TEP_NSEC_OUTPUT)) { + /* print timestamps in nanoseconds */ +} else { + /* print timestamps in microseconds */ +} +... +/* Print timestamps in microseconds */ +tep_clear_flag(tep, TEP_NSEC_OUTPUT); +... +-- +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-strerror.txt b/Documentation/libtraceevent-strerror.txt new file mode 100644 index 0000000..fa53344 --- /dev/null +++ b/Documentation/libtraceevent-strerror.txt @@ -0,0 +1,85 @@ +libtraceevent(3) +================ + +NAME +---- +tep_strerror - Returns a string describing regular errno and tep error number. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +int *tep_strerror*(struct tep_handle pass:[*]_tep_, enum tep_errno _errnum_, char pass:[*]_buf_, size_t _buflen_); + +-- +DESCRIPTION +----------- +The *tep_strerror()* function converts tep error number into a human +readable string. +The _tep_ argument is trace event parser context. The _errnum_ is a regular +errno, defined in errno.h, or a tep error number. The string, describing this +error number is copied in the _buf_ argument. The _buflen_ argument is +the size of the _buf_. + +It as a thread safe wrapper around strerror_r(). The library function has two +different behaviors - POSIX and GNU specific. The *tep_strerror()* API always +behaves as the POSIX version - the error string is copied in the user supplied +buffer. + +RETURN VALUE +------------ +The *tep_strerror()* function returns 0, if a valid _errnum_ is passed and the +string is copied into _buf_. If _errnum_ is not a valid error number, +-1 is returned and _buf_ is not modified. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +... +struct tep_handle *tep = tep_alloc(); +... +char buf[32]; +char *pool = calloc(1, 128); +if (tep == NULL) { + tep_strerror(tep, TEP_ERRNO__MEM_ALLOC_FAILED, buf, 32); + printf ("The pool is not initialized, %s", buf); +} +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent-tseq.txt b/Documentation/libtraceevent-tseq.txt new file mode 100644 index 0000000..03dd748 --- /dev/null +++ b/Documentation/libtraceevent-tseq.txt @@ -0,0 +1,158 @@ +libtraceevent(3) +================ + +NAME +---- +trace_seq_init, trace_seq_destroy, trace_seq_reset, trace_seq_terminate, +trace_seq_putc, trace_seq_puts, trace_seq_printf, trace_seq_vprintf, +trace_seq_do_fprintf, trace_seq_do_printf - +Initialize / destroy a trace sequence. + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* +*#include <trace-seq.h>* + +void *trace_seq_init*(struct trace_seq pass:[*]_s_); +void *trace_seq_destroy*(struct trace_seq pass:[*]_s_); +void *trace_seq_reset*(struct trace_seq pass:[*]_s_); +void *trace_seq_terminate*(struct trace_seq pass:[*]_s_); +int *trace_seq_putc*(struct trace_seq pass:[*]_s_, unsigned char _c_); +int *trace_seq_puts*(struct trace_seq pass:[*]_s_, const char pass:[*]_str_); +int *trace_seq_printf*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, _..._); +int *trace_seq_vprintf*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, va_list _args_); +int *trace_seq_do_printf*(struct trace_seq pass:[*]_s_); +int *trace_seq_do_fprintf*(struct trace_seq pass:[*]_s_, FILE pass:[*]_fp_); +-- + +DESCRIPTION +----------- +Trace sequences are used to allow a function to call several other functions +to create a string of data to use. + +The *trace_seq_init()* function initializes the trace sequence _s_. + +The *trace_seq_destroy()* function destroys the trace sequence _s_ and frees +all its resources that it had used. + +The *trace_seq_reset()* function re-initializes the trace sequence _s_. All +characters already written in _s_ will be deleted. + +The *trace_seq_terminate()* function terminates the trace sequence _s_. It puts +the null character pass:['\0'] at the end of the buffer. + +The *trace_seq_putc()* function puts a single character _c_ in the trace +sequence _s_. + +The *trace_seq_puts()* function puts a NULL terminated string _str_ in the +trace sequence _s_. + +The *trace_seq_printf()* function puts a formated string _fmt _with +variable arguments _..._ in the trace sequence _s_. + +The *trace_seq_vprintf()* function puts a formated string _fmt _with +list of arguments _args_ in the trace sequence _s_. + +The *trace_seq_do_printf()* function prints the buffer of trace sequence _s_ to +the standard output stdout. + +The *trace_seq_do_fprintf()* function prints the buffer of trace sequence _s_ +to the given file _fp_. + +RETURN VALUE +------------ +Both *trace_seq_putc()* and *trace_seq_puts()* functions return the number of +characters put in the trace sequence, or 0 in case of an error + +Both *trace_seq_printf()* and *trace_seq_vprintf()* functions return 0 if the +trace oversizes the buffer's free space, the number of characters printed, or +a negative value in case of an error. + +Both *trace_seq_do_printf()* and *trace_seq_do_fprintf()* functions return the +number of printed characters, or -1 in case of an error. + +EXAMPLE +------- +[source,c] +-- +#include <event-parse.h> +#include <trace-seq.h> +... +struct trace_seq seq; +trace_seq_init(&seq); +... +void foo_seq_print(struct trace_seq *tseq, char *format, ...) +{ + va_list ap; + va_start(ap, format); + if (trace_seq_vprintf(tseq, format, ap) <= 0) { + /* Failed to print in the trace sequence */ + } + va_end(ap); +} + +trace_seq_reset(&seq); + +char *str = " MAN page example"; +if (trace_seq_puts(&seq, str) != strlen(str)) { + /* Failed to put str in the trace sequence */ +} +if (trace_seq_putc(&seq, ':') != 1) { + /* Failed to put ':' in the trace sequence */ +} +if (trace_seq_printf(&seq, " trace sequence: %d", 1) <= 0) { + /* Failed to print in the trace sequence */ +} +foo_seq_print( &seq, " %d\n", 2); + +trace_seq_terminate(&seq); +... + +if (trace_seq_do_printf(&seq) < 0 ) { + /* Failed to print the sequence buffer to the standard output */ +} +FILE *fp = fopen("trace.txt", "w"); +if (trace_seq_do_fprintf(&seq, fp) < 0 ) [ + /* Failed to print the sequence buffer to the trace.txt file */ +} + +trace_seq_destroy(&seq); +... +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*trace-seq.h* + Header file to include in order to have access to trace sequences related APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/libtraceevent.txt b/Documentation/libtraceevent.txt new file mode 100644 index 0000000..0502769 --- /dev/null +++ b/Documentation/libtraceevent.txt @@ -0,0 +1,246 @@ +libtraceevent(3) +================ + +NAME +---- +libtraceevent - Linux kernel trace event library + +SYNOPSIS +-------- +[verse] +-- +*#include <event-parse.h>* + +Management of tep handler data structure and access of its members: + struct tep_handle pass:[*]*tep_alloc*(void); + void *tep_free*(struct tep_handle pass:[*]_tep_); + void *tep_ref*(struct tep_handle pass:[*]_tep_); + void *tep_unref*(struct tep_handle pass:[*]_tep_); + int *tep_get_ref*(struct tep_handle pass:[*]_tep_); + void *tep_set_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); + void *tep_clear_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_); + bool *tep_test_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flags_); + int *tep_get_cpus*(struct tep_handle pass:[*]_tep_); + void *tep_set_cpus*(struct tep_handle pass:[*]_tep_, int _cpus_); + int *tep_get_long_size*(strucqt tep_handle pass:[*]_tep_); + void *tep_set_long_size*(struct tep_handle pass:[*]_tep_, int _long_size_); + int *tep_get_page_size*(struct tep_handle pass:[*]_tep_); + void *tep_set_page_size*(struct tep_handle pass:[*]_tep_, int _page_size_); + int *tep_get_sub_buffer_size*(struct tep_handle pass:[*]_tep_); + int *tep_get_header_page_size*(struct tep_handle pass:[*]_tep_); + int *tep_get_header_timestamp_size*(struct tep_handle pass:[*]_tep_); + bool *tep_is_old_format*(struct tep_handle pass:[*]_tep_); + int *tep_strerror*(struct tep_handle pass:[*]_tep_, enum tep_errno _errnum_, char pass:[*]_buf_, size_t _buflen_); + struct kbuffer pass:[*]*tep_kbuffer*(struct tep_handle pass:[*]:_tep_); + +Register / unregister APIs: + int *tep_register_function*(struct tep_handle pass:[*]_tep_, char pass:[*]_name_, unsigned long long _addr_, char pass:[*]_mod_); + int *tep_register_event_handler*(struct tep_handle pass:[*]_tep_, int _id_, const char pass:[*]_sys_name_, const char pass:[*]_event_name_, tep_event_handler_func _func_, void pass:[*]_context_); + int *tep_unregister_event_handler*(struct tep_handle pass:[*]tep, int id, const char pass:[*]sys_name, const char pass:[*]event_name, tep_event_handler_func func, void pass:[*]_context_); + int *tep_register_print_string*(struct tep_handle pass:[*]_tep_, const char pass:[*]_fmt_, unsigned long long _addr_); + int *tep_register_print_function*(struct tep_handle pass:[*]_tep_, tep_func_handler _func_, enum tep_func_arg_type _ret_type_, char pass:[*]_name_, _..._); + int *tep_unregister_print_function*(struct tep_handle pass:[*]_tep_, tep_func_handler _func_, char pass:[*]_name_); + int *tep_get_function_count*(struct tep_handle *_tep_); + +Trace printk parsing: + void *tep_print_printk*(struct tep_handle pass:[*]tep); + void *tep_print_funcs*(struct tep_handle pass:[*]tep); + void *tep_set_test_filters*(struct tep_handle pass:[*]tep, int test_filters); + void *tep_plugin_print_options*(struct trace_seq pass:[*]s); + int *tep_plugin_add_option*(const char pass:[*]_name_, const char pass:[*]_val_); + +Meta data parsing: + int *tep_parse_saved_cmdlines*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_); + int *tep_parse_printk_formats*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_); + int *tep_parse_kallsyms*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_); + +Plugins management: + struct tep_plugin_list pass:[*]*tep_load_plugins*(struct tep_handle pass:[*]_tep_); + void *tep_unload_plugins*(struct tep_plugin_list pass:[*]_plugin_list_, struct tep_handle pass:[*]_tep_); + char pass:[*]pass:[*]*tep_plugin_list_options*(void); + void *tep_plugin_free_options_list*(char pass:[*]pass:[*]_list_); + int *tep_plugin_add_options*(const char pass:[*]_name_, struct tep_plugin_option pass:[*]_options_); + void *tep_plugin_remove_options*(struct tep_plugin_option pass:[*]_options_); + void *tep_print_plugins*(struct trace_seq pass:[*]_s_, const char pass:[*]_prefix_, const char pass:[*]_suffix_, const struct tep_plugin_list pass:[*]_list_); + void *tep_load_plugins_hook*(struct tep_handle pass:[*]_tep_, const char pass:[*]_suffix_, + void (pass:[*]_load_plugin_)(struct tep_handle pass:[*]tep, + const char pass:[*]path, + const char pass:[*]name, + void pass:[*]data), + void pass:[*]_data_); + int *tep_add_plugin_path*(struct tep_handle pass:[*]tep, char pass:[*]path, + enum tep_plugin_load_priority prio); + +Event related APIs: + struct tep_event pass:[*]*tep_get_event*(struct tep_handle pass:[*]_tep_, int _index_); + struct tep_event pass:[*]*tep_get_first_event*(struct tep_handle pass:[*]_tep_); + int *tep_get_events_count*(struct tep_handle pass:[*]_tep_); + struct tep_event pass:[*]pass:[*]*tep_list_events*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_); + struct tep_event pass:[*]pass:[*]*tep_list_events_copy*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_); + void *tep_print_event*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_record pass:[*]_record_, const char pass:[*]_fmt_, _..._); + +Event finding: + struct tep_event pass:[*]*tep_find_event*(struct tep_handle pass:[*]_tep_, int _id_); + struct tep_event pass:[*]*tep_find_event_by_name*(struct tep_handle pass:[*]_tep_, const char pass:[*]_sys_, const char pass:[*]_name_); + struct tep_event pass:[*]*tep_find_event_by_record*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_record_); + +Parsing of event files: + int *tep_parse_header_page*(struct tep_handle pass:[*]_tep_, char pass:[*]_buf_, unsigned long _size_, int _long_size_); + enum tep_errno *tep_parse_event*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_, unsigned long _size_, const char pass:[*]_sys_); + enum tep_errno *tep_parse_format*(struct tep_handle pass:[*]_tep_, struct tep_event pass:[*]pass:[*]_eventp_, const char pass:[*]_buf_, unsigned long _size_, const char pass:[*]_sys_); + +APIs related to fields from event's format files: + struct tep_format_field pass:[*]pass:[*]*tep_event_common_fields*(struct tep_event pass:[*]_event_); + struct tep_format_field pass:[*]pass:[*]*tep_event_fields*(struct tep_event pass:[*]_event_); + void pass:[*]*tep_get_field_raw*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int pass:[*]_len_, int _err_); + int *tep_get_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); + int *tep_get_common_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); + int *tep_get_any_field_val*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, unsigned long long pass:[*]_val_, int _err_); + int *tep_read_number_field*(struct tep_format_field pass:[*]_field_, const void pass:[*]_data_, unsigned long long pass:[*]_value_); + +Event fields printing: + void *tep_print_field_content*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, int size, struct tep_format_field pass:[*]_field_); + void *tep_print_fields*(struct trace_seq pass:[*]_s_, void pass:[*]_data_, int _size_, struct tep_event pass:[*]_event_); + int *tep_print_num_field*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int _err_); + int *tep_print_func_field*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, struct tep_event pass:[*]_event_, const char pass:[*]_name_, struct tep_record pass:[*]_record_, int _err_); + void *tep_record_print_fields*(struct trace_seq pass:[*]_s_, struct tep_record pass:[*]_record_, struct tep_event pass:[*]_event_); + void *tep_record_print_selected_fields*(struct trace_seq pass:[*]_s_, struct tep_record pass:[*]_record_, struct tep_event pass:[*]_event_, int _select_mask_); + +Event fields finding: + struct tep_format_field pass:[*]*tep_find_common_field*(struct tep_event pass:[*]_event_, const char pass:[*]_name_); + struct tep_format_field pass:[*]*tep_find_field*(struct tep_event_ormat pass:[*]_event_, const char pass:[*]_name_); + struct tep_format_field pass:[*]*tep_find_any_field*(struct tep_event pass:[*]_event_, const char pass:[*]_name_); + +Functions resolver: + int *tep_set_function_resolver*(struct tep_handle pass:[*]_tep_, tep_func_resolver_t pass:[*]_func_, void pass:[*]_priv_); + void *tep_reset_function_resolver*(struct tep_handle pass:[*]_tep_); + const char pass:[*]*tep_find_function*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); + unsigned long long *tep_find_function_address*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_); + int *tep_find_function_info*(struct tep_handle pass:[*]_tep_, unsigned long long _addr_, const char pass:[**]_name_, + unsigned long long pass:[*]_start_, unsigned long pass:[*]_size_); + +Filter management: + struct tep_event_filter pass:[*]*tep_filter_alloc*(struct tep_handle pass:[*]_tep_); + enum tep_errno *tep_filter_add_filter_str*(struct tep_event_filter pass:[*]_filter_, const char pass:[*]_filter_str_); + enum tep_errno *tep_filter_match*(struct tep_event_filter pass:[*]_filter_, struct tep_record pass:[*]_record_); + int *tep_filter_strerror*(struct tep_event_filter pass:[*]_filter_, enum tep_errno _err_, char pass:[*]buf, size_t _buflen_); + int *tep_event_filtered*(struct tep_event_filter pass:[*]_filter_, int _event_id_); + void *tep_filter_reset*(struct tep_event_filter pass:[*]_filter_); + void *tep_filter_free*(struct tep_event_filter pass:[*]_filter_); + char pass:[*]*tep_filter_make_string*(struct tep_event_filter pass:[*]_filter_, int _event_id_); + int *tep_filter_remove_event*(struct tep_event_filter pass:[*]_filter_, int _event_id_); + int *tep_filter_copy*(struct tep_event_filter pass:[*]_dest_, struct tep_event_filter pass:[*]_source_); + int *tep_filter_compare*(struct tep_event_filter pass:[*]_filter1_, struct tep_event_filter pass:[*]_filter2_); + +Parsing various data from the records: + int *tep_data_type*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); + int *tep_data_pid*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); + int *tep_data_preempt_count*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); + int *tep_data_flags*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_); + +Command and task related APIs: + const char pass:[*]*tep_data_comm_from_pid*(struct tep_handle pass:[*]_tep_, int _pid_); + struct cmdline pass:[*]*tep_data_pid_from_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, struct cmdline pass:[*]_next_); + int *tep_register_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, int _pid_); + int *tep_override_comm*(struct tep_handle pass:[*]_tep_, const char pass:[*]_comm_, int _pid_); + bool *tep_is_pid_registered*(struct tep_handle pass:[*]_tep_, int _pid_); + int *tep_cmdline_pid*(struct tep_handle pass:[*]_tep_, struct cmdline pass:[*]_cmdline_); + +Endian related APIs: + int *tep_is_bigendian*(void); + unsigned long long *tep_read_number*(struct tep_handle pass:[*]_tep_, const void pass:[*]_ptr_, int _size_); + bool *tep_is_file_bigendian*(struct tep_handle pass:[*]_tep_); + void *tep_set_file_bigendian*(struct tep_handle pass:[*]_tep_, enum tep_endian _endian_); + bool *tep_is_local_bigendian*(struct tep_handle pass:[*]_tep_); + void *tep_set_local_bigendian*(struct tep_handle pass:[*]_tep_, enum tep_endian _endian_); + +Control library logs: + int *tep_set_loglevel*(enum tep_loglevel _level_); + +KVM plugin calllbacks: (Defined by the application and complied with -rdynamic) + const char pass:[*]*tep_plugin_kvm_get_func*(struct tep_event pass:[*]event, + struct tep_record pass:[*]record, + unsigned long long pass:[*]paddr); + void *tep_plugin_kvm_put_func*(const char pass:[*]func); + +Trace sequences: +*#include <trace-seq.h>* + void *trace_seq_init*(struct trace_seq pass:[*]_s_); + void *trace_seq_reset*(struct trace_seq pass:[*]_s_); + void *trace_seq_destroy*(struct trace_seq pass:[*]_s_); + int *trace_seq_printf*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, ...); + int *trace_seq_vprintf*(struct trace_seq pass:[*]_s_, const char pass:[*]_fmt_, va_list _args_); + int *trace_seq_puts*(struct trace_seq pass:[*]_s_, const char pass:[*]_str_); + int *trace_seq_putc*(struct trace_seq pass:[*]_s_, unsigned char _c_); + void *trace_seq_terminate*(struct trace_seq pass:[*]_s_); + int *trace_seq_do_fprintf*(struct trace_seq pass:[*]_s_, FILE pass:[*]_fp_); + int *trace_seq_do_printf*(struct trace_seq pass:[*]_s_); + +kbuffer parsing: +#include <kbuffer.h> + struct kbuffer pass:[*]*kbuffer_alloc*(enum kbuffer_long_size _size_, enum kbuffer_endian _endian_); + void *kbuffer_free*(struct kbuffer pass:[*]_kbuf_); + int *kbuffer_load_subbuffer*(struct kbuffer pass:[*]_kbuf_, void pass:[*]_subbuffer_); + int *kbuffer_subbuffer_size*(struct kbuffer pass:[*]_kbuf); + int *kbuffer_start_of_data*(struct kbuffer pass:[*]_kbuf_); + unsigned long long *kbuffer_timestamp*(struct kbuffer pass:[*]_kbuf_); + unsigned long long *kbuffer_subbuf_timestamp*(struct kbuffer pass:[*]_kbuf_, void pass:[*]_subbuf_); + void pass:[*]*kbuffer_read_event*(struct kbuffer pass:[*]_kbuf_, unsigned long long pass:[*]_ts_); + void pass:[*]*kbuffer_next_event*(struct kbuffer pass:[*]_kbuf_, unsigned long long pass:[*]_ts_); + void pass:[*]*kbuffer_read_at_offset*(struct kbuffer pass:[*]_kbuf_, int _offset_, unsigned long long pass:[*]_ts_); + int *kbuffer_missed_events*(struct kbuffer pass:[*]_kbuf_); + int *kbuffer_event_size*(struct kbuffer pass:[*]_kbuf_); + int *kbuffer_curr_size*(struct kbuffer pass:[*]_kbuf_); + int *kbuffer_curr_offset*(struct kbuffer pass:[*]_kbuf_); + int *kbuffer_curr_index*(struct kbuffer pass:[*]_kbuf_); +-- + +DESCRIPTION +----------- +The libtraceevent(3) library provides APIs to access kernel tracepoint events, +located in the tracefs file system under the events directory. + +ENVIRONMENT +----------- +[verse] +-- +TRACEEVENT_PLUGIN_DIR + Additional plugin directory. All shared object files, located in this directory will be loaded as traceevent plugins. +-- + +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*trace-seq.h* + Header file to include in order to have access to trace sequences related APIs. + Trace sequences are used to allow a function to call several other functions + to create a string of data to use. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ diff --git a/Documentation/manpage-1.72.xsl b/Documentation/manpage-1.72.xsl new file mode 100644 index 0000000..b4d315c --- /dev/null +++ b/Documentation/manpage-1.72.xsl @@ -0,0 +1,14 @@ +<!-- manpage-1.72.xsl: + special settings for manpages rendered from asciidoc+docbook + handles peculiarities in docbook-xsl 1.72.0 --> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + version="1.0"> + +<xsl:import href="manpage-base.xsl"/> + +<!-- these are the special values for the roff control characters + needed for docbook-xsl 1.72.0 --> +<xsl:param name="git.docbook.backslash">▓</xsl:param> +<xsl:param name="git.docbook.dot" >⌂</xsl:param> + +</xsl:stylesheet> diff --git a/Documentation/manpage-base.xsl b/Documentation/manpage-base.xsl new file mode 100644 index 0000000..a264fa6 --- /dev/null +++ b/Documentation/manpage-base.xsl @@ -0,0 +1,35 @@ +<!-- manpage-base.xsl: + special formatting for manpages rendered from asciidoc+docbook --> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + version="1.0"> + +<!-- these params silence some output from xmlto --> +<xsl:param name="man.output.quietly" select="1"/> +<xsl:param name="refentry.meta.get.quietly" select="1"/> + +<!-- convert asciidoc callouts to man page format; + git.docbook.backslash and git.docbook.dot params + must be supplied by another XSL file or other means --> +<xsl:template match="co"> + <xsl:value-of select="concat( + $git.docbook.backslash,'fB(', + substring-after(@id,'-'),')', + $git.docbook.backslash,'fR')"/> +</xsl:template> +<xsl:template match="calloutlist"> + <xsl:value-of select="$git.docbook.dot"/> + <xsl:text>sp </xsl:text> + <xsl:apply-templates/> + <xsl:text> </xsl:text> +</xsl:template> +<xsl:template match="callout"> + <xsl:value-of select="concat( + $git.docbook.backslash,'fB', + substring-after(@arearefs,'-'), + '. ',$git.docbook.backslash,'fR')"/> + <xsl:apply-templates/> + <xsl:value-of select="$git.docbook.dot"/> + <xsl:text>br </xsl:text> +</xsl:template> + +</xsl:stylesheet> diff --git a/Documentation/manpage-bold-literal.xsl b/Documentation/manpage-bold-literal.xsl new file mode 100644 index 0000000..608eb5d --- /dev/null +++ b/Documentation/manpage-bold-literal.xsl @@ -0,0 +1,17 @@ +<!-- manpage-bold-literal.xsl: + special formatting for manpages rendered from asciidoc+docbook --> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + version="1.0"> + +<!-- render literal text as bold (instead of plain or monospace); + this makes literal text easier to distinguish in manpages + viewed on a tty --> +<xsl:template match="literal"> + <xsl:value-of select="$git.docbook.backslash"/> + <xsl:text>fB</xsl:text> + <xsl:apply-templates/> + <xsl:value-of select="$git.docbook.backslash"/> + <xsl:text>fR</xsl:text> +</xsl:template> + +</xsl:stylesheet> diff --git a/Documentation/manpage-normal.xsl b/Documentation/manpage-normal.xsl new file mode 100644 index 0000000..a48f5b1 --- /dev/null +++ b/Documentation/manpage-normal.xsl @@ -0,0 +1,13 @@ +<!-- manpage-normal.xsl: + special settings for manpages rendered from asciidoc+docbook + handles anything we want to keep away from docbook-xsl 1.72.0 --> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + version="1.0"> + +<xsl:import href="manpage-base.xsl"/> + +<!-- these are the normal values for the roff control characters --> +<xsl:param name="git.docbook.backslash">\</xsl:param> +<xsl:param name="git.docbook.dot" >.</xsl:param> + +</xsl:stylesheet> diff --git a/Documentation/manpage-suppress-sp.xsl b/Documentation/manpage-suppress-sp.xsl new file mode 100644 index 0000000..a63c763 --- /dev/null +++ b/Documentation/manpage-suppress-sp.xsl @@ -0,0 +1,21 @@ +<!-- manpage-suppress-sp.xsl: + special settings for manpages rendered from asciidoc+docbook + handles erroneous, inline .sp in manpage output of some + versions of docbook-xsl --> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + version="1.0"> + +<!-- attempt to work around spurious .sp at the tail of the line + that some versions of docbook stylesheets seem to add --> +<xsl:template match="simpara"> + <xsl:variable name="content"> + <xsl:apply-templates/> + </xsl:variable> + <xsl:value-of select="normalize-space($content)"/> + <xsl:if test="not(ancestor::authorblurb) and + not(ancestor::personblurb)"> + <xsl:text> </xsl:text> + </xsl:if> +</xsl:template> + +</xsl:stylesheet> |