You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用rollingfile_udata_set_logdir时log4c报segmentation fault

段错误根本原因

触发崩溃的核心原因是log4c调用顺序完全错误,在库未完成初始化时就操作内部结构体,具体细节:

  • log4c所有自定义类型(rollingfile appender、sizewin滚动策略等)的注册、内存分配逻辑、操作函数表绑定,都要在log4c_init()执行完成后才会生效。
  • 你的代码跳过了log4c_init()步骤,直接调用log4c_appender_get()拿appender、调用rollingfile_make_udata()创建用户数据,这两个接口在库未初始化时返回的都是无效指针(要么是空,要么是未完成内存映射的野指针)。
  • 后续调用rollingfile_udata_set_logdir()向无效指针指向的内存地址写入数据,直接触发段错误。
  • 额外存在逻辑冲突:你在代码中手动创建udata设置日志目录,和xml配置文件中rfileappender的logdir、rollingpolicy绑定逻辑完全脱节,就算不崩溃,配置的滚动规则、日志前缀等参数也不会生效。
修复方法

严格按照log4c的生命周期调整代码逻辑,禁止在库初始化前操作内部结构体:

  1. 程序启动后第一时间调用log4c_init(),完成库初始化、xml配置文件加载、所有appender/layout/rollingpolicy实例的初始化工作。
  2. 如果不需要动态修改配置,完全不需要手动调用rollingfile_make_udata()、rollingfile_udata_set_logdir()这类appender内部操作接口,xml里配置的/var/log/日志目录、1KB大小滚动、保留10个日志文件的规则会自动生效。
  3. 如果确实需要动态修改日志目录(比如运行用户没有/var/log/写入权限),要在log4c_init()执行完成后,从已经初始化好的appender实例中取出合法的udata指针,再修改参数,禁止手动创建udata。

修正后的参考代码

#include <log4c.h>
// 其他头文件省略

int main() {
    // 第一步:必须先初始化log4c
    if (log4c_init() != 0) {
        return -1;
    }

    const char *logdir = ".";
    // 初始化完成后再获取appender,此时拿到的是合法实例
    log4c_appender_t* app = log4c_appender_get("rfileappender");
    // 从已初始化的appender中取出自动分配的udata,不要自己手动make
    rollingfile_udata_t *rfup = (rollingfile_udata_t*)log4c_appender_get_udata(app);
    if (rfup != NULL) {
        // 此时rfup是合法指针,调用set方法不会触发段错误
        rollingfile_udata_set_logdir(rfup, logdir);
    }

    // 正常日志打印逻辑
    log4c_category_t *collector_cat = log4c_category_get("log4c.collector");
    log4c_category_debug(collector_cat, "log system init success");

    // 程序退出前执行资源清理
    log4c_fini();
    return 0;
}

补充说明:如果不需要动态覆盖配置,上述代码里手动取rfup改logdir的逻辑可以全部删掉,直接用xml里的配置即可,代码会更简洁。

内容的提问来源于stack exchange,提问作者Rony Tesler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 15:45:42