feat(logger): 新增文件日志功能,帮助我很快排查到了segarray_free的bug

This commit is contained in:
建峰 2026-05-17 00:49:29 +08:00
parent 8a65218105
commit 15ab80cc4d
12 changed files with 206 additions and 56 deletions

View File

@ -41,26 +41,44 @@ typedef enum {
#define LOG_DEBUG_DETAIL LOG_DETAIL_DISABLE
#endif
#ifdef LOG_FILE_ENABLE
#ifndef LOG_FILE_NAME
#define LOG_FILE_NAME "unicstl.log"
#endif
#endif
// -------------------- log print --------------------
#if LOG_DEBUG_DETAIL == 1
#define LOG_HEADER_PRINT(level, fmt, ...) do {\
#define _LOG_STR(x) #x
#define _LOG_STR_IMPL(x) _LOG_STR(x)
#define _LOG_LEVEL_STR(level) (_LOG_STR_IMPL(level) + 4)
#define _LOG_LEVEL_PRINT(level) do{\
printf("[%5.*s] ", (int)strlen(_LOG_LEVEL_STR(level)),_LOG_LEVEL_STR(level)); \
}while(0)
#if LOG_DEBUG_DETAIL == LOG_DETAIL_ENABLE
#define _LOG_HEADER_PRINT(level, fmt, ...) do {\
if ((int)level >= (int)LOG_LEVEL) {\
printf("[%s] %s:%d %s()", #level, __FILE__, __LINE__, __func__); \
_LOG_LEVEL_PRINT(level);\
printf("%s:%d %s()\t", __FILE__, __LINE__, __func__); \
}\
} while (0)
#else
#define LOG_HEADER_PRINT(level, fmt, ...) do {} while (0)
#define _LOG_HEADER_PRINT(level, fmt, ...) do {
if ((int)level >= (int)LOG_LEVEL) {\
_LOG_LEVEL_PRINT(level);\
}\
} while (0)
#endif
#define LOG_PRINT(level, fmt, ...) do {\
#define _LOG_PRINT(level, fmt, ...) do {\
if (level >= (int)LOG_LEVEL) {\
LOG_HEADER_PRINT(level, fmt, ##__VA_ARGS__);\
_LOG_HEADER_PRINT(level, fmt, ##__VA_ARGS__);\
printf("@" fmt "\n", ##__VA_ARGS__);\
}\
} while (0)
#define LOG_HEX(level, data, len) do {\
#define _LOG_HEX(level, data, len) do {\
if (level >= LOG_LEVEL) {\
for(uint32_t i_temp = 0; i_temp < len; i_temp++) { \
if(i_temp != 0 && (i_temp % 4 == 0)){ printf(" ");}\
@ -73,15 +91,43 @@ typedef enum {
// -------------------- log api --------------------
#define log_debug(fmt, ...) LOG_PRINT(LOG_DEBUG, fmt, ##__VA_ARGS__)
#define log_info(fmt, ...) LOG_PRINT(LOG_INFO, fmt, ##__VA_ARGS__)
#define log_warn(fmt, ...) LOG_PRINT(LOG_WARN, fmt, ##__VA_ARGS__)
#define log_error(fmt, ...) LOG_PRINT(LOG_ERROR, fmt, ##__VA_ARGS__)
#ifndef LOG_FILE_ENABLE
#define log_init() do {} while (0)
#define log_deinit() do {} while (0)
#define log_debug(fmt, ...) _LOG_PRINT(LOG_DEBUG, fmt, ##__VA_ARGS__)
#define log_info(fmt, ...) _LOG_PRINT(LOG_INFO, fmt, ##__VA_ARGS__)
#define log_warn(fmt, ...) _LOG_PRINT(LOG_WARN, fmt, ##__VA_ARGS__)
#define log_error(fmt, ...) _LOG_PRINT(LOG_ERROR, fmt, ##__VA_ARGS__)
#define log_debug_hex(data, len) _LOG_HEX(LOG_DEBUG, data, len)
#define log_info_hex(data, len) _LOG_HEX(LOG_INFO, data, len)
#define log_warn_hex(data, len) _LOG_HEX(LOG_WARN, data, len)
#define log_error_hex(data, len) _LOG_HEX(LOG_ERROR, data, len)
#else
#define log_init() logger_init(LOG_FILE_NAME)
#define log_deinit() logger_deinit()
#define log_debug(fmt, ...) logger(LOG_DEBUG, __FILE__, __LINE__, __func__, fmt, ##__VA_ARGS__)
#define log_info(fmt, ...) logger(LOG_INFO, __FILE__, __LINE__, __func__,fmt, ##__VA_ARGS__)
#define log_warn(fmt, ...) logger(LOG_WARN, __FILE__, __LINE__, __func__,fmt, ##__VA_ARGS__)
#define log_error(fmt, ...) logger(LOG_ERROR, __FILE__, __LINE__, __func__,fmt, ##__VA_ARGS__)
#define log_debug_hex(data, len) logger_hex(LOG_DEBUG, data, len)
#define log_info_hex(data, len) logger_hex(LOG_INFO, data, len)
#define log_warn_hex(data, len) logger_hex(LOG_WARN, data, len)
#define log_error_hex(data, len) logger_hex(LOG_ERROR, data, len)
void logger_init(const char *file_name);
void logger_deinit(void);
void logger(loglevel_t level, const char *file_name, int line, const char *func_name, const char *format, ...);
void logger_hex(loglevel_t level, const void *data, size_t len);
#endif
#define log_debug_hex(data, len) LOG_HEX(LOG_DEBUG, data, len)
#define log_info_hex(data, len) LOG_HEX(LOG_INFO, data, len)
#define log_warn_hex(data, len) LOG_HEX(LOG_WARN, data, len)
#define log_error_hex(data, len) LOG_HEX(LOG_ERROR, data, len)
#else // no LOGGER_ENABLE

View File

@ -65,7 +65,7 @@
* LOG_ERROR
* LOG_NONE
*/
#define LOG_LEVEL LOG_WARN
#define LOG_LEVEL LOG_DEBUG
/**
* @brief
@ -74,7 +74,7 @@
*/
#define LOG_DEBUG_DETAIL LOG_DETAIL_ENABLE
#define LOG_FILE_ENABLE
// #define UNICSTL_DEBUG_STACK
// #define UNICSTL_DEBUG_QUEUE

View File

@ -278,11 +278,8 @@ static void linklist_print(struct _linklist* self)
static bool linklist_init(struct _linklist * self, size_t obj_size)
{
unicstl_assert(self != NULL);
if(self == NULL || obj_size == 0)
{
return false;
}
unicstl_assert(obj_size != 0);
// -------------------- private --------------------
self->_size = 0;
self->_obj_size = obj_size;

View File

@ -367,7 +367,8 @@ iterator_t list_iter(struct _list* self)
static bool list_init2(struct _list* self, size_t obj_size, size_t capacity)
{
unicstl_assert(self != NULL);
if (self == NULL || obj_size == 0 || capacity == 0)
unicstl_assert(obj_size != 0);
if (capacity == 0)
{
return false;
}

102
src/logger.c Normal file
View File

@ -0,0 +1,102 @@
/**
* @file logger.c
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2026-05-16
*
* @copyright Copyright (c) 2026
*
*/
#include "logger.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
struct log_string
{
loglevel_t level;
const char *str;
};
static FILE* log_file = NULL;
struct log_string log_str[] = {
LOG_DEBUG, "DEBUG",
LOG_INFO, " INFO",
LOG_WARN, " WARN",
LOG_ERROR, "ERROR",
LOG_NONE, NULL
};
void logger_init(const char *file_name)
{
log_file = fopen(file_name, "w");
if (log_file == NULL)
{
perror("Failed to open log file");
exit(-1);
}
fprintf(log_file, "\n\n ============================== log start ============================== \n\n");
fflush(log_file);
}
void logger_deinit()
{
if (log_file != NULL)
{
fprintf(log_file, "\n\n ============================== log end ============================== \n\n");
fflush(log_file);
fclose(log_file);
log_file = NULL;
}
}
// -------------------- logger function --------------------
void logger(loglevel_t level, const char *file_name, int line, const char *func_name, const char *format, ...)
{
if ((int)level >= (int)LOG_LEVEL) {
FILE *file = log_file;
if (file == NULL) {
file = stderr;
}
fprintf(file, "[%5s] ", log_str[level].str);
fprintf(file, "%s:%d %s()\t", file_name, line, func_name);
va_list args;
va_start(args, format);
vfprintf(file, format, args);
va_end(args);
fprintf(file, "\n");
fflush(file);
}
}
void logger_hex(loglevel_t level, const void *data, size_t size)
{
if ((int)level >= (int)LOG_LEVEL) {
FILE *file = log_file;
if (file == NULL) {
file = stderr;
}
const uint8_t *bytes = (const uint8_t *)data;
for (size_t i_temp = 0; i_temp < size; i_temp++) {
if (i_temp != 0 && (i_temp % 4 == 0)) {
fprintf(file, " ");
}
if (i_temp != 0 && (i_temp % 16 == 0)) {
fprintf(file, "\n");
}
fprintf(file, "%02x", bytes[i_temp]);
}
fprintf(file, "\n");
fflush(file);
}
}

View File

@ -64,10 +64,7 @@ bool rawbuf_init(struct _rawbuf *self, size_t obj_size, size_t capacity, void *m
{
unicstl_assert(self != NULL);
unicstl_assert(obj_size > 0);
if(capacity == 0)
{
return false;
}
unicstl_assert(capacity > 0);
// -------------------- private --------------------
self->_obj_size = obj_size;

View File

@ -12,14 +12,10 @@
static inline size_t clac_start_index(size_t capacity)
{
// return 0;
return capacity <= 2 ? 0 : (capacity - 1) / 2;
}
static inline size_t segarray_map_full(struct _segarray *self, size_t capacity)
{
return 0;
}
static bool segarray_push_back(struct _segarray *self, const void *obj)
{
unicstl_assert(self != NULL);
@ -66,7 +62,7 @@ static bool segarray_push_back(struct _segarray *self, const void *obj)
log_error("map->push_back failed!");
return false;
}
self->_seghead = 0;
self->_segtail = 0;
}
}
@ -77,6 +73,7 @@ static bool segarray_push_back(struct _segarray *self, const void *obj)
return false;
}
size_t index = self->_segtail;
log_debug("segtail=%zu", index);
if (!seg->set(seg, index, obj))
{
log_error("seg->set failed!");
@ -189,7 +186,12 @@ static bool segarray_pop_back(struct _segarray *self, void *obj)
{
self->_segtail = self->_segsize;
map->pop_back(map, &seg);
if(!map->pop_back(map, &seg))
{
log_error("mapfree->pop_back failed!");
return false;
}
if (!mapfree->push_back(mapfree, &seg))
{
log_error("mapfree->push_back failed!");
@ -239,7 +241,11 @@ static bool segarray_pop_front(struct _segarray *self, void *obj)
self->_seghead = 0;
rawbuf_t seg;
map->pop_front(map, &seg);
if(!map->pop_front(map, &seg))
{
log_error("mapfree->pop_back failed!");
return false;
}
if (!mapfree->push_back(mapfree, &seg))
{
@ -399,15 +405,7 @@ static bool segarray_empty(struct _segarray *self)
static bool segarray_full(struct _segarray *self)
{
unicstl_assert(self != NULL);
size_t map_size = self->_map->size(self->_map);
if(self->_map->full(self->_map))
{
if(self->_seghead == 0 || self->_segtail == self->_segsize - 1)
{
return true;
}
}
return false;
return self->size(self) == self->capacity(self);
}
static bool segarray_clear(struct _segarray *self)
@ -424,18 +422,23 @@ static void segarray_destory(struct _segarray *self)
{
unicstl_assert(self != NULL);
ringbuf_t map = self->_map;
if (self->_dynamic)
if (self->_dynamic && map != NULL)
{
rawbuf_t seg = NULL;
while(map->empty(map))
while(!map->empty(map))
{
if (map->pop_back(map, &seg))
{
if(seg == NULL)
{
log_error("seg is NULL");
}
rawbuf_free(&seg);
}
}
ringbuf_free(&map);
ringbuf_free(&self->_map);
}
log_info("segarray destoryed!");
}
static void segarray_print(struct _segarray *self)

View File

@ -75,9 +75,11 @@ void tearDown(void)
int main(int argc, char const *argv[])
{
log_init();
printf("----- Unicstl Unit Test -----\n");
UNITY_BEGIN();
TEST_ADD(test_unicstl);
TEST_ADD(test_darray);
@ -98,5 +100,6 @@ int main(int argc, char const *argv[])
TEST_ADD(test_rawbuf);
TEST_ADD(test_segarray);
log_deinit();
return UNITY_END();
}

View File

@ -12,13 +12,13 @@
static void test_linklist_new(void)
{
// TEST_ASSERT_NULL(linklist_new(0)); // nomeaning
linklist_t linklist = NULL;
linklist = linklist_new(sizeof(int));
TEST_ASSERT_NOT_NULL(linklist);
linklist_free(&linklist);
TEST_ASSERT_NULL(linklist_new(0));
// ------------------------------
TEST_ASSERT_NULL(linklist);
linklist_free(&linklist);

View File

@ -21,9 +21,8 @@ static void test_list_new(void)
list_free(&list); // list_free(NULL);
TEST_ASSERT_NULL(list);
//
TEST_ASSERT_NULL(list_new2(0, 1));
TEST_ASSERT_NULL(list_new2(sizeof(int), 0));
// TEST_ASSERT_NULL(list_new2(0, 1)); // nomeaing
// TEST_ASSERT_NULL(list_new2(sizeof(int), 0)); //
}
static void test_list_append(void)

View File

@ -22,8 +22,8 @@ static void test_rawbuf_new(void)
static void test_rawbuf_new_invalid(void)
{
rawbuf_t rawbuf = rawbuf_new(sizeof(int), 0);
TEST_ASSERT_NULL(rawbuf);
// rawbuf_t rawbuf = rawbuf_new(sizeof(int), 0);
// TEST_ASSERT_NULL(rawbuf);
}
#ifdef UNICSTL_STATIC_MEMORY

View File

@ -193,6 +193,7 @@ static void test_segarray_pop_back(void)
TEST_ASSERT_FALSE(segarray->pop_back(segarray, NULL));
segarray_free(&segarray);
log_info("test_segarray_pop_back pass");
}
static void test_segarray_pop_front(void)
@ -201,6 +202,7 @@ static void test_segarray_pop_front(void)
int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int temp = 0;
size_t len = sizeof(data) / sizeof(data[0]);
log_info("test_segarray_pop_front start");
segarray_t segarray = segarray_new(sizeof(int), len);
segarray->print_obj = print_num;
@ -691,7 +693,7 @@ static void test_segarray_status(void)
TEST_ASSERT_FALSE(segarray->full(segarray));
}
TEST_ASSERT_TRUE(segarray->push_back(segarray, &data[i]));
// TEST_ASSERT_TRUE(segarray->full(segarray));
TEST_ASSERT_TRUE(segarray->full(segarray));
TEST_ASSERT_TRUE(segarray->push_back(segarray, &data[i]));
TEST_ASSERT_TRUE(segarray->clear(segarray));