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

日志函数add_log存在哪些安全隐患?线程与高频调用问题分析

日志函数add_log的线程/高频场景不安全因素分析

朋友推荐了如下add_log函数代码,我已在多个版本中使用。起初仅用于调试特定函数,后作为常规内部日志记录方式,但发现在线程环境或高频调用场景下会出现问题。请问该函数的实现存在哪些不安全因素?

void add_log(const char* format, ...)
{
    HANDLE filehandle;
    DWORD dwReadBytes;
    char buffer[2048];
    char writebuffer[2048];
    va_list args;
    va_start(args, format);
    vsprintf_s(buffer, format, args);
    filehandle = CreateFile("C:\\Log.txt", GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0);
    SetFilePointer(filehandle, 0, 0, FILE_END);
    time_t ltime;
    ltime = time(NULL);
    //sprintf_s(writebuffer, 2048, "%s: %s\n", asctime(localtime(&ltime)), buffer);
    sprintf_s(writebuffer, 2048, "%s", buffer);
    WriteFile(filehandle, writebuffer, strlen(writebuffer), &dwReadBytes, 0);
    CloseHandle(filehandle);
}

核心不安全因素

  • 线程间无同步,日志会被覆盖或乱序
    多线程同时调用时,每个线程独立执行「打开文件→定位末尾→写入→关闭」流程,这些操作不是原子的。比如线程A刚定位到文件末尾,线程B就抢先写入了内容,线程A再写入就会直接覆盖B的日志;或者多个线程的写入操作交叉执行,导致日志内容拼接混乱、顺序完全错乱。

  • 文件共享模式错误,高频调用会触发打开失败
    CreateFile的第三个参数传了0,意味着独占打开文件,不允许任何其他线程/进程访问。如果多个线程同时调用该函数,后续线程的CreateFile会直接失败,连文件都打不开更别说写日志了。正常应该传FILE_SHARE_WRITE | FILE_SHARE_READ,允许其他线程同时读写该文件。

  • 定位+写入非原子,存在竞态条件
    就算改了共享模式,SetFilePointer和WriteFile是两个独立的系统调用,中间可能被其他线程打断,导致写入位置错误。比如线程A定位到末尾后,线程B写入了内容,线程A的写入位置就不再是最新的末尾,同样会覆盖日志。可以用带OVERLAPPED结构体的WriteFile直接指定写入到末尾,或者用原子化的写入方式避免这个问题。

  • 固定缓冲区存在溢出风险
    虽然用了sprintf_s这类安全函数,但buffer和writebuffer固定为2048字节。如果格式化后的日志内容超过这个长度,会触发sprintf_s的错误处理(默认会调用无效参数处理程序导致程序崩溃),高频调用下一旦出现超长日志,直接影响程序稳定性。

  • 未处理系统调用错误,故障无感知
    CreateFile、WriteFile这些系统调用都可能失败(比如磁盘满、权限不足),但函数里完全没做错误检查。就算文件打开失败,后续的写入操作照样执行,日志丢了程序也不会有任何提示,排查问题时根本不知道哪里出了错。

内容的提问来源于stack exchange,提问作者Minseok Kim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 01:46:31