ELinks 0.18.0
error.h File Reference

Error handling and debugging stuff. More...

Macros

#define DBG   errfile = __FILE__, errline = __LINE__, elinks_debug
 DBG(format_string) is used for printing of debugging information.
#define WDBG   errfile = __FILE__, errline = __LINE__, elinks_wdebug
 WDBG(format_string) is used for printing of debugging information, akin to DBG().
#define ERROR   errfile = __FILE__, errline = __LINE__, elinks_error
 ERROR(format_string) is used to report non-fatal unexpected errors during the ELinks run.
#define INTERNAL   errfile = __FILE__, errline = __LINE__, elinks_internal
 INTERNAL(format_string) is used to report fatal errors during the ELinks run.
#define LOG_ERR(args...)
#define LOG_WARN(args...)
#define LOG_INFO(args...)
#define LOG_DBG(args...)
#define assert(x)
 This is our smart assert().
#define assertm(x, m...)
 This is extended assert() version, it can print additional user-specified message.
#define if_assert_failed   if (assert_failed && !(assert_failed = 0))
#define do_not_optimize_here_gcc_2_7(x)
#define do_not_optimize_here_gcc_3_x(x)
#define do_not_optimize_here_gcc_3_3(x)

Functions

void elinks_debug (const char *fmt,...)
void elinks_wdebug (const char *fmt,...)
void elinks_error (const char *fmt,...)
void elinks_internal (const char *fmt,...)
void usrerror (const char *fmt,...)
 usrerror(format_string) is used to report user errors during a peaceful ELinks run.
void elinks_log (char *msg, char *file, int line, const char *fmt,...)
 The LOG_*() macros can be used to log to a file, however, by default log messages are written to stderr.
void force_dump (void)
 This will print some fancy message, version string and possibly do something else useful.
void do_not_optimize_here (void *x)
 This function does nothing, except making compiler not to optimize certains spots of code — this is useful when that particular optimization is buggy.

Variables

int errline
const char * errfile
int assert_failed
 Whether an assertion has failed and the failure has not yet been handled.
char full_static_version [1024]
 This function dumps backtrace (or whatever similar it founds on the stack) nicely formatted and with symbols resolved to f.

Detailed Description

Error handling and debugging stuff.

Here you will found a chunk of functions useful for error states — from reporting of various problems to generic error tests/workarounds to some tools to be used when you got into an error state already. Some of the functions are also useful for debugging.

Macro Definition Documentation

◆ assert

#define assert ( x)
Value:
do { if (!assert_failed && (assert_failed = !(x))) { \
INTERNAL("assertion " #x " failed!"); \
} } while (0)
int assert_failed
Whether an assertion has failed and the failure has not yet been handled.
Definition error.c:141

This is our smart assert().

It is basically equivalent to if (x) INTERNAL(), but it generates a uniform message and mainly does not do the test if we are supposed to be lightning fast. Use it, use it a lot! And never forget the recovery path, see below if_assert_failed.

◆ assertm

#define assertm ( x,
m... )
Value:
do { if (!assert_failed && (assert_failed = !(x))) { \
INTERNAL("assertion " #x " failed: " m); \
} } while (0)

This is extended assert() version, it can print additional user-specified message.

Quite useful not only to detect that something is wrong, but also how wrong is it ;-). Note that the format string must always be a regular string, not a variable reference. Also, be careful what will you attempt to print, or you could easily get just a SIGSEGV instead of the assertion failed message.

◆ DBG

#define DBG   errfile = __FILE__, errline = __LINE__, elinks_debug

DBG(format_string) is used for printing of debugging information.

It should not be used anywhere in the official codebase (although it is often lying there commented out, as it may get handy).

◆ do_not_optimize_here_gcc_2_7

#define do_not_optimize_here_gcc_2_7 ( x)

◆ do_not_optimize_here_gcc_3_3

#define do_not_optimize_here_gcc_3_3 ( x)

◆ do_not_optimize_here_gcc_3_x

#define do_not_optimize_here_gcc_3_x ( x)

◆ ERROR

#define ERROR   errfile = __FILE__, errline = __LINE__, elinks_error

ERROR(format_string) is used to report non-fatal unexpected errors during the ELinks run.

It tries to (not that agressively) draw user's attention to the error, but never dumps core or so. Note that this should be used only in cases of non-severe internal inconsistences etc, never as an indication of user error (bad parameter, config file error etc.). We have usrerror() for this kind of stuff, and there's nothing naughty about using that.

◆ if_assert_failed

#define if_assert_failed   if (assert_failed && !(assert_failed = 0))

◆ INTERNAL

#define INTERNAL   errfile = __FILE__, errline = __LINE__, elinks_internal

