Есть ли способ в C / C ++ определить, работает ли код во время статической инициализации? - PullRequest
4 голосов
/ 20 июля 2010

Я пишу библиотеку трассировки, которая доступна как DLL.Это потребляется в основном каждым компонентом в моей системе.Одно хитрое требование заключается в том, что функции трассировки должны вызываться очень рано в течение времени жизни процесса, даже до запуска main ().

Потребители этой библиотеки включают исполняемые файлы, статически связанные библиотеки DLL, библиотеки с задержкой загрузки и динамически загружаемые библиотеки.библиотеки DLL.Все варианты.

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

Просить потребителей сделать явный вызов "Я закончил, инициализация" сами по себе не делает "t работают из-за того, что некоторые потребители сами являются DLL и не контролируют исполняемый файл, на котором они размещаются.Та же самая проблема просто перемещается на один уровень вверх по цепочке.

Я надеюсь, что у меня есть какой-то способ спросить среду выполнения, выполняется ли в данный момент статическая инициализация или этот этап завершен,Это возможно?

Чтобы еще больше усложнить ситуацию, мне нужно работать на 5 платформах.Мне не нужно решение для однократной записи, но мне нужно, чтобы оно работало как-то на всех платформах.

Ответы [ 3 ]

1 голос
/ 21 июля 2010

Глобальная переменная? Что-то вроде:

bool initTime = true;

в вашей DLL, а затем

int main()
{
  initTime = false;
  // your main code comes here
}

в вашем исполняемом файле.

0 голосов
/ 21 июля 2010

Возможно, вам придется переписать (ну, изменить), а затем связать с переписанным crt0.o.Очевидно, что для каждой платформы это должно быть по-разному.

0 голосов
/ 21 июля 2010

Вы пишете, что

Некоторые функции трассировки плохо воспроизводятся со статической инициализацией, но другие все в порядке.

Однако в большинстве случаев проблема заключается не в фазе статической инициализации исполняемого файла (процесса), а в фазе статической инициализации библиотеки DLL /. Вы должны знать, что каждая DLL имеет свою собственную фазу статической инициализации для своего статического объекта C ++. В частности, у вашей библиотеки трассировки есть и другие библиотеки DLL, которые могут использовать вашу библиотеку DLL.

Подводя итог: Возможно, вам все равно, завершена ли фаза статической инициализации исполняемого файла, но вам делать важно, если а) ваша собственная DLL завершила инициализацию и б) если во время вызова вашей DLL Блокировка загрузчика в настоящее время удерживается.

Что касается a) Если ваша DLL завершена, инициализация - это только проблема внутри вашего кода, поскольку никто не может вызвать вашу DLL до ее инициализации.

Что касается б) Кажется, что нет никакого (переносимого, документированного) способа определить из кода, удерживается ли в данный момент блокировка загрузчика. Я не знаю другого способа, кроме как четко документировать, какие функции нельзя вызывать, пока удерживается блокировка загрузчика.

...