使用C中的宏对vsprintf进行分段错误

我在C.中创建了一个简单的记录器库.我有三个文件

我的示例文件:

> example.c

库文件:

> loglib.h
> loglib.c

我的主记录器功能称为logme.我将不同的宏定义为包装器以指示不同的日志级别:

例如

>警告
>错误
>等..

在example.c中我调用宏:

int int_arg = 55;
WARN(1, "Warn message with level 1");
WARN(1, "Warn message with level %d", int_arg);

WARN宏在loglib.h中定义:

#define WARN(LEVEL, ...) \
    logme(LEVEL, 8, " <%s:%d> inside %s() -- "__VA_ARGS__, __FILE__, __LINE__, __func__);

最后这里是logme函数:

void slog(int level, int flag, const char *msg, ...)
{
    char string[10000];
    bzero(string, sizeof(string));
    va_list args;
    va_start(args, msg);
    vsprintf(string, msg, args);
    va_end(args);

    // .. do other things
}

当我运行示例文件时,这就是我得到的:

inside main() — Warn message with level 1

Segmentation fault (core dumped)

当我使用格式化字符串调用WARN时,我会出现分段错误.

分段错误出现在vsprintf(string,msg,args);

我的宏有问题吗?

这是我的lib的make文件:

CFLAGS = -g -O2 -Wall -lpthread
LIB = -lrt
OBJS = loglib.o

LIBINSTALL = /usr/local/lib
HEADINSTALL = /usr/local/include

.c.o:
    $(CC) $(CFLAGS) -c $< $(LIB)

libslog.a: $(OBJS)
    $(AR) rcs liblog.a $(OBJS)
    @echo [-] Syncing static library
    sync

install:
    @test -d $(LIBINSTALL) || mkdir $(LIBINSTALL)
    @test -d $(HEADINSTALL) || mkdir $(HEADINSTALL)
    @install -m 0664 liblog.a $(LIBINSTALL)/
    @install -m 0664 loglib.h $(HEADINSTALL)/
    @echo [-] Done

loglib.o: loglib.h

.PHONY: clean
clean:
    $(RM) liblog.a $(OBJS)

最佳答案 这不起作用,因为您在此处尝试字符串连接__VA_ARGS__:

#define WARN(LEVEL, ...) \
logme(LEVEL, 8, " <%s:%d> inside %s() -- "__VA_ARGS__, __FILE__, __LINE__, __func__);

这会弄乱你的参数序列:__ FILE__不会与<%s等一起使用.你必须重新定义你的WARN()宏,以便__VA_ARGS__是最后一个.如果要预先添加所有信息,则必须编写适当的可变参数函数.请注意,__ func__不是字符串文字,它引用相应的字符串.

点赞