recorder_dump(3)
π recorder_dump β Recorder Library, bestie edition β¨
okay so first things first: this whole page lives in the Recorder Library (recorder_dump(3)), and it's literally the group chat for dumping everything your program secretly remembered. pull up a chair π«Ά
β¨ NAME β¨
recorder_dump β dump all the recorder entries π
recorder_dump_for β dump the selected recorders
recorder_sort β the fine-controlled, picky-picky recorder dump π
recorder_dump_on_signal β dump the recorder the second a signal shows up π
recorder_dump_on_common_signals β dump the recorder for the standard signals π
π¦ SYNOPSIS π¦
#include <recorder/recorder.h>
typedef unsigned (*recorder_show_fn) (const char *text,
size_tlen,
void *output);
typedef void (*recorder_format_fn)(recorder_show_fn show,
void *output,
const char * label,
const char *location,
uintptr_torder,
uintptr_ttimestamp,
const char *message);
typedef size_t (*recorder_type_fn)(intptr_t trace,
const char *format,
char *buffer,
size_tlength,
uintptr_tdata);
unsigned recorder_dump(void);
unsigned recorder_dump_for(const char *pattern);
unsigned recorder_sort(const char *pattern,
recorder_format_fn format,
recorder_show_fn show,
void * show_arg);
void recorder_dump_on_signal(int signal);
void recorder_dump_on_common_signals(unsigned add,
unsigned remove);
πΈ DESCRIPTION πΈ
recorder_dump() dumps the content of all the event recorders, in the order in which they were recorded. no reordering, no chaos, just vibes in chronological order β¨
recorder_dump_for() is the picky one: it only dumps the recorders selected by the regular expression pattern. it's giving "only my favorites" π
recorder_sort() dumps the recorders selected by regular expression pattern, but it does the whole thing your way β it uses format to format an event record, show to show it, and it passes show_arg along to the function show. full main character energy, you're in control π
calls to recorder_dump() and recorder_dump_for() are equivalents to calls to recorder_sort where standard default values for format, show and arg are used. and guess what, bestie β those values can be changed using recorder_configure_format(3), recorder_configure_show(3) and recorder_configure_output(3) respectively. so you can totally customize the fit π₯
recorder_dump_on_signal() makes sure that recorder_dump() gets called if the program receives the given signal. like, the moment it happens, boom, dump. π₯
recorder_dump_on_common_signals() makes sure a recorder dump happens if any of a common set of signals is received by the program β that set is SIGQUIT, SIGILL, SIGABRT, SIGBUS, SIGSEGV, SIGSYS, SIGXCPU, SIGXFSZ, SIGINFO, SIGUSR1, SIGUSR2, SIGSTKFLT and SIGPWR, insofar as they are defined for the operating system (so like, only the ones that actually exist where you're running, no cap).
the add and remove are bit masks that you can use to add or remove other signals compared to the default list. so you can add your own faves and drop the ones you don't vibe with π
β RETURN VALUE β
recorder_dump(), recorder_dump_for() and recorder_sort() return the number of event records that were dumped. a lil receipt for your dump, periodt π
π ENVIRONMENT VARIABLES π
recorder_dump_on_common_signals() also reads the following environment variables, iykyk:
RECORDER_TRACESβ a trace description, in the format expected byrecorder_trace_set(3). β¨RECORDER_TWEAKSβ likeRECORDER_TRACES, but normally used for tweaking configuration values as opposed to tracing. πRECORDER_DUMPβ activates a background thread to dump the given pattern at regular intervals. yes, a whole background thread doing it on a schedule, iconic π
π§ EXAMPLES π§
okay so this first program records its input arguments, and crashes if you pass crash as the first command-line argument. dramatic? yes. useful? also yes π
#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 occurs, previously recorded events are printed out on the console. so you get the receipts after the fall πβ¨
and now the second program, bestie β it's an instrumented version of the classical recursive Fibonacci computation. it uses several recorders corresponding to different types of events, and activates warnings and errors in a way that can be configured by setting an environment variable. obsessed π
#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
the first column in trace outputs is the number of events that were recorded. the second column is the time in seconds since the program started. π
the same program can also be run with additional tracing or warnings, for example:
% 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 π
okay so we gotta be honest here, bestie. the current signal handling mechanism does not yet use sigaltstack(2) and consequently is not robust to stack overflow. it is also known to fail for repeated signals. and SIGINFO (and the associated Control-T keyboard shortcut) do not exist on Linux, which is a pity. π
bugs should be reported using https://github.com/c3d/recorder/issues. pls do, they want to hear from you π«Ά
π SEE ALSO π
RECORDER_DEFINE(3), RECORDER_DECLARE(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 π
and that's the whole page, bestie! π¦ this was version 1.0, dated 2019-03-09, from recorder_dump(3) in the Recorder Library β thanks for reading, you ate that π
β¨
π¦ 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