1
2
3recorder_dump(3) Recorder Library recorder_dump(3)
4
5
6
8 recorder_dump - Dump all recorder entries
9 recorder_dump_for - Dump selected recorders
10 recorder_sort - Fine-controlled recorder dump
11 recorder_dump_on_signal - Dump the recorder when receiving a signal
12 recorder_dump_on_common_signals - Dump the recorder for standard sig‐
13 nals
14
15
16
18 #include <recorder/recorder.h>
19
20 typedef unsigned (*recorder_show_fn) (const char *text,
21 size_tlen,
22 void *output);
23 typedef void (*recorder_format_fn)(recorder_show_fn show,
24 void *output,
25 const char * label,
26 const char *location,
27 uintptr_torder,
28 uintptr_ttimestamp,
29 const char *message);
30 typedef size_t (*recorder_type_fn)(intptr_t trace,
31 const char *format,
32 char *buffer,
33 size_tlength,
34 uintptr_tdata);
35
36 unsigned recorder_dump(void);
37 unsigned recorder_dump_for(const char *pattern);
38 unsigned recorder_sort(const char *pattern,
39 recorder_format_fn format,
40 recorder_show_fn show,
41 void * show_arg);
42 void recorder_dump_on_signal(int signal);
43 void recorder_dump_on_common_signals(unsigned add,
44 unsigned remove);
45
47 The recorder_dump() function dumps the content of all the event
48 recorders, in the order in which they were recorded. The
49 recorder_dump_for() function only dumps the recorders selected by the
50 regular expression pattern. The recorder_sort() function dumps the
51 recorders selected by regular expression pattern using format to format
52 an event record, show to show it, and passing show_arg to the function
53 show.
54
55
56 Calls to recorder_dump() and recorder_dump_for() are equivalents to
57 calls to recorder_sort where standard default values for format, show
58 and arg. These values can be changed using recorder_configure_for‐
59 mat(3), recorder_configure_show(3) and recorder_configure_output(3)
60 respectively.
61
62
63 The recorder_dump_on_signal() function ensures that recorder_dump() is
64 called if the programs receives the given signal. The
65 recorder_dump_on_common_signals() ensures that a recorder dump happens
66 if any of a common set of signals is received by the program (SIGQUIT,
67 SIGILL, SIGABRT, SIGBUS, SIGSEGV, SIGSYS, SIGXCPU, SIGXFSZ, SIGINFO,
68 SIGUSR1, SIGUSR2, SIGSTKFLT and SIGPWR, insofar as they are defined for
69 the operating system). The add and remove are bit masks that can be
70 used to add or remove other signals compared to the default list.
71
72
73
75 The recorder_dump(), recorder_dump_for() and recorder_sort() functions
76 return the number of event records that were dumped.
77
78
79
81 The recorder_dump_on_common_signals() function also reads the following
82 environment variables:
83
84
85 RECORDER_TRACES
86 A trace description, in the format expected by
87 recorder_trace_set(3).
88
89
90 RECORDER_TWEAKS
91 Like RECORDER_TRACES, but normally used for tweaking configura‐
92 tion values as opposed to tracing.
93
94
95 RECORDER_DUMP
96 Activates a background thread to dump the given pattern at regu‐
97 lar intervals.
98
99
100
102 The program below records its input arguments, and crashes if passed
103 crash as the first command-line argument.
104
105 #include <recorder/recorder.h>
106 #include <string.h>
107
108 RECORDER(program_args, 32, "Program command-line arguments");
109 int main(int argc, char **argv)
110 {
111 int a;
112 recorder_dump_on_common_signals(0, 0);
113 for (a = 0; a < argc; a++)
114 record(program_args, "Argument %d is %+s", a, argv[a]);
115
116 if (argc >= 2 && strcmp(argv[1], "crash") == 0)
117 {
118 char *ptr = NULL;
119 strcpy(ptr, argv[1]);
120 }
121 }
122
123 When a crash occurs, previously recorded events are printed out on the
124 console.
125
126
127 The program below is an instrumented version of the classical recursive
128 Fibonacci computation. It uses several recorders corresponding to dif‐
129 ferent types of events, and activates warnings and errors in a way that
130 can be configured by setting an environment variable.
131
132 #include <recorder/recorder.h>
133 #include <string.h>
134 #include <stdio.h>
135 #include <stdlib.h>
136
137 RECORDER(fib_main, 32, "Loops in fib function");
138 RECORDER(fib_loops, 32, "Loops in fib function");
139 RECORDER(fib_warning, 32, "Warnings in fib function");
140 RECORDER(fib_error, 32, "Errors in fib function");
141
142 int fib(int n)
143 {
144 if (n <= 1) {
145 if (n < 0)
146 record(fib_error, "fib is undefined for negative value %d", n);
147 return n;
148 }
149 record(fib_loops, "Computing fib(%d)", n);
150 int result = fib(n-1) + fib(n-2);
151 record(fib_loops, "Computed fib(%d) = %d", n, result);
152 return result;
153 }
154
155 int main(int argc, char **argv)
156 {
157 int a;
158 recorder_dump_on_common_signals(0, 0);
159 recorder_trace_set(".*_warning=35 .*_error");
160 recorder_trace_set(getenv("FIB_TRACES"));
161 for (a = 1; a < argc; a++) {
162 int n = atoi(argv[a]);
163 if (n >= RECORDER_TRACE(fib_warning))
164 record(fib_warning, "Computing for %d may take a while", n);
165 printf("fib(%d) = %d0, n, fib(n));
166 if (n >= RECORDER_TRACE(fib_warning))
167 record(fib_warning, "Computation for %d finally completed", n);
168 }
169 }
170
171 This program will produce an output similar to the following:
172
173 % fib 1 2 3 4 10 20 30 35 10 40 -1
174 fib(1) = 1
175 fib(2) = 1
176 fib(3) = 2
177 fib(4) = 3
178 fib(10) = 55
179 fib(20) = 6765
180 fib(30) = 832040
181 [2714667 0.177725] fib_warning: Computing for 35 may take a while
182 fib(35) = 9227465
183 [32575370 1.859156] fib_warning: Computation for 35 finally completed
184 fib(10) = 55
185 [32575547 1.859171] fib_warning: Computing for 40 may take a while
186 fib(40) = 102334155
187 [363735828 20.527882] fib_warning: Computation for 40 finally completed
188 [363735829 20.527887] fib_error: fib is undefined for negative value -1
189 fib(-1) = -1
190 The first column in trace outputs is the number of events that were
191 recorded. THe second column is the time in seconds since the program
192 started.
193
194
195 The same program can also be run with additional tracing or warnings,
196 for example:
197
198 % FIB_TRACES="recorder_location fib_loops fib_warning=3" /tmp/fib 3 4
199 /tmp/fib.c:33:[82 0.000496] fib_warning: Computing for 3 may take a while
200 /tmp/fib.c:18:[83 0.000561] fib_loops: Computing fib(3)
201 /tmp/fib.c:18:[84 0.000570] fib_loops: Computing fib(2)
202 /tmp/fib.c:20:[85 0.000575] fib_loops: Computed fib(2) = 1
203 /tmp/fib.c:20:[86 0.000581] fib_loops: Computed fib(3) = 2
204 fib(3) = 2
205 /tmp/fib.c:36:[87 0.000590] fib_warning: Computation for 3 finally completed
206 /tmp/fib.c:33:[88 0.000596] fib_warning: Computing for 4 may take a while
207 /tmp/fib.c:18:[89 0.000601] fib_loops: Computing fib(4)
208 /tmp/fib.c:18:[90 0.000607] fib_loops: Computing fib(3)
209 /tmp/fib.c:18:[91 0.000612] fib_loops: Computing fib(2)
210 /tmp/fib.c:20:[92 0.000619] fib_loops: Computed fib(2) = 1
211 /tmp/fib.c:20:[93 0.000625] fib_loops: Computed fib(3) = 2
212 /tmp/fib.c:18:[94 0.000664] fib_loops: Computing fib(2)
213 /tmp/fib.c:20:[95 0.000707] fib_loops: Computed fib(2) = 1
214 /tmp/fib.c:20:[96 0.000724] fib_loops: Computed fib(4) = 3
215 fib(4) = 3
216 /tmp/fib.c:36:[97 0.000741] fib_warning: Computation for 4 finally completed
217
218
220 The current signal handling mechanism does not yet use sigaltstack(2)
221 and consequently is not robust to stack overflow. It is also known to
222 fail for repeated signals. SIGINFO (and the associated Control-T key‐
223 board shortcut) do not exist on Linux, which is a pity.
224
225
226 Bugs should be reported using https://github.com/c3d/recorder/issues.
227
228
229
231 RECORDER_DEFINE(3), RECORDER_DECLARE(3)
232 recorder_dump(3), recorder_dump_for(3),
233 recorder_configure_output(3), recorder_configure_show(3)
234 recorder_configure_format(3), recorder_configure_type(3)
235
236
237 Additional documentation and tutorials can be found at
238 https://github.com/c3d/recorder.
239
240
241
243 Written by Christophe de Dinechin
244
245
246
2471.0 2019-03-09 recorder_dump(3)