Commit 7528e41d authored by Lucas Russo's avatar Lucas Russo

src/libs/liberrhand: add new library for debug/error handling

This is a refactoring/modularization of hal/debug alongside with
hal/include/hal_assert.h and hal/include/hal_opts.h. Now, all of
these files live in a single library and is, for now, customizable
via Makefile variables.
parent 85013c4f
debug_DIR = $(SRC_DIR)/hal/debug
debug_OBJS = $(debug_DIR)/debug_print.o \
$(debug_DIR)/local_print.o \
$(debug_DIR)/debug_subsys.o
debug_INCLUDE_DIRS = $(debug_DIR)
/*
* Copyright (C) 2014 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
* Parts taken from lwIP debug system
*
* Released according to the GNU LGPL, version 3 or any later version.
*/
#ifndef _DEBUG_PRINT_H_
#define _DEBUG_PRINT_H_
#include <stdarg.h>
#include <stdio.h>
#include "debug_subsys.h" /* This must come before "hal_opts.h" */
#include "hal_opts.h"
struct _zmsg_t;
/************** Debug functions declarations **************/
void debug_print (const char *fmt, ...) __attribute__((format(printf,1,2)));
void debug_print_vec (const char *fmt, const char *data, int len);
void debug_log_print (int dbg_lvl, const char *fmt, ...) __attribute__((format(printf,2,3)));
/* Set the output logfile Defaults to STDOUT */
void debug_set_log_file (FILE *log_file);
int debug_set_log (const char *log_file_name, const char *mode);
void debug_log_print_zmq_msg (struct _zmsg_t *msg);
/********************** Debug macros **********************/
#if (DBG_SUBSYS_ON & DBG_MSG)
#define LOCAL_MSG_DBG
#endif
#ifdef DBE_DBG
#define dbg_print(fmt, ...) \
debug_print(fmt, ## __VA_ARGS__)
#define dbg_print_vec(fmt, data, len) \
debug_print_vec(fmt, data, len)
#define dbg_log_print(dbg_lvl, fmt, ...) \
debug_log_print(dbg_lvl, fmt, ## __VA_ARGS__)
#else
#define dbg_print(fmt, ...)
#define dbg_print_vec(fmt, data, len)
#define dbg_log_print(dbg_lvl, fmt, ...)
#endif /* DBE_DBG */
/* dbg has the following format:
* 31 - 4 3 - 1 0-0
* DBG_SUBSYS DBG_LVL DBG_HALT
*/
#ifdef DBE_DBG
#define DBE_DEBUG(dbg, fmt, ...) \
do { \
if (((dbg) & DBG_SUBSYS_ON) && \
(((dbg) & DBG_LVL_MASK) >= \
DBG_MIN_LEVEL)) { \
dbg_log_print((dbg) & DBG_LVL_MASK, \
fmt, ## __VA_ARGS__); \
\
if ((dbg) & DBG_LVL_HALT) { \
while(1); \
} \
} \
} while(0)
#define DBE_DEBUG_ARRAY(dbg, fmt, data, len) \
do { \
if (((dbg) & DBG_SUBSYS_ON) && \
(((dbg) & DBG_LVL_MASK) >= \
DBG_MIN_LEVEL)) { \
dbg_print_vec(fmt, data, len); \
\
if ((dbg) & DBG_LVL_HALT) \
while(1); \
} \
} while(0)
#define DBE_ERR(...) \
do { \
dbg_print(fmt, ##__VA_ARGS__); \
} while(0)
#else
#define DBE_DEBUG(dbg, fmt, ...)
#define DBE_DEBUG_ARRAY(dbg, fmt, data, len)
#define DBE_ERR(...)
#endif /* DBE_DBG */
#endif
/*
* Copyright (C) 2014 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU LGPL, version 3 or any later version.
*/
#ifndef _DEBUG_SUBSYS_H_
#define _DEBUG_SUBSYS_H_
/****************** Debug subsys macros ******************/
/*
* DBG_SUBSYS variable is one-hot encoded between
* the bits 31 and 4:
* bit 31 ... bit 4 bit 3 ... bit 0
* [1|0] [1|0] X X
*/
#define DBG_SUBSYS_SHIFT 4
/* Up to 28 debug subsystems (one-hot encoded) */
#define DBG_SUBSYS_MAX 28
#define DBG_SUBSYS_MASK_RAW ((1 << DBG_SUBSYS_MAX)-1)
#define DBG_SUBSYS_MASK (DBG_SUBSYS_MASK_RAW << DBG_SUBSYS_SHIFT)
#define DBG_SUBSYS_GEN(val) ((val & DBG_SUBSYS_MASK_RAW) << DBG_SUBSYS_SHIFT)
#define DBG_SUBSYS_DEGEN(val) ((val & DBG_SUBSYS_MASK) >> DBG_SUBSYS_SHIFT)
/* Debug subsys raw */
#define DBG_DEV_MNGR_RAW 0x1
#define DBG_DEV_IO_RAW 0x2
#define DBG_LL_IO_RAW 0x4
#define DBG_SM_IO_RAW 0x8
#define DBG_MSG_RAW 0x10
#define DBG_HAL_UTILS_RAW 0x20
#define DBG_LIB_CLIENT_RAW 0x40 /* The client library shares this macros */
#define DBG_SM_PR_RAW 0x80
#define DBG_SM_CH_RAW 0x100
#define DBG_DEV_MNGR DBG_SUBSYS_GEN(DBG_DEV_MNGR_RAW)
#define DBG_DEV_IO DBG_SUBSYS_GEN(DBG_DEV_IO_RAW)
#define DBG_LL_IO DBG_SUBSYS_GEN(DBG_LL_IO_RAW)
#define DBG_SM_IO DBG_SUBSYS_GEN(DBG_SM_IO_RAW)
#define DBG_MSG DBG_SUBSYS_GEN(DBG_MSG_RAW)
#define DBG_HAL_UTILS DBG_SUBSYS_GEN(DBG_HAL_UTILS_RAW)
/* The client library shares this macros */
#define DBG_LIB_CLIENT DBG_SUBSYS_GEN(DBG_LIB_CLIENT_RAW)
#define DBG_SM_PR DBG_SUBSYS_GEN(DBG_SM_PR_RAW)
#define DBG_SM_CH DBG_SUBSYS_GEN(DBG_SM_CH_RAW)
/****************** Debug levels macros ******************/
/*
* DBG_LVL variable is binary encoded between
* the bits 3 and 1:
* bit 31 ... bit 4 bit 3 ... bit 1 bit 0
* X X [1|0] [1|0] X
*/
#define DBG_LVL_SHIFT 1
#define DBG_LVL_MAX 3
#define DBG_LVL_MASK_RAW ((1 << DBG_LVL_MAX)-1)
#define DBG_LVL_MASK (DBG_LVL_MASK_RAW << DBG_LVL_SHIFT)
/* Up to 2^3 debug levels */
#define DBG_LVL_GEN(val) ((val & DBG_LVL_MASK_RAW) << DBG_LVL_SHIFT)
#define DBG_LVL_DEGEN(val) ((val & DBG_LVL_MASK) >> DBG_LVL_SHIFT)
#define DBG_LVL_NUM 5
/* Debug levels raw */
#define DBG_LVL_TRACE_RAW 0x1
#define DBG_LVL_INFO_RAW 0x2
#define DBG_LVL_WARN_RAW 0x3
#define DBG_LVL_ERR_RAW 0x4
#define DBG_LVL_FATAL_RAW 0x5
/* Debug levels mask'ed and shift'ed */
#define DBG_LVL_TRACE DBG_LVL_GEN(DBG_LVL_TRACE_RAW)
#define DBG_LVL_INFO DBG_LVL_GEN(DBG_LVL_INFO_RAW)
#define DBG_LVL_WARN DBG_LVL_GEN(DBG_LVL_WARN_RAW)
#define DBG_LVL_ERR DBG_LVL_GEN(DBG_LVL_ERR_RAW)
#define DBG_LVL_FATAL DBG_LVL_GEN(DBG_LVL_FATAL_RAW)
#define DBG_LVL_TRACE_STR "TRACE"
#define DBG_LVL_INFO_STR "INFO"
#define DBG_LVL_WARN_STR "WARN"
#define DBG_LVL_ERR_STR "ERR"
#define DBG_LVL_FATAL_STR "FATAL"
extern const char *dbg_lvl_str [DBG_LVL_NUM];
char *dbg_lvl_to_str (int dbg_lvl);
/****************** Debug halt macros ******************/
/*
* DBG_HALT variable is binary encoded in bit 0:
* bit 31 ... bit 4 bit 3 ... bit 1 bit 0
* X X X X [1|0]
*/
/* Debug halt */
#define DBG_HALT_SHIFT 0
#define DBG_HALT_MAX 1
#define DBG_HALT_MASK_RAW ((1 << DBG_HALT_SHIFT)-1)
#define DBG_HALT_MASK (DBG_HALT_MASK_RAW << DBG_HALT_SHIFT)
/* 1 halt signal */
#define DBG_HALT_GEN(val) ((val & DBG_HALT_MASK_RAW) << DBG_HALT_SHIFT)
#define DBG_HALT_DEGEN(val) ((val & DBG_HALT_MASK) >> DBG_HALT_SHIFT)
/* Debug halt raw */
#define DBG_LVL_HALT_RAW 0x1
/* Debug halt mask'ed and shift'ed */
#define DBG_LVL_HALT DBG_HALT_GEN(DBG_LVL_HALT_RAW)
#endif
/*
* Copyright (C) 2014 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU LGPL, version 3 or any later version.
*/
#ifndef _HAL_ASSERT_H_
#define _HAL_ASSERT_H_
#include "debug_print.h"
#include "varg_macros.h"
/* TODO: find a way avoid modifying the "global" err variable */
#define SET_ERR_VAR(err_code) WHENNOT(ISEMPTY(err_code))( \
err = err_code)
/* Generic macros for asserting in subsystems. The
* general use case for them is to wrapp these with
* meaningful strings for differentes subsystems */
#define ASSERT_HAL_TEST(test_boolean, debug_subsys, \
debug_name, err_str, err_goto_label, /* err_code*/ ...) \
do { \
if(!(test_boolean)) { \
DBE_DEBUG (DBG_ ##debug_subsys | DBG_LVL_FATAL, \
debug_name " %s\n", err_str); \
SET_ERR_VAR(/* err_code*/ __VA_ARGS__); \
goto err_goto_label; \
} \
} while(0)
#define ASSERT_HAL_ALLOC(ptr, debug_subsys, debug_name, \
err_str, err_goto_label, /* err_code*/ ...) \
ASSERT_HAL_TEST(ptr!=NULL, debug_subsys, debug_name, \
err_str, err_goto_label, /* err_code*/ __VA_ARGS__)
#define CHECK_HAL_ERR(err, debug_subsys, debug_name, \
err_str) \
do { \
if (err < 0) { \
DBE_DEBUG (DBG_ ##debug_subsys | DBG_LVL_ERR, \
debug_name " %s\n", err_str); \
return err; \
} \
} while (0)
#endif
# Set your cross compile prefix with CROSS_COMPILE variable
CROSS_COMPILE ?=
CMDSEP = ;
CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
LD = $(CROSS_COMPILE)ld
OBJDUMP = $(CROSS_COMPILE)objdump
OBJCOPY = $(CROSS_COMPILE)objcopy
SIZE = $(CROSS_COMPILE)size
MAKE = make
PWD = $(shell pwd)
LIBERRHAND = liberrhand
# General C flags
CFLAGS = -std=gnu99 -O2
# To enable this option, use: make ERRHAND_DBG=y
ifneq ($(ERRHAND_DBG),)
CFLAGS_DEBUG += -DERRHAND_DBG=$(ERRHAND_DBG)
endif
# To enable this option use: make ERRHAND_MIN_LEVEL=DBG_MIN_TRACE
ifneq ($(ERRHAND_MIN_LEVEL),)
CFLAGS_DEBUG += -DERRHAND_MIN_LEVEL=$(ERRHAND_MIN_LEVEL)
endif
# To enable this option use: make ERRHAND_SUBSYS_ON='"(DBG_DEV_MNGR | \
# DBG_DEV_IO | DBG_SM_IO | DBG_LIB_CLIENT | DBG_SM_PR | DBG_SM_CH | DBG_LL_IO | DBG_HAL_UTILS)"'
#
# You can also OR the available subsytems to enable debug messages in just the
# those subsytems. See file errhand_opts.h for more information
ifneq ($(ERRHAND_SUBSYS_ON),)
CFLAGS_DEBUG += -DERRHAND_SUBSYS_ON=$(ERRHAND_SUBSYS_ON)
endif
# The following options are just for compatibility. Prefer the above ones!
ifneq ($(DBE_DBG),)
CFLAGS_DEBUG += -DDBE_DBG=$(DBE_DBG)
endif
ifneq ($(DBG_MIN_LEVEL),)
CFLAGS_DEBUG += -DDBG_MIN_LEVEL=$(DBG_MIN_LEVEL)
endif
ifneq ($(DBG_SUBSYS_ON),)
CFLAGS_DEBUG += -DDBG_SUBSYS_ON=$(DBG_SUBSYS_ON)
endif
# Debug flags -D<flasg_name>=<value>
CFLAGS_DEBUG += -g
# Specific platform Flags
CFLAGS_PLATFORM = -Wall -Wextra -Werror
LDFLAGS_PLATFORM =
# Libraries
LIBS =
# General library flags -L<libdir>
LFLAGS =
# Include directories
INCLUDE_DIRS = -I.
# Merge all flags. Optimize for size (-Os)
CFLAGS += $(CFLAGS_PLATFORM) $(CFLAGS_DEBUG)
LDFLAGS = $(LDFLAGS_PLATFORM)
# Output library names
OUT = $(LIBERRHAND)
.SECONDEXPANSION:
# Library objects
$(LIBERRHAND)_OBJS_LIB = errhand_print.o errhand_subsys.o errhand_local_print.o
# Objects common for this library
common_OBJS =
# Objects for each version of library
$(LIBERRHAND)_OBJS = $(common_OBJS) $($(LIBERRHAND)_OBJS_LIB)
$(LIBERRHAND)_CODE_HEADERS = errhand_opts.h errhand.h
$(LIBERRHAND)_HEADERS = $($(LIBERRHAND)_OBJS_LIB:.o=.h) $($(LIBERRHAND)_CODE_HEADERS)
OBJS_all = $(common_OBJS) $($(LIBERRHAND)_OBJS)
# Libraries suffixes
LIB_STATIC_SUFFIX = .a
# Generate suitable names for static libraries
TARGET_STATIC = $(addsuffix $(LIB_STATIC_SUFFIX), $(OUT))
.PHONY: all clean mrproper install uninstall
# Avoid deletion of intermediate files, such as objects
.SECONDARY: $(OBJS_all)
# Makefile rules
all: $(TARGET_STATIC)
# Compile static library
%.a: $$($$*_OBJS)
$(AR) rcs $@ $^
# Pull in dependency info for *existing* .o files and don't complain if the
# corresponding .d file is not found
-include $(OBJS_all:.o=.d)
# Compile with position-independent objects.
# Autodependencies generatation by Scott McPeak, November 2001,
# from article "Autodependencies with GNU make"
%.o: %.c
$(CC) $(CFLAGS) $(INCLUDE_DIRS) -c $*.c -o $@
# create the dependency files "target: pre-requisites"
${CC} -MM $(CFLAGS) $(INCLUDE_DIRS) $*.c > $*.d
# Workaround to make objects in different folders have
# the correct target path. e.g., "dir/bar.o: dir/bar.c dir/foo.h"
# instead of "bar.o: dir/bar.c dir/foo.h"
@mv -f $*.d $*.d.tmp
@sed -e 's|.*:|$*.o:|' < $*.d.tmp > $*.d
# All prereqs listed will also become command-less,
# prereq-less targets. In this way, the prereq file will be
# treated as changed and the target will be rebuilt
# sed: strip the target (everything before colon)
# sed: remove any continuation backslashes
# fmt -1: list words one per line
# sed: strip leading spaces
# sed: add trailing colons
@sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | \
sed -e 's/^ *//' -e 's/$$/:/' >> $*.d
@rm -f $*.d.tmp
install:
uninstall:
clean:
rm -f $(OBJS_all) $(OBJS_all:.o=.d)
mrproper: clean
rm -f *.a
/*
* Copyright (C) 2015 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
* Parts taken from lwIP debug system
*
* Released according to the GNU LGPL, version 3 or any later version.
*/
#ifndef _ERRHAND_
#define _ERRHAND_
#include "errhand_assert.h"
#include "errhand_subsys.h"
#include "errhand_opts.h"
#include "errhand_print.h"
#endif
/*
* Copyright (C) 2014 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU LGPL, version 3 or any later version.
*/
#ifndef _ERRHAND_ASSERT_H_
#define _ERRHAND_ASSERT_H_
#include "errhand_print.h"
#include "varg_macros.h" /* Point the -I to somewhere visible */
/* TODO: find a way avoid modifying the "global" err variable */
#define SET_ERR_VAR(err_code) WHENNOT(ISEMPTY(err_code))( \
err = err_code)
/* Generic macros for asserting in subsystems. The
* general use case for them is to wrapp these with
* meaningful strings for differentes subsystems */
#define ERRHAND_TEST(test_boolean, debug_subsys, \
debug_name, err_str, err_goto_label, /* err_code*/ ...) \
do { \
if(!(test_boolean)) { \
ERRHAND_PRINT (DBG_ ##debug_subsys | DBG_LVL_FATAL, \
debug_name " %s\n", err_str); \
SET_ERR_VAR(/* err_code*/ __VA_ARGS__); \
goto err_goto_label; \
} \
} while(0)
#define ERRHAND_TEST_ALLOC(ptr, debug_subsys, debug_name, \
err_str, err_goto_label, /* err_code*/ ...) \
ERRHAND_TEST(ptr!=NULL, debug_subsys, debug_name, \
err_str, err_goto_label, /* err_code*/ __VA_ARGS__)
#define ERRHAND_CHECK_ERR(err, debug_subsys, debug_name, \
err_str) \
do { \
if (err < 0) { \
ERRHAND_PRINT (DBG_ ##debug_subsys | DBG_LVL_ERR, \
debug_name " %s\n", err_str); \
return err; \
} \
} while (0)
/* For compatibility */
#define ASSERT_HAL_TEST ERRHAND_TEST
#define ASSERT_HAL_ALLOC ERRHAND_TEST_ALLOC
#define CHECK_HAL_ERR ERRHAND_CHECK_ERR
#endif
......@@ -7,12 +7,12 @@
#include <czmq.h>
char *local_vprintf (const char *format, va_list argptr)
char *errhand_lprint_vprintf (const char *format, va_list argptr)
{
return zsys_vprintf (format, argptr);
}
void local_print_zmq_msg (zmsg_t *msg, FILE *file)
void errhand_lprint_zmq_msg (zmsg_t *msg, FILE *file)
{
zmsg_fprint (msg, file);
fprintf (file, "--------------------------------------\n");
......
......@@ -6,10 +6,10 @@
* Released according to the GNU LGPL, version 3 or any later version.
*/
#ifndef _LOCAL_PRINT_H_
#define _LOCAL_PRINT_H_
#ifndef _ERRHAND_LOCAL_PRINT_H_
#define _ERRHAND_LOCAL_PRINT_H_
char *local_vprintf (const char *format, va_list argptr);
void local_print_zmq_msg (zmsg_t *msg, FILE *file);
char *errhand_lprint_vprintf (const char *format, va_list argptr);
void errhand_lprint_zmq_msg (zmsg_t *msg, FILE *file);
#endif
......@@ -6,8 +6,11 @@
* Released according to the GNU LGPL, version 3 or any later version.
*/
#ifndef _HAL_OPTS_
#define _HAL_OPTS_
#ifndef _ERRHAND_OPTS_
#define _ERRHAND_OPTS_
/* Defaults to sensible values if DBG_MIN_LEVEL and DBG_SUBSYS_ON
* are not specified previously */
/*
* Define the debug level here.
......@@ -19,7 +22,17 @@
* DBG_LVL_FATAL = only the critical messages are shown
*/
#ifndef ERRHAND_MIN_LEVEL
/* For compatibility */
#ifndef DBG_MIN_LEVEL
#warning "liberrhand: undefined DBG_MIN_LEVEL. Using DBG_LVL_TRACE."
#define DBG_MIN_LEVEL DBG_LVL_TRACE
#endif /* DBG_MIN_LEVEL */
#define ERRHAND_MIN_LEVEL DBG_MIN_LEVEL
#endif /* ERRHAND_MIN_LEVEL */
/* Define which subsystem will be traced. The DBG_SUBSYS_ON
* macro must be OR'ed.
......@@ -34,6 +47,10 @@
* DBG_SM_CH
*/
#ifndef ERRHAND_SUBSYS_ON
#ifndef DBG_SUBSYS_ON
#warning "liberrhand: undefined DBG_SUBSYS_ON. Using library defaults."
#define DBG_SUBSYS_ON (\
DBG_DEV_MNGR | \
DBG_DEV_IO | \
......@@ -44,5 +61,10 @@
DBG_LL_IO | \
DBG_HAL_UTILS)
/* DBG_MSG | \ */
#endif /* DBG_SUBSYS_ON */
#define ERRHAND_SUBSYS_ON DBG_SUBSYS_ON
#endif /* ERRHAND_SUBSYS_ON */
#endif
......@@ -9,15 +9,17 @@
#include <stdlib.h>
#include <time.h>
#include <czmq.h>
#include "debug_print.h"
#include "local_print.h"
#define DBE_PRINT_PAD_FMT "-5"
#include "errhand_print.h"
#include "errhand_local_print.h"
#include "errhand_subsys.h"
#define ERRHAND_PRINT_PAD_FMT "-5"
/* Our logfile */
static FILE *_debug_logfile = NULL;
static FILE *_errhand_logfile = NULL;
void debug_print (const char *fmt, ...)
void errhand_print (const char *fmt, ...)
{
va_list args;
......@@ -28,11 +30,11 @@ void debug_print (const char *fmt, ...)
/* Based on CZMQ s_log () function. Available in
* https://github.com/zeromq/czmq/blob/master/src/zsys.c */
static void _debug_log_write (char *dbg_lvl_str, char *msg)
static void _errhand_log_write (char *errhand_lvl_str, char *msg)
{
/* Default to stdout */
if (!_debug_logfile) {
_debug_logfile = stdout;
if (!_errhand_logfile) {
_errhand_logfile = stdout;
}
time_t curtime = time (NULL);
......@@ -42,39 +44,39 @@ static void _debug_log_write (char *dbg_lvl_str, char *msg)
strftime (date, 20, "%y-%m-%d %H:%M:%S", loctime);
char log_text [1024];
snprintf (log_text, 1024, "%" DBE_PRINT_PAD_FMT "s: [%s] %s",
dbg_lvl_str, date, msg);
fprintf (_debug_logfile, "%s", log_text);
fflush (_debug_logfile);
snprintf (log_text, 1024, "%" ERRHAND_PRINT_PAD_FMT "s: [%s] %s",
errhand_lvl_str, date, msg);
fprintf (_errhand_logfile, "%s", log_text);
fflush (_errhand_logfile);
}
/* Based on CZMQ zsys_error () function. Available in
* https://github.com/zeromq/czmq/blob/master/src/zsys.c */
void debug_log_print (int dbg_lvl, const char *fmt, ...)
void errhand_log_print (int errhand_lvl, const char *fmt, ...)
{
va_list argptr;
va_start (argptr, fmt);
char *msg = local_vprintf (fmt, argptr);
char *msg = errhand_lprint_vprintf (fmt, argptr);
va_end (argptr);
/* Convert debug level code to string */
char *dbg_lvl_str = dbg_lvl_to_str (dbg_lvl);
_debug_log_write (dbg_lvl_str, msg);
/* Convert errhand level code to string */
char *errhand_lvl_str = errhand_lvl_to_str (errhand_lvl);
_errhand_log_write (errhand_lvl_str, msg);
free (msg);
free (dbg_lvl_str);
free (errhand_lvl_str);
}
void debug_log_print_zmq_msg (zmsg_t *msg)
void errhand_log_print_zmq_msg (zmsg_t *msg)
{
/* Default to stdout */
if (!_debug_logfile) {
_debug_logfile = stdout;
if (!_errhand_logfile) {
_errhand_logfile = stdout;
}
local_print_zmq_msg (msg, _debug_logfile);
errhand_lprint_zmq_msg (msg, _errhand_logfile);
}
void debug_print_vec (const char *fmt, const char *data, int len)
void errhand_print_vec (const char *fmt, const char *data, int len)
{
int i;
for (i = 0; i < len; ++i)
......@@ -83,17 +85,17 @@ void debug_print_vec (const char *fmt, const char *data, int len)
printf ("\n");
}
static void _debug_set_log_file (FILE *log_file)
static void _errhand_set_log_file (FILE *log_file)
{
_debug_logfile = log_file;
_errhand_logfile = log_file;
}
void debug_set_log_file (FILE *log_file)
void errhand_set_log_file (FILE *log_file)
{
_debug_set_log_file (log_file);
_errhand_set_log_file (log_file);
}
int debug_set_log (const char *log_file_name, const char *mode)
int errhand_set_log (const char *log_file_name, const char *mode)
{
int err = -1; /* Error */
FILE *log_file = NULL;
......@@ -129,7 +131,7 @@ int debug_set_log (const char *log_file_name, const char *mode)
log_file = stdout;
}
_debug_set_log_file (log_file);
_errhand_set_log_file (log_file);
return err;
}
/*
* Copyright (C) 2014 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
* Parts taken from lwIP debug system
*
* Released according to the GNU LGPL, version 3 or any later version.
*/
#ifndef _ERRHAND_PRINT_H_
#define _ERRHAND_PRINT_H_
#include <stdarg.h>
#include <stdio.h>
#include "errhand_subsys.h" /* This must come before "errhand_opts.h" */
#include "errhand_opts.h"
struct _zmsg_t;
/************** Error handling functions declarations **************/
void errhand_print (const char *fmt, ...) __attribute__((format(printf,1,2)));
void errhand_print_vec (const char *fmt, const char *data, int len);
void errhand_log_print (int dbg_lvl, const char *fmt, ...) __attribute__((format(printf,2,3)));
/* Set the output logfile Defaults to STDOUT */
void errhand_set_log_file (FILE *log_file);
int errhand_set_log (const char *log_file_name, const char *mode);
void errhand_log_print_zmq_msg (struct _zmsg_t *msg);
/********************** Error handling macros **********************/
/* For compatibility */
#ifndef ERRHAND_DBG
#define ERRHAND_DBG DBE_DBG
#endif
#ifndef ERRHAND_SUBSYS_ON
#define ERRHAND_SUBSYS_ON DBG_SUBSYS_ON
#endif
#ifndef ERRHAND_DBG_MSG
#define ERRHAND_DBG_MSG DBG_MSG
#endif
#if (ERRHAND_SUBSYS_ON & ERRHAND_DBG_MSG)
#define LOCAL_MSG_DBG
/* For compatibility */
#define ERRHAND_LOCAL_MSG_DBG
#endif
/* dbg has the following format:
* 31 - 4 3 - 1 0-0
* ERRHAND_SUBSYS ERRHAND_LVL ERRHAND_HALT
*/
#ifdef ERRHAND_DBG
#define ERRHAND_DEBUG(dbg, fmt, ...) \
do { \
if (((dbg) & ERRHAND_SUBSYS_ON) && \
(((dbg) & ERRHAND_LVL_MASK) >= \
ERRHAND_MIN_LEVEL)) { \
errhand_log_print((dbg) & ERRHAND_LVL_MASK, \
fmt, ## __VA_ARGS__); \
\
if ((dbg) & ERRHAND_LVL_HALT) { \
while(1); \
} \
} \
} while(0)
#define ERRHAND_DEBUG_ARRAY(dbg, fmt, data, len) \
do { \
if (((dbg) & ERRHAND_SUBSYS_ON) && \
(((dbg) & ERRHAND_LVL_MASK) >= \
ERRHAND_MIN_LEVEL)) { \
errhand_print_vec(fmt, data, len); \
\
if ((dbg) & ERRHAND_LVL_HALT) \
while(1); \
} \
} while(0)
#define ERRHAND_ERR(...) \
do { \
errhand_print(fmt, ##__VA_ARGS__); \
} while(0)
#else
#define ERRHAND_DEBUG(dbg, fmt, ...)
#define ERRHAND_DEBUG_ARRAY(dbg, fmt, data, len)
#define ERRHAND_ERR(...)
#endif /* ERRHAND_DBG */
/* Convenient name */
#define ERRHAND_PRINT ERRHAND_DEBUG
/* For compatibility */
#define DBE_DEBUG ERRHAND_DEBUG
#define DBE_DEBUG_ARRAY ERRHAND_DEBUG_ARRAY
#define DBE_ERR ERRHAND_ERR
#endif
......@@ -6,23 +6,24 @@
*/
#include <czmq.h>
#include "debug_subsys.h"
#include "errhand_subsys.h"
const char *dbg_lvl_str [DBG_LVL_NUM] = {
[0] = DBG_LVL_TRACE_STR,
[1] = DBG_LVL_INFO_STR,
[2] = DBG_LVL_WARN_STR,
[3] = DBG_LVL_ERR_STR,
[4] = DBG_LVL_FATAL_STR
const char *errhand_lvl_str [ERRHAND_LVL_NUM] = {
[0] = ERRHAND_LVL_TRACE_STR,
[1] = ERRHAND_LVL_INFO_STR,
[2] = ERRHAND_LVL_WARN_STR,
[3] = ERRHAND_LVL_ERR_STR,
[4] = ERRHAND_LVL_FATAL_STR
};
char *dbg_lvl_to_str (int dbg_lvl)
char *errhand_lvl_to_str (int errhand_lvl)
{
/* Should be large enough for all possible debug levels */
int size = 16;
char *str = zmalloc (size);
const char *dbg_str = dbg_lvl_str [DBG_LVL_DEGEN(dbg_lvl)-1];
const char *errhand_str = errhand_lvl_str [ERRHAND_LVL_DEGEN(errhand_lvl)-1];
memcpy (str, dbg_str, strlen (dbg_str)+1);
memcpy (str, errhand_str, strlen (errhand_str)+1);
return str;
}
/*
* Copyright (C) 2014 LNLS (www.lnls.br)
* Author: Lucas Russo <lucas.russo@lnls.br>
*
* Released according to the GNU LGPL, version 3 or any later version.
*/
#ifndef _ERRHAND_SUBSYS_H_
#define _ERRHAND_SUBSYS_H_
/****************** Debug subsys macros ******************/
/*
* ERRHAND_SUBSYS variable is one-hot encoded between
* the bits 31 and 4:
* bit 31 ... bit 4 bit 3 ... bit 0
* [1|0] [1|0] X X
*/
#define ERRHAND_SUBSYS_SHIFT 4
/* Up to 28 debug subsystems (one-hot encoded) */
#define ERRHAND_SUBSYS_MAX 28
#define ERRHAND_SUBSYS_MASK_RAW ((1 << ERRHAND_SUBSYS_MAX)-1)
#define ERRHAND_SUBSYS_MASK (ERRHAND_SUBSYS_MASK_RAW << ERRHAND_SUBSYS_SHIFT)
#define ERRHAND_SUBSYS_GEN(val) ((val & ERRHAND_SUBSYS_MASK_RAW) << ERRHAND_SUBSYS_SHIFT)
#define ERRHAND_SUBSYS_DEGEN(val) ((val & ERRHAND_SUBSYS_MASK) >> ERRHAND_SUBSYS_SHIFT)
/* Debug subsys raw */
#define ERRHAND_DEV_MNGR_RAW 0x1
#define ERRHAND_DEV_IO_RAW 0x2
#define ERRHAND_LL_IO_RAW 0x4
#define ERRHAND_SM_IO_RAW 0x8
#define ERRHAND_MSG_RAW 0x10
#define ERRHAND_HAL_UTILS_RAW 0x20
#define ERRHAND_LIB_CLIENT_RAW 0x40 /* The client library shares this macros */
#define ERRHAND_SM_PR_RAW 0x80
#define ERRHAND_SM_CH_RAW 0x100
#define ERRHAND_DEV_MNGR ERRHAND_SUBSYS_GEN(ERRHAND_DEV_MNGR_RAW)
#define ERRHAND_DEV_IO ERRHAND_SUBSYS_GEN(ERRHAND_DEV_IO_RAW)
#define ERRHAND_LL_IO ERRHAND_SUBSYS_GEN(ERRHAND_LL_IO_RAW)
#define ERRHAND_SM_IO ERRHAND_SUBSYS_GEN(ERRHAND_SM_IO_RAW)
#define ERRHAND_MSG ERRHAND_SUBSYS_GEN(ERRHAND_MSG_RAW)
#define ERRHAND_HAL_UTILS ERRHAND_SUBSYS_GEN(ERRHAND_HAL_UTILS_RAW)
/* The client library shares this macros */
#define ERRHAND_LIB_CLIENT ERRHAND_SUBSYS_GEN(ERRHAND_LIB_CLIENT_RAW)
#define ERRHAND_SM_PR ERRHAND_SUBSYS_GEN(ERRHAND_SM_PR_RAW)
#define ERRHAND_SM_CH ERRHAND_SUBSYS_GEN(ERRHAND_SM_CH_RAW)
/* For compatibility */
#define DBG_DEV_MNGR ERRHAND_DEV_MNGR
#define DBG_DEV_IO ERRHAND_DEV_IO
#define DBG_LL_IO ERRHAND_LL_IO
#define DBG_SM_IO ERRHAND_SM_IO
#define DBG_MSG ERRHAND_MSG
#define DBG_HAL_UTILS ERRHAND_HAL_UTILS
#define DBG_LIB_CLIENT ERRHAND_LIB_CLIENT
#define DBG_SM_PR ERRHAND_SM_PR
#define DBG_SM_CH ERRHAND_SM_CH
/****************** Debug levels macros ******************/
/*
* ERRHAND_LVL variable is binary encoded between
* the bits 3 and 1:
* bit 31 ... bit 4 bit 3 ... bit 1 bit 0
* X X [1|0] [1|0] X
*/
#define ERRHAND_LVL_SHIFT 1
#define ERRHAND_LVL_MAX 3
#define ERRHAND_LVL_MASK_RAW ((1 << ERRHAND_LVL_MAX)-1)
#define ERRHAND_LVL_MASK (ERRHAND_LVL_MASK_RAW << ERRHAND_LVL_SHIFT)
/* Up to 2^3 debug levels */
#define ERRHAND_LVL_GEN(val) ((val & ERRHAND_LVL_MASK_RAW) << ERRHAND_LVL_SHIFT)
#define ERRHAND_LVL_DEGEN(val) ((val & ERRHAND_LVL_MASK) >> ERRHAND_LVL_SHIFT)
#define ERRHAND_LVL_NUM 5
/* Debug levels raw */
#define ERRHAND_LVL_TRACE_RAW 0x1
#define ERRHAND_LVL_INFO_RAW 0x2
#define ERRHAND_LVL_WARN_RAW 0x3
#define ERRHAND_LVL_ERR_RAW 0x4
#define ERRHAND_LVL_FATAL_RAW 0x5
/* Debug levels mask'ed and shift'ed */
#define ERRHAND_LVL_TRACE ERRHAND_LVL_GEN(ERRHAND_LVL_TRACE_RAW)
#define ERRHAND_LVL_INFO ERRHAND_LVL_GEN(ERRHAND_LVL_INFO_RAW)
#define ERRHAND_LVL_WARN ERRHAND_LVL_GEN(ERRHAND_LVL_WARN_RAW)
#define ERRHAND_LVL_ERR ERRHAND_LVL_GEN(ERRHAND_LVL_ERR_RAW)
#define ERRHAND_LVL_FATAL ERRHAND_LVL_GEN(ERRHAND_LVL_FATAL_RAW)
/* For compatibility */
#define DBG_LVL_TRACE ERRHAND_LVL_TRACE
#define DBG_LVL_INFO ERRHAND_LVL_INFO
#define DBG_LVL_WARN ERRHAND_LVL_WARN
#define DBG_LVL_ERR ERRHAND_LVL_ERR
#define DBG_LVL_FATAL ERRHAND_LVL_FATAL
#define ERRHAND_LVL_TRACE_STR "TRACE"
#define ERRHAND_LVL_INFO_STR "INFO"
#define ERRHAND_LVL_WARN_STR "WARN"
#define ERRHAND_LVL_ERR_STR "ERR"
#define ERRHAND_LVL_FATAL_STR "FATAL"
extern const char *errhand_lvl_str [ERRHAND_LVL_NUM];
char *errhand_lvl_to_str (int errhand_lvl);
/****************** Debug halt macros ******************/
/*
* ERRHAND_HALT variable is binary encoded in bit 0:
* bit 31 ... bit 4 bit 3 ... bit 1 bit 0
* X X X X [1|0]
*/
/* Debug halt */
#define ERRHAND_HALT_SHIFT 0
#define ERRHAND_HALT_MAX 1
#define ERRHAND_HALT_MASK_RAW ((1 << ERRHAND_HALT_SHIFT)-1)
#define ERRHAND_HALT_MASK (ERRHAND_HALT_MASK_RAW << ERRHAND_HALT_SHIFT)
/* 1 halt signal */
#define ERRHAND_HALT_GEN(val) ((val & ERRHAND_HALT_MASK_RAW) << ERRHAND_HALT_SHIFT)
#define ERRHAND_HALT_DEGEN(val) ((val & ERRHAND_HALT_MASK) >> ERRHAND_HALT_SHIFT)
/* Debug halt raw */
#define ERRHAND_LVL_HALT_RAW 0x1
/* Debug halt mask'ed and shift'ed */
#define ERRHAND_LVL_HALT ERRHAND_HALT_GEN(ERRHAND_LVL_HALT_RAW)
/* For compatibility */
#define DBG_LVL_HALT ERRHAND_LVL_HALT
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment