Блог пользователя PavelKunyavskiy

Автор PavelKunyavskiy, 12 лет назад, По-русски

Добрый день.

Некоторое время назад мы наткнулись на интересный баг. Я был бы рад, если бы кто-то мог мне его объяснить.

Посмотрим на такой код

int main(){
    for(;;);
    return 0;
}

Скомпилируем его с помощью обычного g++. При запуске, он ожидаемо зависает. Прервем процесс.

Теперь попробуем сделать немного по-другому. Добавим в строку компиляции -Wl,--stack=925000001. Запустим процесс, он снова зависнет(неожиданно правда?). Однако, при нажатии Ctrl+C, он полностью занимает ядро процессора и не собирается завершаться.

Константа 925000001 найдена бинпоиском, на границе эффект воспроизводится не очень стабильно, иногда не убивается один из 2-3 запусков. Воспроизвелось на нескольких Win7.

Проблема не у gcc, потому что у MSVS2010 происходит тоже самое, только начиная с 9400000001 стека.

Так же было бы интересно воспроизводится ли под другими версиями windows.

  • Проголосовать: нравится
  • +30
  • Проголосовать: не нравится

»
12 лет назад, # |
Rev. 3   Проголосовать: нравится +5 Проголосовать: не нравится

не воспроизвелось почему-то, запускал раз 10 :(

на xp в MSVS2010 с 9400000001 и gcc 4.6.1 с 925000001 и 9400000001 просто запускается и нормально отрабатывает ctrl-c как в explorer, так и в far

на win7x64 в gcc 9400000001 "недостаточно памяти для запуска программы..."

можете выложить сгенерированный exe-шник?

  • »
    »
    12 лет назад, # ^ |
      Проголосовать: нравится +8 Проголосовать: не нравится

    Попробуйте побольше стека. Думаю оно как-то завязано на 1GB.

    Здесь код и два exe http://yadi.sk/d/JjhEDHHL4ga5a

    • »
      »
      »
      12 лет назад, # ^ |
        Проголосовать: нравится +19 Проголосовать: не нравится

      воспроизвелось :)

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

      поправьте, если несу бред

      • »
        »
        »
        »
        12 лет назад, # ^ |
          Проголосовать: нравится +8 Проголосовать: не нравится

        Похоже, что мысль в верном направлении: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682541.aspx

        The system creates a new thread in each client process to handle the event.
        • »
          »
          »
          »
          »
          12 лет назад, # ^ |
          Rev. 2   Проголосовать: нравится +18 Проголосовать: не нравится

          Погодите-ка, -Wl,--stack влияет на все потоки процесса? Тогда легко понять, почему такое происходит: в 32-битном Windows по умолчанию программе доступны только 2 ГБ памяти, остальные 2 ГБ отводятся ядру. При запуске программы ~1 ГБ уже отводится на стек главному потоку, при Ctrl+C система пытается создать ещё один поток со стеком 1 ГБ — но памяти уже не хватает, поток не запускается и не прерывает программу.

          Как проверить: можно загрузить Windows с параметром /3GB (справка). Если предположение верно, то проблема исчезнет и появится снова при размере стека ~1,5 ГБ. Ещё можно программу запустить на 64-битном Windows (тогда ей вроде бы будут доступны 4 ГБ), или же скомпилировать как 64-битную.