使用 g_log_structured 的内存泄漏

memory leak by using g_log_structured

提问人:Holger 提问时间:10/19/2023 最后编辑:Sam MasonHolger 更新时间:10/23/2023 访问量:59

问:

我想使用 Glib 实现结构化日志记录到 Linux (Ubuntu) 的系统日志中。 在三种可能性中,有一种经常导致内存访问错误。

不幸的是,我发现经常使用g_log_structured(..)会导致内存泄漏。 代码如下:

#define G_LOG_USE_STRUCTURED
#define G_LOG_DOMAIN "MyDomain"

#include <glib.h>
#include <stdio.h>

int main(int argc, char *argv[]) 
{
   g_log_set_writer_func (g_log_writer_journald, NULL, NULL);

/*  regularly leads to a memory leak.
    g_log_structured (G_LOG_DOMAIN,
                   G_LOG_LEVEL_DEBUG,
                   "CODE_FILE", "mysource.c",
                   "CODE_LINE", 312,
                   "MESSSAGE_ID", "06d4df59e6c24647bfe69d2c27ef0b4e",
                   "MESSAGE", "You have %d eggs", 12 + 2);
*/

/* The following log message will go to journald */
        const GLogField fields[] = {
               {"MESSAGE", "This is the message", -1},
               {"EIGENES_FELD", "mysource.c", -1},
               {"STATUS", "3",-1},
        };

        // works        
        g_log_structured_array (G_LOG_LEVEL_DEBUG, fields,G_N_ELEMENTS (fields));
        
        // works
        GLogWriterOutput result = g_log_writer_journald (
                                 G_LOG_LEVEL_INFO,
                                 fields,
                                 G_N_ELEMENTS(fields),
                                 NULL); 
    return 0;
}

不幸的是,我发现经常使用会导致内存泄漏。g_log_structured(..)

Okt 19 14:44:05 holger kernel: a.out[12281]: segfault at 138 ip 00007fe6b6b7401d sp 00007ffe746157e8 error 4 in libc.so.6[7fe6b6a22000+178000] likely on CPU 1 (core 1, socket 0)
Okt 19 14:44:05 holger kernel: Code: 00 00 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 89 f8 48 89 fa c5 f9 ef c0 25 ff 0f 00 00 3d e0 0f 00 00 0f 87 33 01 00 00 <c5> fd 74 0f c5 fd d7 c1 85 c0 74 57 f3 0f bc c0 c5 f8 77 c3 66 66

同时,我相信这是 Glib 库中的一个错误。 我使用的是 Ubuntu 操作系统和 Glib 2.76.1。 有没有人有这方面的经验?

c 滑行

评论

0赞 Sam Mason 10/22/2023
如果您只想在系统日志中轻松显示条目,那么为什么不直接打印到 stdout 并在 systemd 服务下运行程序呢?这样一来,调试就很容易了(stdout 可以随心所欲地进行),管理员可以通过配置来控制他们希望生产条目的位置journald
2赞 Philip Withnall 10/23/2023
您的意思是“内存泄漏”还是“内存访问错误”?你似乎可以互换使用这些术语,但它们的意思却截然不同。您是否在以下位置运行代码或尝试找出问题所在?gdbvalgrind
0赞 Sam Mason 10/23/2023
内存泄漏意味着某些代码已成功运行,但在完成后仍分配了意外的内存。内存访问错误(即 Unix 系统中的段错误)意味着程序由于尝试访问无效的内存而崩溃。

答:

2赞 Philip Withnall 10/23/2023 #1

传递给的值必须全部是字符串(尽管字段的值的处理方式不同),因此必须传递而不是 for 。g_log_structured()MESSAGE"312"312CODE_LINE

g_log_structured()将无条件地将其读取为 ,这意味着它将取消引用指针 312 并崩溃。(这假设你所处的体系结构的指针和整数宽度相同。如果不是,它将读取不同的垃圾值,并崩溃略有不同。const char*