У меня очень странная ошибка, возникающая сейчас в довольно крупном C ++ приложении на работе (огромная с точки зрения использования процессора и оперативной памяти, а также длины кода - свыше 100 000 строк). Это работает на двухъядерной машине Sun Solaris 10. Программа подписывается на каналы цен акций и отображает их на «страницах», настроенных пользователем (страница - это оконная конструкция, настроенная пользователем - программа позволяет пользователю настраивать такие страницы). Эта программа работала без проблем, пока одна из базовых библиотек не стала многопоточной. Части программы, затронутые этим, были изменены соответствующим образом. На мою проблему.
Примерно один раз в каждые три запуска программы происходит сбой при запуске. Это не обязательно жесткое правило - иногда оно будет три раза подряд, а затем будет работать пять раз подряд. Это segfault, что интересно (читай: больно). Это может проявляться несколькими способами, но чаще всего случается, что функция A вызывает функцию B, и при входе в функцию B указатель кадра внезапно устанавливается на 0x000002. Функция A:
result_type emit(typename type_trait<T_arg1>::take _A_a1) const
{ return emitter_type::emit(impl_, _A_a1); }
Это простая реализация сигнала. impl_ и _A_a1 четко определены в их кадре при сбое. При фактическом выполнении этой инструкции мы оказываемся в программном счетчике 0x000002.
Это не всегда происходит с этой функцией. На самом деле это происходит в нескольких местах, но это один из более простых случаев, который не оставляет места для ошибок. Иногда случается, что переменная, размещенная в стеке, внезапно окажется в нежелательной памяти (всегда в 0x000002) безо всякой причины. В других случаях тот же код будет работать нормально. Итак, мой вопрос: что может так сильно испортить стек? Что на самом деле может изменить значение указателя кадра? Я конечно никогда не слышал о такой вещи. Единственное, о чем я могу думать, это записывать данные за пределы массива, но я построил его с помощью стекового протектора, который должен подходить для любых случаев этого. Я также хорошо в пределах моего стека здесь. Я также не вижу, как другой поток может перезаписать переменную в стеке первого потока, так как каждый поток имеет свой собственный стек (это все pthreads). Я пытался собрать это на Linux-машине, и, хотя у меня там нет segfaults, примерно один из трех раз он зависнет от меня.