[MSVC] Грабли: thread_local могут конструироваться до обычных глобальных
От: Alexander G Украина  
Дата: 15.03.17 13:06
Оценка: 18 (1)
thread_local переменные могут конструироваться до обычных глобальных переменных.

Это может происходить, если кто-то создаёт thread до того, как все глобальные объекты проинициализированы,
для этой нити и будет создан инстанс thread_local переменной.

Казалось бы, в здравом уме никто сам это делать не будет.
Но сторонние приложения тоже могут инджектить свои DLLки.
И это не обязательно malware, могут быть, например, и anti-malware.
Собственно, судя по дампу, там anti-malware.

Ещё одна деталь: для сторонних нитей конструктор thread_local вызывается из TLS-callback, а внутри PE Loader в ntdll все ислючения из TLS-коллбэков по-тихому ловятся.
(ловятся как SEH, т.е. если бросить С++ исключение, то С++ объект от него утечёт)

Так, легко не знать, что ситуация имеет место, пока не подебажишься.

Вывод: не пытайтесь ничего сложного делать в конструкторе thread_local переменной, если хотите работать в Windows.



Что же касается деструкторов thread_local, то с ними, думаю, всё в порядке.
Для нити main (или нити, вызвавшей exit) в силе комментарий из exit.cpp (200), снабженный даже ссылкой на стандарт:

// If this module has any dynamically initialized
// __declspec(thread) variables, then we invoke their
// destruction for the primary thread. All thread_local
// destructors are sequenced before any atexit calls or static
// object destructors (3.6.3/1)

Других нитей как бы не должно быть, и если они есть, то для них просто не будет вызван TLS-callback с DLL_THREAD_DETACH
(объект как бы утечёт вместе со всем остальным, что утекло от работающей нити).
Русский военный корабль идёт ко дну!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.