Почему символы оператора new&delete в shared-obj должны перемещаться, даже если они реализованы в этом shared-obj?

Я пытаюсь реализовать свои собственные операторы C++ new & delete в моей программе, как показано ниже:

#include <stdio.h>
#include <stdlib.h>
#include <new>

using namespace std;

void *operator new(std::size_t size) throw(std::bad_alloc)
{
    printf("My new is called!\n");
    return malloc(size);
}

void operator delete(void *ptr) throw ()
{
    printf("My delete is called!\n");
    free(ptr);
}

void *operator new(std::size_t size, const std::nothrow_t&) throw()
{
    return malloc(size);
}

void operator delete(void *ptr, const std::nothrow_t&) throw()
{
    free(ptr);
}

void *operator new[](std::size_t size) throw(std::bad_alloc)
{
    return malloc(size);
}

void operator delete[](void *ptr) throw () 
{
    free(ptr);
}

void *operator new[](std::size_t size,
                     const std::nothrow_t&) throw()
{
    return malloc(size);
}

void operator delete[](void *ptr,
                       const std::nothrow_t&) throw()
{
    free(ptr);
}

class Object
{
public:
    Object() {}
    ~Object() {}

private:
    int a;
};

int main()
{
    Object* obj = new Object();
    if (obj)
        delete obj;

    return 0;
}

Затем я обнаружил, что если программа построена как: - exe, то мой new/delete вызывается, как и ожидалось, - но, это общий объект, тогда символы new & delete должны быть перемещены, поэтому в мой env, когда это загружено dlopen в другой программе, тогда новый & delete будет сопоставлен с новым & delete другой программы...

Подробная информация как ниже...

  1. построить exe:

    gcc -m32 -c main.cpp gcc -m32 main.o -o main.exe

    $./main.exe Мой новый называется! Моё удаление называется!

    $ objdump -d main.exe 080484ac:
    80484ac: 55 push% ebp
    80484ad: 89 e5 mov% esp,% ebp
    80484af: 53 push% ebx
    80484b0: 83 ec 24 sub $ 0x24,% esp
    80484b3: 83 e4 f0 и $ 0xfffffff0,% esp
    80484b6: b8 00 00 00 00 mov $ 0x0,% eax
    80484bb: 83 c0 0f добавить $ 0xf,% eax
    80484be: 83 c0 0f добавить $ 0xf,% eax
    80484c1: c1 e8 04 shr $ 0x4,% eax
    80484c4: c1 e0 04 shl $ 0x4,% eax
    80484c7: 29 c4 sub% eax,% esp
    80484c9: c7 04 24 04 00 00 00 movl $ 0x4, (% esp)
    80484d0: e8 1f ff ff ff call 80483f4 <_Znwj> -> new: ожидается!!
    80484d5: 89 c3 mov% eax,% ebx
    80484d7: 89 1c 24 mov% ebx, (% esp)
    80484da: e8 35 00 00 00, вызов 8048514 <_ZN6ObjectC1Ev>
    80484df: 89 5d f8 mov% ebx, -0x8 (% ebp)
    80484e2: 83 7d f8 00 cmpl $ 0x0, -0x8 (% ebp)
    80484e6: 74 22 je 804850a
    80484e8: 8b 45 f8 mov -0x8 (% ebp),% eax
    80484eb: 89 45 e8 mov% eax, -0x18 (% ebp)
    80484ee: 83 7d e8 00 cmpl $ 0x0, -0x18 (% ebp)
    80484f2: 74 16 je 804850a
    80484f4: 8b 45 e8 mov -0x18 (% ebp),% eax
    80484f7: 89 04 24 mov% eax, (% esp)
    80484fa: e8 1b 00 00 00, вызов 804851a <_ZN6ObjectD1Ev>
    80484ff: 8b 45 e8 mov -0x18 (% ebp),% eax
    8048502: 89 04 24 mov% eax, (% esp)
    8048505: e8 0a ff ff ff call 8048414 <_ZdlPv> -> delete: ожидается

  2. построить общий объект:

    gcc -m32 -c main.cpp gcc --shared -m32 main.o -o main.so

    $ objdump -d main.so 000006d4:
    6d4: 55 push% ebp
    6d5: 89 e5 mov% esp,% ebp
    6d7: 53 push% ebx
    6d8: 83 ec 24 sub $ 0x24,% esp
    6 дБ: 83 e4 f0 и $ 0xfffffff0,% esp
    6de: b8 00 00 00 00 mov $ 0x0,% eax
    6e3: 83 c0 0f добавить $ 0xf,% eax
    6e6: 83 c0 0f добавить $ 0xf,% eax
    6e9: c1 e8 04 shr $ 0x4,% eax
    6ec: c1 e0 04 shl $ 0x4,% eax
    6ef: 29 c4 sub% eax,% esp
    6f1: c7 04 24 04 00 00 00 movl $ 0x4, (% esp)
    6f8: e8 fc ff ff ff call 6f9 ---> new: подлежит перемещению, неожиданно:(
    6fd: 89 c3 mov% eax,% ebx
    6ff: 89 1c 24 mov% ebx, (% esp)
    702: e8 fc ff ff ff call 703
    707: 89 5d f8 mov% ebx, -0x8 (% ebp)
    70a: 83 7d f8 00 cmpl $ 0x0, -0x8 (% ebp)
    70e: 74 22 je 732
    710: 8b 45 f8 mov -0x8 (% ebp),% eax
    713: 89 45 e8 mov% eax, -0x18 (% ebp)
    716: 83 7d e8 00 cmpl $ 0x0, -0x18 (% ebp)
    71a: 74 16 je 732
    71c: 8b 45 e8 mov -0x18 (% ebp),% eax
    71f: 89 04 24 mov% eax, (% esp)
    722: e8 fc ff ff ff call 723 ---> delete: подлежит перемещению, неожиданно:(
    727: 8b 45 e8 mov -0x18 (% ebp),% eax
    72a: 89 04 24 mov% eax, (% esp)
    72d: e8 fc ff ff ff call 72e

1 ответ

Решение

но разделяемый объект, то символы new & delete должны быть перемещены

Это точно так, как задумано (в этом отношении общие библиотеки UNIX работают совсем не так, как общие библиотеки Windows).

Причина: вставка символов. Например, в UNIX вы можете связать альтернативную реализацию malloc (например, tcmalloc) с основным исполняемым файлом и каждой общей библиотекой, включая libc.so который предоставляет свой собственный malloc, будет вызывать ваш malloc.

Если вы хотите добиться связывания Windows-подобных символов в UNIX, -Bsymbolic Флаг компоновщика может делать то, что вы хотите (читать man ld на вашей платформе).

Если вы используете Linux или Solaris, gcc -shared -Wl,-Bsymbolic ... должен делать то, что вы хотите. Осторожно: есть много ошибок, идущих "против системы". Вы можете сожалеть, пытаясь сделать это таким образом.

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