Добрый день.
Некоторое время назад мы наткнулись на интересный баг. Я был бы рад, если бы кто-то мог мне его объяснить.
Посмотрим на такой код
int main(){
for(;;);
return 0;
}
Скомпилируем его с помощью обычного g++. При запуске, он ожидаемо зависает. Прервем процесс.
Теперь попробуем сделать немного по-другому. Добавим в строку компиляции -Wl,--stack=925000001
. Запустим процесс, он снова зависнет(неожиданно правда?). Однако, при нажатии Ctrl+C, он полностью занимает ядро процессора и не собирается завершаться.
Константа 925000001 найдена бинпоиском, на границе эффект воспроизводится не очень стабильно, иногда не убивается один из 2-3 запусков. Воспроизвелось на нескольких Win7.
Проблема не у gcc, потому что у MSVS2010 происходит тоже самое, только начиная с 9400000001 стека.
Так же было бы интересно воспроизводится ли под другими версиями windows.
не воспроизвелось почему-то, запускал раз 10 :(
на xp в MSVS2010 с 9400000001 и gcc 4.6.1 с 925000001 и 9400000001 просто запускается и нормально отрабатывает ctrl-c как в explorer, так и в far
на win7x64 в gcc 9400000001 "недостаточно памяти для запуска программы..."
можете выложить сгенерированный exe-шник?
Попробуйте побольше стека. Думаю оно как-то завязано на 1GB.
Здесь код и два exe http://yadi.sk/d/JjhEDHHL4ga5a
воспроизвелось :)
как я понял это происходит из-за такой штуки: при нажатии ctrl-c винда обрабатывает твое действие и должна вызвать его обработчик, а обработчик вызывается в том процессе, которому передается это сообщение, т.е. создается поток, который должен начать выполнять ничего не делающую заглушку, а т.к. памяти для создания потока не хватит, то что-то фейлится
поправьте, если несу бред
Похоже, что мысль в верном направлении: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682541.aspx
Погодите-ка,
-Wl,--stack
влияет на все потоки процесса? Тогда легко понять, почему такое происходит: в 32-битном Windows по умолчанию программе доступны только 2 ГБ памяти, остальные 2 ГБ отводятся ядру. При запуске программы ~1 ГБ уже отводится на стек главному потоку, при Ctrl+C система пытается создать ещё один поток со стеком 1 ГБ — но памяти уже не хватает, поток не запускается и не прерывает программу.Как проверить: можно загрузить Windows с параметром
/3GB
(справка). Если предположение верно, то проблема исчезнет и появится снова при размере стека ~1,5 ГБ. Ещё можно программу запустить на 64-битном Windows (тогда ей вроде бы будут доступны 4 ГБ), или же скомпилировать как 64-битную.