summaryrefslogtreecommitdiffstats
path: root/Documentation/libtracefs-eprobes.txt
blob: a96ad1b81783ad27e66544af117fe06db9ac827e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
libtracefs(3)
=============

NAME
----
tracefs_eprobe_alloc - Allocate new event probe (eprobe)

SYNOPSIS
--------
[verse]
--
*#include <tracefs.h>*

struct tracefs_dynevent pass:[*]
*tracefs_eprobe_alloc*(const char pass:[*]_system_, const char pass:[*]_event_,
		       const char pass:[*]_target_system_, const char pass:[*]_target_event_,
		       const char pass:[*]_fetchargs_);
--

DESCRIPTION
-----------
*tracefs_eprobe_alloc*() allocates a new eprobe context. The ebrobe is not configured in the system.
The new eprobe will be in the _system_ group (or eprobes if _system_ is NULL) and have the name of
_event_. The eprobe will be attached to _target_event_, located in _target_system_. The list of
arguments, described in _fetchargs_, will be fetched from _target_event_. The returned pointer to
the event probe must be freed with *tracefs_dynevent_free*().


RETURN VALUE
------------
The *tracefs_eprobe_alloc*() API returns a pointer to an allocated tracefs_dynevent structure,
describing the event probe. This pointer must be freed by *tracefs_dynevent_free*(3). Note, this
only allocates a descriptor representing the eprobe. It does not modify the running system. On error
NULL is returned.

EXAMPLE
-------
[source,c]
--
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

#include <tracefs.h>

static struct tep_event *open_event;
static struct tep_format_field *file_field;

static int callback(struct tep_event *event, struct tep_record *record,
		    int cpu, void *data)
{
	struct trace_seq seq;

	trace_seq_init(&seq);
	tep_print_event(event->tep, &seq, record, "%d-%s: ", TEP_PRINT_PID, TEP_PRINT_COMM);

	if (event->id == open_event->id) {
		trace_seq_puts(&seq, "open file='");
		tep_print_field(&seq, record->data, file_field);
		trace_seq_puts(&seq, "'\n");
	}

	trace_seq_terminate(&seq);
	trace_seq_do_printf(&seq);
	trace_seq_destroy(&seq);

	return 0;
}

static pid_t run_exec(char **argv, char **env)
{
	pid_t pid;

	pid = fork();
	if (pid)
		return pid;

	execve(argv[0], argv, env);
	perror("exec");
	exit(-1);
}

const char *myprobe = "my_eprobes";

int main (int argc, char **argv, char **env)
{
	struct tracefs_dynevent *eprobe;
	struct tracefs_instance *instance;
	struct tep_handle *tep;
	const char *sysnames[] = { myprobe, NULL };
	pid_t pid;

	if (argc < 2) {
		printf("usage: %s command\n", argv[0]);
		exit(-1);
	}

	instance = tracefs_instance_create("exec_open");
	if (!instance) {
		perror("creating instance");
		exit(-1);
	}

	tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_EPROBE, true);

	eprobe = tracefs_eprobe_alloc(myprobe, "sopen", "syscalls", "sys_enter_openat2",
				      "file=+0($filename):ustring");
	if (!eprobe) {
		perror("allocating event probe");
		exit(-1);
	}

	if (tracefs_dynevent_create(eprobe)) {
		perror("creating event probe");
		exit(-1);
	}

	tep = tracefs_local_events_system(NULL, sysnames);
	if (!tep) {
		perror("reading events");
		exit(-1);
	}

	open_event = tep_find_event_by_name(tep, myprobe, "sopen");
	file_field = tep_find_field(open_event, "file");

	tracefs_event_enable(instance, myprobe, "sopen");
	pid = run_exec(&argv[1], env);

	/* Let the child start to run */
	sched_yield();

	do {
		tracefs_load_cmdlines(NULL, tep);
		tracefs_iterate_raw_events(tep, instance, NULL, 0, callback, NULL);
	} while (waitpid(pid, NULL, WNOHANG) != pid);

	/* Will disable the events */
	tracefs_dynevent_destroy(eprobe, true);
	tracefs_dynevent_free(eprobe);
	tracefs_instance_destroy(instance);
	tep_free(tep);

	return 0;
}
--

FILES
-----
[verse]
--
*tracefs.h*
	Header file to include in order to have access to the library APIs.
*-ltracefs*
	Linker switch to add when building a program that uses the library.
--

SEE ALSO
--------
*libtracefs*(3),
*libtraceevent*(3),
*trace-cmd*(1)

AUTHOR
------
[verse]
--
*Steven Rostedt* <rostedt@goodmis.org>
*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>
--

REPORTING BUGS
--------------
Report bugs to  <linux-trace-devel@vger.kernel.org>

LICENSE
-------
libtracefs is Free Software licensed under the GNU LGPL 2.1

RESOURCES
---------
https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/

COPYING
-------
Copyright \(C) 2021 VMware, Inc. Free use of this software is granted under
the terms of the GNU Public License (GPL).