1
2
3record(3)                      Recorder Library                      record(3)
4
5
6

NAME

8       record, record_fast - Fast event logging in circular buffers
9
10
11

SYNOPSIS

13       #include <recorder/recorder.h>
14
15       ringidx_t record(recorder_name recname, const char *format, ...);
16       ringidx_t record_fast(recorder_name recname, const char *format, ...);
17

DESCRIPTION

19       The  record()  function  stores  an event in the recorder identified by
20       recname.  The event record includes a time stamp provided by  the  get‐
21       timeofday(3) function (or a similar absolute time function), as well as
22       the format string and up to 12 additional arguments. The format  string
23       should  follow the printf(3) conventions, with the exceptions and addi‐
24       tions indicated below.
25
26
27       The record_fast() reuses the time stamp of the previous record()  func‐
28       tion  for  the  same recorder, making it approximately twice as fast on
29       some modern systems. The cost difference should be in the order of  the
30       cost of a call like gettimeofday(3)
31
32
33       Event  recording  code  is designed to remain active in your program at
34       all times.  Unlike  typical  printf(3)  messages,  events  recorded  by
35       record()  are not generally intended to be seen immediately, but rather
36       to be shown laster, for example in case of crash. See recorder_dump(3).
37       Formatting only happens when the message is actually printed.
38
39
40       Events  can  also  be traced on a per-recorder basis. In that case, the
41       record() and record_fast() functions will immediately format their out‐
42       put. See recorder_set_trace(3)
43
44
45   Automatic end of line
46       Event  records are always printed on an individual line. It is not nec‐
47       essary to add a \n character at the end of the format string. If one is
48       present, it will have no effect.
49
50           record(my_recorder, "Hello");
51           record(my_recorder, "World0);
52
53
54       The  use of \n at other positions in the string is possible and has the
55       usual effect.
56
57
58   Formatting character strings: %s and %+s
59       Since formatting an event may happen  at  an  unknown  time  after  its
60       recording,  the  %s and S formats are treated like %p unless formatting
61       happens as part of tracing. If you are passing a character string  that
62       is  known  to be constant, or at least still valid when it will be for‐
63       matted, then you can use the %+s format instead.
64
65           const char *name[2] = { "false", "true" };
66           record(my_recorder, "Value %d is %+s", value, name[!!value]);
67
68
69
70   Extended format characters
71       It  is  possible  to  configure  additional  format   characters.   See
72       recorder_configure_type.   When  this  function is used, format strings
73       may deviate notably from the printf(3) standard, or may  conflict  with
74       other extensions to that standard.
75
76
77

RETURN VALUE

79       The  return  value  is  the  index of the event that was recorded. This
80       value is rarely useful and can generally be ignored.
81
82
83

EXAMPLES

85       The program below records its input arguments, and  crashes  if  passed
86       crash as the first command-line argument.
87
88           #include <recorder/recorder.h>
89           #include <string.h>
90
91           RECORDER(program_args, 32, "Program command-line arguments");
92           int main(int argc, char **argv)
93           {
94               int a;
95               recorder_dump_on_common_signals(0, 0);
96               for (a = 0; a < argc; a++)
97                   record(program_args, "Argument %d is %+s", a, argv[a]);
98
99               if (argc >= 2 && strcmp(argv[1], "crash") == 0)
100               {
101                   char *ptr = NULL;
102                   strcpy(ptr, argv[1]);
103               }
104           }
105
106       When  a crash occurs, previously recorded events are printed out on the
107       console.
108
109
110       The program below is an instrumented version of the classical recursive
111       Fibonacci  computation. It uses several recorders corresponding to dif‐
112       ferent types of events, and activates warnings and errors in a way that
113       can be configured by setting an environment variable.
114
115           #include <recorder/recorder.h>
116           #include <string.h>
117           #include <stdio.h>
118           #include <stdlib.h>
119
120           RECORDER(fib_main,    32, "Loops in fib function");
121           RECORDER(fib_loops,   32, "Loops in fib function");
122           RECORDER(fib_warning, 32, "Warnings in fib function");
123           RECORDER(fib_error,   32, "Errors in fib function");
124
125           int fib(int n)
126           {
127               if (n <= 1) {
128                   if (n < 0)
129                       record(fib_error, "fib is undefined for negative value %d", n);
130                   return n;
131               }
132               record(fib_loops, "Computing fib(%d)", n);
133               int result = fib(n-1) + fib(n-2);
134               record(fib_loops, "Computed fib(%d) = %d", n, result);
135               return result;
136           }
137
138           int main(int argc, char **argv)
139           {
140               int a;
141               recorder_dump_on_common_signals(0, 0);
142               recorder_trace_set(".*_warning=35 .*_error");
143               recorder_trace_set(getenv("FIB_TRACES"));
144               for (a = 1; a < argc; a++) {
145                   int n = atoi(argv[a]);
146                   if (n >= RECORDER_TRACE(fib_warning))
147                       record(fib_warning, "Computing for %d may take a while", n);
148                   printf("fib(%d) = %d0, n, fib(n));
149                   if (n >= RECORDER_TRACE(fib_warning))
150                       record(fib_warning, "Computation for %d finally completed", n);
151               }
152           }
153
154       This program will produce an output similar to the following:
155
156           % fib 1 2 3 4 10 20 30 35 10 40 -1
157           fib(1) = 1
158           fib(2) = 1
159           fib(3) = 2
160           fib(4) = 3
161           fib(10) = 55
162           fib(20) = 6765
163           fib(30) = 832040
164           [2714667 0.177725] fib_warning: Computing for 35 may take a while
165           fib(35) = 9227465
166           [32575370 1.859156] fib_warning: Computation for 35 finally completed
167           fib(10) = 55
168           [32575547 1.859171] fib_warning: Computing for 40 may take a while
169           fib(40) = 102334155
170           [363735828 20.527882] fib_warning: Computation for 40 finally completed
171           [363735829 20.527887] fib_error: fib is undefined for negative value -1
172           fib(-1) = -1
173       The  first  column  in  trace outputs is the number of events that were
174       recorded. THe second column is the time in seconds  since  the  program
175       started.
176
177
178       The  same  program can also be run with additional tracing or warnings,
179       for example:
180
181           % FIB_TRACES="recorder_location fib_loops fib_warning=3" /tmp/fib 3 4
182           /tmp/fib.c:33:[82 0.000496] fib_warning: Computing for 3 may take a while
183           /tmp/fib.c:18:[83 0.000561] fib_loops: Computing fib(3)
184           /tmp/fib.c:18:[84 0.000570] fib_loops: Computing fib(2)
185           /tmp/fib.c:20:[85 0.000575] fib_loops: Computed fib(2) = 1
186           /tmp/fib.c:20:[86 0.000581] fib_loops: Computed fib(3) = 2
187           fib(3) = 2
188           /tmp/fib.c:36:[87 0.000590] fib_warning: Computation for 3 finally completed
189           /tmp/fib.c:33:[88 0.000596] fib_warning: Computing for 4 may take a while
190           /tmp/fib.c:18:[89 0.000601] fib_loops: Computing fib(4)
191           /tmp/fib.c:18:[90 0.000607] fib_loops: Computing fib(3)
192           /tmp/fib.c:18:[91 0.000612] fib_loops: Computing fib(2)
193           /tmp/fib.c:20:[92 0.000619] fib_loops: Computed fib(2) = 1
194           /tmp/fib.c:20:[93 0.000625] fib_loops: Computed fib(3) = 2
195           /tmp/fib.c:18:[94 0.000664] fib_loops: Computing fib(2)
196           /tmp/fib.c:20:[95 0.000707] fib_loops: Computed fib(2) = 1
197           /tmp/fib.c:20:[96 0.000724] fib_loops: Computed fib(4) = 3
198           fib(4) = 3
199           /tmp/fib.c:36:[97 0.000741] fib_warning: Computation for 4 finally completed
200
201
202

BUGS

204       There is a limit to the number of  arguments  that  can  be  passed  to
205       record()  and  record_fast().  As of version 1.0, the maximum number is
206       12. If that number is exceeded, the compilation error  message  is  not
207       friendly.
208
209
210       Bugs should be reported using https://github.com/c3d/recorder/issues.
211
212
213

SEE ALSO

215       RECORDER_DEFINE(3), RECORDER_DECLARE(3)
216       recorder_trace_set(3) RECORDER_TRACE(3)
217       recorder_dump(3), recorder_dump_for(3),
218       recorder_configure_output(3), recorder_configure_show(3)
219       recorder_configure_format(3), recorder_configure_type(3)
220
221
222       Additional    documentation    and    tutorials   can   be   found   at
223       https://github.com/c3d/recorder.
224
225
226

AUTHOR

228       Written by Christophe de Dinechin
229
230
231
2321.0                               2019-03-09                         record(3)
Impressum