RECORDER(3)
β¨ RECORDER, RECORDER_DEFINE, RECORDER_DECLARE β¨
okay bestie, this is a page from the Recorder Library and it's literally all about declaring and defining the little buffers that hold your events π
πΈ NAME πΈ
RECORDER, RECORDER_DEFINE, RECORDER_DECLARE β declare and define buffers to record events π
π SYNOPSIS π
#include <recorder/recorder.h>
#define RECORDER(recname, recsize, rechelp) ...
#define RECORDER_DEFINE(recname, recsize, rechelp) ...
#define RECORDER_DECLARE(recname) ...
π¦ DESCRIPTION π¦
so the RECORDER() macro defines a buffer named recname that can store up to recsize events, and those events get used by the record(3) function. the rechelp string is the self-documentation β it describes what kinds of events live in that buffer. and the way you actually see that self-documentation? you turn on the help trace, which is described over in recorder_set_trace(3). iykyk β¨
the RECORDER_DECLARE() macro just declares an event recorder, and it's the one you're allowed to drop in header files π
the RECORDER_DEFINE() macro is literally just an alias for RECORDER(). the vibe is intentional though:
- use
RECORDER()for event recorders that are local to a single file π - use a
RECORDER_DECLARE()in the header file paired with aRECORDER_DEFINE()in a non-header file for event recorders that get shared across multiple translation units π€
these macros need to live at file scope, aka exactly where a function definition or a global variable is allowed. no putting them inside functions, bestie π
every single recorder has a trace value associated with it β that's an integer value you can read with RECORDER_TRACE(3). see also recorder_trace_set(3). π
π₯ EXAMPLES π₯
the program below records its input arguments, and it crashes if you pass crash as the first command-line argument. (yes it crashes on purpose, it's a demo, breathe π)
#include <recorder/recorder.h>
#include <string.h>
RECORDER(program_args, 32, "Program command-line arguments");
int main(int argc, char **argv)
{
int a;
recorder_dump_on_common_signals(0, 0);
for (a = 0; a < argc; a++)
record(program_args, "Argument %d is %+s", a, argv[a]);
if (argc >= 2 && strcmp(argv[1], "crash") == 0)
{
char *ptr = NULL;
strcpy(ptr, argv[1]);
}
}
when a crash happens, the events that got recorded earlier get printed out on the console. iconic πβ¨
next up: the program below is an instrumented version of the classic recursive Fibonacci computation. it uses several recorders for different types of events, and it activates warnings and errors in a way you can configure by setting an environment variable π
#include <recorder/recorder.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
RECORDER(fib_main, 32, "Loops in fib function");
RECORDER(fib_loops, 32, "Loops in fib function");
RECORDER(fib_warning, 32, "Warnings in fib function");
RECORDER(fib_error, 32, "Errors in fib function");
int fib(int n)
{
if (n <= 1) {
if (n < 0)
record(fib_error, "fib is undefined for negative value %d", n);
return n;
}
record(fib_loops, "Computing fib(%d)", n);
int result = fib(n-1) + fib(n-2);
record(fib_loops, "Computed fib(%d) = %d", n, result);
return result;
}
int main(int argc, char **argv)
{
int a;
recorder_dump_on_common_signals(0, 0);
recorder_trace_set(".*_warning=35 .*_error");
recorder_trace_set(getenv("FIB_TRACES"));
for (a = 1; a < argc; a++) {
int n = atoi(argv[a]);
if (n >= RECORDER_TRACE(fib_warning))
record(fib_warning, "Computing for %d may take a while", n);
printf("fib(%d) = %d0, n, fib(n));
if (n >= RECORDER_TRACE(fib_warning))
record(fib_warning, "Computation for %d finally completed", n);
}
}
this program will produce an output similar to the following π
% fib 1 2 3 4 10 20 30 35 10 40 -1
fib(1) = 1
fib(2) = 1
fib(3) = 2
fib(4) = 3
fib(10) = 55
fib(20) = 6765
fib(30) = 832040
[2714667 0.177725] fib_warning: Computing for 35 may take a while
fib(35) = 9227465
[32575370 1.859156] fib_warning: Computation for 35 finally completed
fib(10) = 55
[32575547 1.859171] fib_warning: Computing for 40 may take a while
fib(40) = 102334155
[363735828 20.527882] fib_warning: Computation for 40 finally completed
[363735829 20.527887] fib_error: fib is undefined for negative value -1
fib(-1) = -1
about those trace outputs: the first column is the number of events that were recorded. the second column is the time in seconds since the program started β±οΈ (yes, that typo-ish capital in the original says THe β that's just how it is, no cap).
the same program can also be run with additional tracing or warnings, like so:
% FIB_TRACES="recorder_location fib_loops fib_warning=3" /tmp/fib 3 4
/tmp/fib.c:33:[82 0.000496] fib_warning: Computing for 3 may take a while
/tmp/fib.c:18:[83 0.000561] fib_loops: Computing fib(3)
/tmp/fib.c:18:[84 0.000570] fib_loops: Computing fib(2)
/tmp/fib.c:20:[85 0.000575] fib_loops: Computed fib(2) = 1
/tmp/fib.c:20:[86 0.000581] fib_loops: Computed fib(3) = 2
fib(3) = 2
/tmp/fib.c:36:[87 0.000590] fib_warning: Computation for 3 finally completed
/tmp/fib.c:33:[88 0.000596] fib_warning: Computing for 4 may take a while
/tmp/fib.c:18:[89 0.000601] fib_loops: Computing fib(4)
/tmp/fib.c:18:[90 0.000607] fib_loops: Computing fib(3)
/tmp/fib.c:18:[91 0.000612] fib_loops: Computing fib(2)
/tmp/fib.c:20:[92 0.000619] fib_loops: Computed fib(2) = 1
/tmp/fib.c:20:[93 0.000625] fib_loops: Computed fib(3) = 2
/tmp/fib.c:18:[94 0.000664] fib_loops: Computing fib(2)
/tmp/fib.c:20:[95 0.000707] fib_loops: Computed fib(2) = 1
/tmp/fib.c:20:[96 0.000724] fib_loops: Computed fib(4) = 3
fib(4) = 3
/tmp/fib.c:36:[97 0.000741] fib_warning: Computation for 4 finally completed
π BUGS π
if you use these macros incorrectly, you're generally gonna get nonsensical compiler diagnostics. like, the compiler will start speaking in riddles. that's the punishment π
bugs should be reported using https://github.com/c3d/recorder/issues β pls actually report them, don't just suffer in silence bestie π«Ά
π SEE ALSO π
record(3),record_fast(3)recorder_trace_set(3)RECORDER_TRACE(3)recorder_dump(3),recorder_dump_for(3),recorder_configure_output(3),recorder_configure_show(3)recorder_configure_format(3),recorder_configure_type(3)
additional documentation and tutorials can be found at https://github.com/c3d/recorder πβ¨
π AUTHOR π
written by Christophe de Dinechin π
okay that's the whole thing, you're officially certified in recorder macros, slay π
this was version 1.0, dated 2019-03-09, and it's the RECORDER(3) page, so go forth and record your events, bestie ππ
π¦ where this page comes from
- fedora 43: recorder-devel 1.2.2-12.fc43 Β· LGPLv2+
- fedora 43: recorder-devel 1.2.2-12.fc43 Β· LGPLv2+
- fedora 43: recorder-devel 1.2.2-13.fc43 Β· LGPLv2+
- fedora 43: recorder-devel 1.2.2-13.fc43 Β· LGPLv2+
- fedora 44: recorder-devel 1.2.3-.fc44 Β· LGPLv2+
- fedora 44: recorder-devel 1.2.3-.fc44 Β· LGPLv2+
- fedora 44: recorder-devel 1.2.3-.fc44.1 Β· LGPLv2+
- fedora 44: recorder-devel 1.2.3-.fc44.1 Β· LGPLv2+
- (C) 2019-2020 Christophe de Dinechin <christophe@dinechin.org>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms