LINUX.ORG.RU

C++: перегруженные new/delete не работают в shared libraries?!


0

0

Собственно, subj.

Если сделать такую библиотеку:

#include <stdio.h>
#include <stdlib.h>
void * operator new(size_t n)
{ 
  printf("operator new(%d)\n",n);
  return malloc(n); 
}
void operator delete(void* p)
{ 
  printf("operator delete(%X)\n",p);
  return free(p); 
}
class my_struct {
  char data[0x10000];
};
my_struct *mystr = new my_struct;
extern "C" {
 extern void Cleanup () {
        printf("cleaning up...\n");
        delete mystr;
 }
}

загрузить, поработать и выгрузить ее dlopen/dlsym/dlclose, операторы
new/delete заиспользуются вовсе не мои перегруженные, а стандартные.
как же быть, если мне позарез нужно перегрузить new/delete в моей
конкретной библиотеке?

Да, а в обычных екзешниках все мои new/delete работают...


Как workaround, можно все своё хозяйство обернуть namespace My, но это же не выход...

jek_
() автор топика

Расскажи с какими опциями вызывался dlopen и покажи как выглядит твои new и delete в разделяемой библиотеке с точки зрения nm (только предварительно озаботься demanglингом, чтобы не было очень страшно).

anonymous
()
Ответ на: комментарий от anonymous

dlopen("./libmylib.so", RTLD_LAZY)

demangl'а у меня к сожалению нет и freshmeat.net про такого зверя не
знает :(

nm выдает вот что

// ...snip...
000007c8 t _Z41__static_initialization_and_destruction_0ii
0000079e T _ZdlPv
00000774 T _Znwj

jek_
() автор топика
Ответ на: комментарий от jek_

Я посмотрел в отлачике - вызов new идет не в мой _Znwj (то бишь new),
а в недра libstdc++ - в libstdc++::_Znwj.

jek_
() автор топика
Ответ на: комментарий от jek_

Попробуй dlopen с RTLD_GLOBAL (за подробностями man dlopen). "T большое" вроде бы правильно, так что, насколько я понимаю, после этого должно заработать.

А по поводу demangle поищи соответствующую опцию у nm или используй c++filt , но за прилежание все равно пятерка ;)

anonymous
()
Ответ на: комментарий от anonymous

RTLD_GLOBAL не помогает.

#include <stdio.h>
#include <dlfcn.h>
int main() {
  void *dll;
  char dllname[] = "./libmylib.so";
  printf("loading %s...\n", dllname);
  dll = dlopen(dllname, RTLD_LAZY | RTLD_GLOBAL);
  if(dll) {
    dlclose(dll);
    printf("unloading %s...\n", dllname);
  } else {
    printf("error: %s...\n", dlerror());
  }
  return 0;
}

jek_
() автор топика
Ответ на: комментарий от jek_

... те же грабли .. когда-то "баловался" с этим ...
Вроде под linux все получалось. Проблемы были с M$ windows (VC), потому что linker у них совсем другой (двух-проходной).
Решение было - не перегружать new/delete, а "подстaвлять" свой malloc/free, который выполнялся, как
pointer to function.

Хотелось бы отметить один момент. Если есть динамически
перегружаемые new/delete, то необходимо помнить каким
new/delete-ом (старым или новым) создавался "обьект", т.е.
созданные старым_new - должны уничтожаться старым_delete,
и наоборот,
созданные новым_new - должны уничтожаться новым_delete,
a также новый_delete должен уметь delete по-старому.

Без флагов внутри "обьектa", каким старым или новым new
он был создан не обойтись. Одним словом - геммор.

Подумай, зачем тебе это надо? ;-)


Valeriy_Onuchin ★★
()

Может, дело в статическом mystr? Он инициализируется до всего -- возможно, на него перегрузка не действует... Достаточно глупо всё это, но попробуй его в функу засунуть -- что получится?

С уважением -- Смоляное Чучелко

anonymous
()
Ответ на: комментарий от jek_

> dll = dlopen(dllname, RTLD_LAZY | RTLD_GLOBAL);

А связывание функций где? Или ты думаешь, что библиотеку загрузил и функи на неё переставились?

С уважением -- Смоляное Чучелко

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.