Видимость функции, вызывающая утечку памяти - PullRequest
0 голосов
/ 21 января 2020

Мое приложение A явно связывает мои .so библиотеки B1, B2 и др. c. используя общий внутренний API. Он перебирает их всех и использует dlopen (), за которым следует dlclose (). Библиотеки Bx статически связывают многие библиотеки, одной из которых является Caffe. Чтобы правильно освободить всю выделенную память (глобальные переменные), мне нужно вызвать функцию google :: protobuf :: ShutdownProtobufLibrary (). Bx использует ограничение на символы таблицы экспорта (я называю этот файл exportmap, т. Е. -Wl, - version-script = exportmap), чтобы указывать функции для экспорта клиентам, только функции из внутреннего API могут быть видны глобально. Все это написано на C ++.

1) Проблема в том, что если я использую эту настройку и выполняю бесконечную l oop в программе A:

while(1) {
  forall B in Bx { // loop over filepaths to .so libraries Bx
    hdl = dlopen(B, RTLD_LAZY);
    dlclose(hdl);
}}

программа будет постепенно увеличивать утечку памяти (память увеличивается до тех пор, пока не произойдет сбой).

2) Если я не использую exportmap на Bx, то программа не теряет память, но это верно только в случае, если больше чем 1 библиотека Bx. Если я вставлю 2 или более разных Bx, то снова будет присутствовать инкрементная утечка памяти.

3) Если я использую флаг RTLD_NODELETE в функции dlopen в программе A:

while(1) {
  forall B in Bx {
    hdl = dlopen(B, RTLD_LAZY | RTLD_NODELETE)
    dlclose(hdl);
}}

, и я отключаю При вызове google :: protobuf :: ShutdownProtobufLibrary () в библиотеках Bx нет никакого постепенного увеличения утечки памяти, но в protobuf останутся вещи, поэтому этот вариант пока лучший, но все же не идеальный.

Кто-нибудь может объяснить, как это возможно, что exportmap может вызвать утечку памяти и, возможно, как решить эту проблему без утечек памяти?

...