Skip to content

lyd_new_opaq2 function memory leak #2461

@sicongPang

Description

@sicongPang

Hello, we are using libyang version 2.1.30. During debugging, we noticed that the memory usage keeps increasing when calling the lyd_new_opaq2 function.
By capturing the call stack, it was found that the lyd_new_opaq2 function is suspected of having a memory leak:

Thread 38 "DefSch0101" hit Hardware access (read/write) watchpoint 1: (long)0x7f40388af000
Value = 0

0x00007f40f081eaa7 in ?? () from /usr/lib64/libc.so.6
#0  0x00007f40f081eaa7 in ?? () from /usr/lib64/libc.so.6
#1  0x00007f411432cd14 in calloc () from /opt/ccell/lib/libmemmonitor.so
#2  0x00007f40ed265403 in ?? () from /opt/depend/lib/nos/libyang.so.2
#3  0x00007f40ed26841c in lyd_new_opaq2 () from /opt/depend/lib/nos/libyang.so.2
#4  0x00007f40ee3c7928 in OMA_DataTree_LoadAllFields () from /opt/depend/lib/nos/liboma.so

Looking at the code, lyd_new_opaq2 calls the lyd_create_opaq function, which contains a local variable named "opaq":

LY_ERR
lyd_create_opaq(const struct ly_ctx *ctx, const char *name, size_t name_len, const char *prefix, size_t pref_len,
        const char *module_key, size_t module_key_len, const char *value, size_t value_len, ly_bool *dynamic,
        LY_VALUE_FORMAT format, void *val_prefix_data, uint32_t hints, struct lyd_node **node)
{
    LY_ERR ret = LY_SUCCESS;
    struct lyd_node_opaq *opaq;

    assert(ctx && name && name_len && format);

    if (!value_len && (!dynamic || !*dynamic)) {
        value = "";
    }

    opaq = calloc(1, sizeof *opaq);
    LY_CHECK_ERR_GOTO(!opaq, LOGMEM(ctx); ret = LY_EMEM, finish);

    opaq->prev = &opaq->node;
    LY_CHECK_GOTO(ret = lydict_insert(ctx, name, name_len, &opaq->name.name), finish);

    if (pref_len) {
        LY_CHECK_GOTO(ret = lydict_insert(ctx, prefix, pref_len, &opaq->name.prefix), finish);
    }
    if (module_key_len) {
        LY_CHECK_GOTO(ret = lydict_insert(ctx, module_key, module_key_len, &opaq->name.module_ns), finish);
    }
    if (dynamic && *dynamic) {
        LY_CHECK_GOTO(ret = lydict_insert_zc(ctx, (char *)value, &opaq->value), finish);
        *dynamic = 0;
    } else {
        LY_CHECK_GOTO(ret = lydict_insert(ctx, value, value_len, &opaq->value), finish);
    }

    opaq->format = format;
    opaq->val_prefix_data = val_prefix_data;
    opaq->hints = hints;
    opaq->ctx = ctx;

finish:
    if (ret) {
        lyd_free_tree(&opaq->node);
        ly_free_prefix_data(format, val_prefix_data);
    } else {
        *node = &opaq->node;
    }
    return ret;
}

The opaq variable is allocated using the alloc function within this function, but the final return only returns the pointer &opaq->node. How is the deallocation of the opaq variable handled? No obvious deallocation point is seen in the current function.

Looking forward to your reply, thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    is:questionIssue is actually a question.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions