Встроенный Perl FREETMPS неправильно очищает массив хеш-ссылок

У меня есть проект с несколькими макросами, которые помогают мне писать функции Perl и в основном «преобразовывать» структуры C в хэши Perl. Некоторые из этих хэшей вложены друг в друга, но я перейду к сути.

Использование памяти моей программой резко возрастает с течением времени, это интерфейс для социальных сетей, написанный на C и Embedded Perl (странный выбор языка, но это неважно). Я на 100% уверен, что нашел основную причину кода, так как его удаление и другие вещи приводят к его исчезновению, и я также профилировал его, и каждая проблема указывает на мой массив хэшей.

      if (notifs && notifs_len)
{
    // Leak occurs here
    mXPUSHs(newRV_noinc((SV*)perlify_notifications(notifs, notifs_len)));
}
else ARG_UNDEFINED();


// Run function
PERL_STACK_SCALAR_CALL("base_page");
char* dup = PERL_GET_STACK_EXIT;

Где PERL_GET_STACK_EXIT — это макрос, который соответствует

      #define PERL_GET_STACK_EXIT savesharedsvpv(POPs);   \
    PUTBACK;                                        \
    FREETMPS;                                       \
    LEAVE;                                          \
    perl_unlock()

// Macros for storing data
#define hvstores_str(hv, key, val) if (val) { hv_stores((hv), key, newSVpv((val), 0)); }
#define hvstores_int(hv, key, val) hv_stores((hv), key, newSViv((val)))
#define hvstores_ref(hv, key, val) if (val) {  hv_stores((hv), key, newRV_noinc((SV*)(val))); }

создается с помощью другого макроса.

      // Calls one of the `perlify_X` functions for each element in an array
// Note: I was not using av_push before, I only temporarily switched thinking that was the issue or if I was misreading the docs
// EX: PERLIFY_MULTI(notification, notifications, notification_t
#define PERLIFY_MULTI(type, types, mstype) AV* perlify_##types(const struct mstype* const types, size_t len) { \
    if (!(types && len)) return NULL;                               \
    AV* av = newAV();                                               \
    for (size_t i = 0; i < len; ++i)                                \
        av_push(av, newRV_noinc((SV*)perlify_##type(types + i)));   \
    return av;                                                      \
}

Сделав шаг вперед, вот хеш-функции. Такой какв коде.

      // Converts it into a perl struct
HV* perlify_notification(const struct mstdnt_notification* const notif)
{
    if (!notif) return NULL;
    HV* notif_hv = newHV();

    // Profiler doesn't show much data leaking for these 4, so I am uncertain
    hvstores_str(notif_hv, "id", notif->id);
    hvstores_int(notif_hv, "created_at", notif->created_at);
    hvstores_str(notif_hv, "emoji", notif->emoji);
    hvstores_str(notif_hv, "type", mstdnt_notification_t_to_str(notif->type));
    // The functions below seem to leak the most (and they store a bunch of data), if I comment them out, most of the
    // memleak is gone (because these output a lot of data). The functions
    // being called look equivalent to this one, so it's no secret.
    hvstores_ref(notif_hv, "account", perlify_account(notif->account));
    hvstores_ref(notif_hv, "pleroma", perlify_notification_pleroma(notif->pleroma));
    hvstores_ref(notif_hv, "status", perlify_status(notif->status));
    
    return notif_hv;
}

Я попытался скомпилировать весь Perl из исходного кода, так как я на Gentoo, чтобы отладить эту проблему и изучить внутренности FREETMPS, и попытался увидеть, что происходит. Я пытался сбросить все ссылки, которые мог, но каждый объект имел REFCNT, равный 1. Не повезло

Когда я запускал это с помощью массива, просматривая его с помощью Top, я просто наблюдал, как медленно увеличивается память. Я проверил свою удачу с помощью проб и ошибок: он начинается примерно с 9 МБ, затем медленно увеличивается до 15–25 МБ использования памяти, пока я продолжаю вызывать эти функции снова и снова. Конечно, если я закомментирую FREETMPS или просто запущу функции без каких-либо других действий, использование памяти увеличится с той же скоростью, что и раньше. Я все еще уверен, что это основная проблема.

Я действительно в растерянности, я делаю что-то не так с тем, как я «перлифифицирую» свои структуры C?

0 ответов

Другие вопросы по тегам