2012-08-03 2 views
0

У нас есть многопоточное приложение C++, скомпилированное с g ++, работающим на встроенном powerpc. Для проверки утечки памяти это в ходе непрерывного теста интеграции мы создали анализатор кучи, который загружается с ld_preload.Должен ли загрузочный модуль LD_PRELOAD или просто использовать модуль для замены символов

Мы хотели бы гарантировать, что функция в модуле ld_preloaded вызывается до того, как что-либо еще произойдет (включая создание статических объектов и т. Д.). Еще более важно, что мы хотели бы иметь еще одну функцию, которая вызывается непосредственно перед выходом из процесса, поэтому анализатор кучи может выводить свои результаты. Проблема, которую мы видим, заключается в том, что вектор в нашем приложении создается в области глобального файла, прежде чем что-либо произойдет в нашем модуле ld_preloaded. Вектор растет в пределах основного. При выключении функция destructor в нашем предварительно загруженном модуле вызывается до того, как вектор будет уничтожен.

Есть ли способ кодировать предварительно загруженный модуль для запуска функции перед чем-либо еще и после всего остального? Мы пробовали использовать __attribute__((constructor)) и destructor без успеха.

Возвращаясь к заголовку вопроса, я начинаю подозревать, что ld только просматривает предварительно загруженный модуль при разрешении символов для последующих нагрузок модулей. Он не загружает предварительно загруженный модуль. Может ли кто-нибудь пролить свет на это для нас?

ответ

1

Первоначально вы не могли бы контролировать порядок конструкторов из разных единиц перевода. Таким образом, это распространяется и на общие библиотеки.

Однако новые версии GCC поддерживают применение параметра приоритета к атрибуту constructor, который должен позволять вам контролировать, когда ваша указанная функция будет выполняться по отношению к другим глобальным конструкторам. Приоритет по умолчанию, если не указан, является максимальным значением приоритета. Таким образом, любой уровень приоритета, который вы устанавливаете ниже, должен заставить ваш конструктор работать перед ними и ваш деструктор после них.

static int initialize() __attribute__((constructor(101))); 
static int deinitialize() __attribute__((destructor(101))); 

static int initialize() { 
    puts("initialized"); 
} 

static int deinitialize() { 
    puts("deinitialized"); 
} 

101 по-видимому, самый низкий уровень приоритета разрешено быть указан. 65535 - самый высокий. Сначала выполняются более низкие номера.

+0

К сожалению, это не повлияло. Дальнейшее чтение, кажется, предполагает, что существует бесконечный квест для реальной точки входа в приложение C++. – Fenster34

+1

Жаль, что это не сработало. Я могу только предложить обходное решение для вас тогда. Если вы динамически выделяете свой анализатор кучи, он никогда не будет уничтожен. Если он сохраняет свое состояние в файле с отображением памяти, вы можете проанализировать файл позже, когда программа закончится. – jxh

+0

Это отличная идея, поскольку она всегда гарантирована для работы. Мы решили изменить наш код, чтобы избежать проблемы, но я буду записывать это как будущий аспект. благодаря – Fenster34