У меня проблемы с _1 _ / _ 2_ и их подключением к stdio (_3 _ / _ 4 _ / _ 5_ стандартные указатели файлов). Я годами успешно использую эту последовательность:
int main(int argc, char **argv)
{
FreeConsole();
AllocConsole();
freopen("CONIN$", "rb", stdin);
freopen("CONOUT$", "wb", stdout);
freopen("CONOUT$", "wb", stderr);
(см., например, этот вопрос). Однако в Windows10 с последними обновлениями я получаю исключение 0xC0000008 в freopen
. Обратите внимание, что
- Я вижу это только во время сеансов отладки (VS2017, конфигурация отладки). Кажется, что нормальный запуск приложения и конфигурация выпуска тоже работают (или, может быть, исключение автоматически игнорируется?).
- Это случается очень часто, но не повторяется. Иногда первый freopen выходит из строя, иногда второй, иногда третий, иногда ни один из них.
- Отладчик перехватывает исключение (я знаю, что могу его выключить, но я бы предпочел не делать этого, так как это вообще интересное событие). Когда я принудительно продолжаю программу, кажется, что программа работает правильно. Однако я вовсе не уверен, что состояние CRT все еще безопасно.
- Если я добавлю
fclose(stdin); fclose(stdout); fclose(stderr)
передFreeConsole
, исключение произойдет вFreeConsole
.
Вопросов:
- Что-то не так в приведенной выше последовательности?
- Как правильно подключить стандартные указатели файлов к новой консоли?
- Есть ли способ избежать этого исключения (т.е. убедиться, что этого не происходит, а не просто игнорировать)? Во время сеансов отладки это очень раздражает.
Больше информации:
- Я использую VS2017, но программа использует набор инструментов VS2013.
- Программа скомпилирована для x86 (32 бита).
- Как в конфигурации отладки, так и в конфигурации выпуска используются библиотека DLL-Multithread (/ MD) и многобайтовый набор символов.
- ОС Windows10-64 Professional 1903 - 18362.720
Спасибо заранее
FreeConsole
. В противном случае закрытие вfreopen
может сбрасываться до недопустимого дескриптора. Как есть, он позволяет избежать утечки дескрипторов, посколькуFreeConsole
не закрывает общие дескрипторы консоли (для \ Device \ ConDrv \ Input и \ Device \ ConDrv \ Output, которые изначально установлены в стандартных дескрипторах процесса), аAllocConsole
открывает новую общую консоль ручки. Эта утечка дескриптора была ошибкой с тех пор, как condrv.sys был добавлен в Windows 8. - person Eryk Sun   schedule 24.03.2020FreeConsole
и проанализировать вызов, который вызывает исключениеSTATUS_INVALID_HANDLE
. Я бы хотел, но не могу воспроизвести проблему в 10.0.18363. - person Eryk Sun   schedule 24.03.2020NtClose
дамп информации о дескрипторе. В отладчиках платформы (windbg, cdb) значение дескриптора должно быть? poi(@esp + 4)
, и вы можете выгрузить информацию о дескрипторе через!handle <handle value> f
. Кроме того, текущие стандартные дескрипторы (StandardInput
и т. Д.) Находятся в параметрах процесса?? @$peb->ProcessParameters
. - person Eryk Sun   schedule 24.03.2020