summaryrefslogtreecommitdiffstats
path: root/libosmocore-usdt.patch
blob: 97cf3c223a40b5e97b284af8b6a094e9e94bf892 (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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
From d08b4443ea1e5cd64a394832c4af685e06110fcc Mon Sep 17 00:00:00 2001
From: Harald Welte <laforge@osmocom.org>
Date: Sat, 26 Sep 2020 11:51:32 +0200
Subject: [PATCH] initial support for static userspace probes via systemtap

This adds a --enable-systemtap configure option, which will then
add static tracepoints to the generated libosmocore binary.

At this point, only two tracepoints are supported: stderr_start
and stderr_done.  They can be used to trace the amount of time
a libosmocore-using application spends in blocking calls to log
to stderr.

Change-Id: I7e1ab664241deb524c9582cbd1bec31af46c747e
---
 Makefile.am            |  2 +-
 configure.ac           | 33 +++++++++++++++++++++++++++++++++
 src/Makefile.am        | 12 ++++++++++++
 src/logging.c          | 23 ++++++++++++++++++++++-
 src/probes.d           |  7 +++++++
 tapset/Makefile.am     | 22 ++++++++++++++++++++++
 tapset/libosmocore.stp | 18 ++++++++++++++++++
 7 files changed, 115 insertions(+), 2 deletions(-)
 create mode 100644 src/probes.d
 create mode 100644 tapset/Makefile.am
 create mode 100644 tapset/libosmocore.stp

diff --git a/Makefile.am b/Makefile.am
index f2a05a96..ab2aad92 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
 ACLOCAL_AMFLAGS = -I m4
 
 AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
-SUBDIRS = include src src/vty src/codec src/gsm src/coding src/gb src/ctrl src/sim src/pseudotalloc src/usb utils tests
+SUBDIRS = include src src/vty src/codec src/gsm src/coding src/gb src/ctrl src/sim src/pseudotalloc src/usb utils tapset tests
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = libosmocore.pc libosmocodec.pc libosmovty.pc libosmogsm.pc \
diff --git a/configure.ac b/configure.ac
index b07a3bd6..e26d8a8b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -392,6 +392,38 @@ AC_MSG_CHECKING([whether to enable ARM NEON instructions support])
 AC_MSG_RESULT([$neon])
 AM_CONDITIONAL(HAVE_NEON, [test "x$neon" != "xno"])
 
+#
+# SystemTap support
+#
+AC_MSG_CHECKING([whether to include systemtap tracing support])
+AC_ARG_ENABLE([systemtap],
+	      [AS_HELP_STRING([--enable-systemtap],
+			      [Enable inclusion of systemtap trace support])],
+	      [ENABLE_SYSTEMTAP="${enableval}"], [ENABLE_SYSTEMTAP='no'])
+AM_CONDITIONAL([ENABLE_SYSTEMTAP], [test x$ENABLE_SYSTEMTAP = xyes])
+AC_MSG_RESULT(${ENABLE_SYSTEMTAP})
+
+if test "x${ENABLE_SYSTEMTAP}" = xyes; then
+  # Additional configuration for --enable-systemtap is HERE
+  AC_CHECK_PROGS(DTRACE, dtrace)
+  if test -z "$DTRACE"; then
+    AC_MSG_ERROR([dtrace not found])
+  fi
+  AC_CHECK_HEADER([sys/sdt.h], [SDT_H_FOUND='yes'],
+                [SDT_H_FOUND='no';
+                   AC_MSG_ERROR([systemtap support needs sys/sdt.h header])])
+  AC_DEFINE([HAVE_SYSTEMTAP], [1], [Define to 1 if using SystemTap probes.])
+  AC_ARG_WITH([tapset-install-dir],
+	      [AS_HELP_STRING([--with-tapset-install-dir],
+	         [The absolute path where the tapset dir will be installed])],
+	      [if test "x${withval}" = x; then
+		 ABS_TAPSET_DIR="\$(datadir)/systemtap/tapset"
+	       else
+		 ABS_TAPSET_DIR="${withval}"
+	       fi], [ABS_TAPSET_DIR="\$(datadir)/systemtap/tapset"])
+  AC_SUBST(ABS_TAPSET_DIR)
+fi
+
 
 OSMO_AC_CODE_COVERAGE
 
@@ -446,6 +478,7 @@ AC_OUTPUT(
 	src/gb/Makefile
 	src/ctrl/Makefile
 	src/pseudotalloc/Makefile
+	tapset/Makefile
 	tests/Makefile
 	tests/atlocal
 	utils/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index 891b4a6f..f03ce559 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -28,6 +28,7 @@ libosmocore_la_SOURCES = context.c timer.c timer_gettimeofday.c timer_clockgetti
 			 sockaddr_str.c \
 			 use_count.c \
 			 exec.c \
+			 probes.d \
 			 $(NULL)
 
 if HAVE_SSSE3
@@ -71,5 +72,16 @@ if ENABLE_SERIAL
 libosmocore_la_SOURCES += serial.c
 endif
 
+if ENABLE_SYSTEMTAP
+probes.h: probes.d
+	$(DTRACE) -C -h -s $< -o $@
+
+probes.lo: probes.d
+	$(LIBTOOL) --mode=compile $(AM_V_lt) --tag=CC env CFLAGS="$(CFLAGS)" $(DTRACE) -C -G -s $< -o $@
+
+BUILT_SOURCES += probes.h probes.lo
+libosmocore_la_LIBADD += probes.lo
+endif
+
 crc%gen.c: crcXXgen.c.tpl
 	$(AM_V_GEN)sed -e's/XX/$*/g' $< > $@
diff --git a/src/logging.c b/src/logging.c
index 212b0b99..b480f0b5 100644
--- a/src/logging.c
+++ b/src/logging.c
@@ -44,6 +44,17 @@
 #include <syslog.h>
 #endif
 
+#ifdef HAVE_SYSTEMTAP
+/* include the generated probes header and put markers in code */
+#include "probes.h"
+#define TRACE(probe) probe
+#define TRACE_ENABLED(probe) probe ## _ENABLED()
+#else
+/* Wrap the probe to allow it to be removed when no systemtap available */
+#define TRACE(probe)
+#define TRACE_ENABLED(probe) (0)
+#endif /* HAVE_SYSTEMTAP */
+
 #include <time.h>
 #include <sys/time.h>
 #include <errno.h>
@@ -642,9 +653,11 @@ void logp2(int subsys, unsigned int level, const char *file, int line, int cont,
 {
 	va_list ap;
 
+	LIBOSMOCORE_LOG_START();
 	va_start(ap, format);
 	osmo_vlogp(subsys, level, file, line, cont, format, ap);
 	va_end(ap);
+	LIBOSMOCORE_LOG_DONE();
 }
 
 /*! Register a new log target with the logging core
@@ -831,6 +844,14 @@ void log_set_category_filter(struct log_target *target, int category,
 }
 
 #if (!EMBEDDED)
+static void _stderr_output(struct log_target *target, unsigned int level,
+			 const char *log)
+{
+	LIBOSMOCORE_STDERR_START(strlen(log));
+	fprintf(target->tgt_file.out, "%s", log);
+	fflush(target->tgt_file.out);
+	LIBOSMOCORE_STDERR_DONE();
+}
 static void _file_output(struct log_target *target, unsigned int level,
 			 const char *log)
 {
@@ -898,7 +919,7 @@ struct log_target *log_target_create_stderr(void)
 
 	target->type = LOG_TGT_TYPE_STDERR;
 	target->tgt_file.out = stderr;
-	target->output = _file_output;
+	target->output = _stderr_output;
 	return target;
 #else
 	return NULL;
diff --git a/src/probes.d b/src/probes.d
new file mode 100644
index 00000000..12840577
--- /dev/null
+++ b/src/probes.d
@@ -0,0 +1,7 @@
+provider libosmocore {
+	probe stderr_start(int); /* (int number of octets) */
+	probe stderr_done()
+
+	probe log_start();
+	probe log_done()
+};
diff --git a/tapset/Makefile.am b/tapset/Makefile.am
new file mode 100644
index 00000000..a07a3b1d
--- /dev/null
+++ b/tapset/Makefile.am
@@ -0,0 +1,22 @@
+.PHONY: clean-local install-data-hook uninstall-local
+
+EXTRA_DIST = libosmocore.stp
+TAPSET_FILES = $(EXTRA_DIST)
+TAPSET_INSTALL_DIR = $(DESTDIR)@ABS_TAPSET_DIR@
+
+if ENABLE_SYSTEMTAP
+all-local: $(TAPSET_FILES)
+
+clean-local:
+
+install-data-hook:
+	$(MKDIR_P) $(TAPSET_INSTALL_DIR)
+	$(INSTALL_DATA) $(TAPSET_FILES) $(TAPSET_INSTALL_DIR)
+
+uninstall-local:
+	@list='$(TAPSET_FILES)'; for p in $$list; do \
+	  echo " rm -f '$(TAPSET_INSTALL_DIR)/$$p'"; \
+	  rm -f "$(TAPSET_INSTALL_DIR)/$$p"; \
+	done
+
+endif
diff --git a/tapset/libosmocore.stp b/tapset/libosmocore.stp
new file mode 100644
index 00000000..10fa7b24
--- /dev/null
+++ b/tapset/libosmocore.stp
@@ -0,0 +1,18 @@
+/* libosmocore tapset
+ *
+ * This file is part of libosmocore.
+ *
+ * Each probe defines the probe name and a full probestr which consist of the probe name and between
+ * brackets all argument names and values.
+ */
+
+probe libosmocore_stderr_start = process("libosmocore").mark("stderr_start")
+{
+ count = $arg1;
+ probestr = sprintf("%s(count=%d), $$name, count);
+}
+
+probe libosmocore_stderr_done = process("libosmocore").mark("stderr_done")
+{
+ probestr = sprintf("%s", $$name);
+}
-- 
2.28.0