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