INTERNAL(format_string) is used to report fatal errors during the ELinks run.

It tries to draw user's attention to the error and dumps core if ELinks is running in the CONFIG_DEBUG mode.

◆ LOG_DBG

#define LOG_DBG ( args...)
Value:
elinks_log("debug", __FILE__, __LINE__, args)
void elinks_log(char *msg, char *file, int line, const char *fmt,...)
The LOG_*() macros can be used to log to a file, however, by default log messages are written to stde...
Definition error.c:201

◆ LOG_ERR

#define LOG_ERR ( args...)
Value:
elinks_log("error", __FILE__, __LINE__, args)

◆ LOG_INFO

#define LOG_INFO ( args...)
Value:
elinks_log("info", __FILE__, __LINE__, args)

◆ LOG_WARN

#define LOG_WARN ( args...)
Value:
elinks_log("warn", __FILE__, __LINE__, args)

◆ WDBG

#define WDBG   errfile = __FILE__, errline = __LINE__, elinks_wdebug

WDBG(format_string) is used for printing of debugging information, akin to DBG().

However, it sleep(1)s, therefore being useful when it is going to be overdrawn or so. It should not be used anywhere in the official codebase (although it is often lying there commented out, as it may get handy).

Function Documentation

◆ do_not_optimize_here()

void do_not_optimize_here ( void * x)

This function does nothing, except making compiler not to optimize certains spots of code — this is useful when that particular optimization is buggy.

So we are just workarounding buggy compilers.

This function should be always used only in context of compiler version specific macros.

◆ elinks_debug()

void elinks_debug ( const char * fmt,
... )

◆ elinks_error()

void elinks_error ( const char * fmt,
... )

◆ elinks_internal()

void elinks_internal ( const char * fmt,
... )

◆ elinks_log()

void elinks_log ( char * msg,
char * file,
int line,
const char * fmt,
... )

The LOG_*() macros can be used to log to a file, however, by default log messages are written to stderr.

Set the following environment variables to configure the log behavior:

ELINKS_LOG
The path to the log file, it is opened for appending
ELINKS_MSG
A comma separated list containing "error", "warn", "info" and/or "debug" which can be used to limit what messages to emit to the log.
ELINKS_FILES
A comma separated list of which files names to emit log messages from.

◆ elinks_wdebug()

void elinks_wdebug ( const char * fmt,
... )

◆ force_dump()

void force_dump ( void )

This will print some fancy message, version string and possibly do something else useful.

Then, it will dump core.

◆ usrerror()

void usrerror ( const char * fmt,
... )

usrerror(format_string) is used to report user errors during a peaceful ELinks run.

It does not belong to the family above - it doesn't print code location, beep nor sleep, it just wraps around fprintf(stderr, "...\n");.

Variable Documentation

◆ assert_failed

int assert_failed
extern

Whether an assertion has failed and the failure has not yet been handled.

To make recovery path possible (assertion failed may not mean end of the world, the execution goes on if we're outside of CONFIG_DEBUG and CONFIG_FASTMEM), assert_failed is set to true if the last assert() failed, otherwise it's zero. Note that you must never change assert_failed value, sorry guys.

You should never test assert_failed directly anyway. Use if_assert_failed instead, it will attempt to hint compiler to optimize out the recovery path if we're CONFIG_FASTMEM. So it should go like:

assertm(1 == 1, "The world's gonna blow up!");
if_assert_failed { schedule_time_machine(); return; }
#define if_assert_failed
Definition error.h:193
#define assertm(x, m...)
This is extended assert() version, it can print additional user-specified message.
Definition error.h:129

In-depth explanation: this restriction is here because in the CONFIG_FASTMEM mode, assert_failed is initially initialized to zero and then not ever touched anymore. So if you change it to non-zero failure, your all further recovery paths will get hit (and since developers usually don't test CONFIG_FASTMEM mode extensively...). So better don't mess with it, even if you would do that with awareness of this fact. We don't want to iterate over tens of spots all over the code when we change one detail regarding CONFIG_FASTMEM operation.

This is not that actual after introduction of if_assert_failed, but it's a safe recommendation anyway, so... ;-)

◆ errfile

const char* errfile
extern

◆ errline

int errline
extern

◆ full_static_version

char full_static_version[1024]
extern

This function dumps backtrace (or whatever similar it founds on the stack) nicely formatted and with symbols resolved to f.

When trouble is set, it tells it to be extremely careful and not use dynamic memory allocation functions etc (useful in SIGSEGV handler etc).

Note that this function just calls system-specific backend provided by the libc, so it is available only on some systems. CONFIG_BACKTRACE is defined if it is available on yours. This is needed for providing info about features when dumping core