OutputDebugString() в консоли

Я использую стороннюю библиотеку, которая использует функцию OutputDebugString() и при чтении документации MSDN, кажется, указывает, что это для печати в отладчике.

Но это неудобно в моем случае, есть ли способ прочитать этот вывод, если не подключен отладчик?

Если бы это была моя LIB, я бы предпочел, чтобы выходные данные переходили в stdout / stderr всякий раз, когда пользователь проходит --debug или аналогичные, но так как это не так, я ищу другие способы передачи этой информации в консоль (или файл) без подключения отладчика.

1 ответ

OutputDebugStringA генерировать исключение DBG_PRINTEXCEPTION_C (W версия в win10 - DBG_PRINTEXCEPTION_WIDE_C) с 2 аргументами - (длина строки в символах + 1, указатель строки) - в результате мы можем обработать это исключение самостоятельно (системный обработчик по умолчанию для этого исключения делает это).

пример обработчика для перенаправления OutputDebugString утешить:

LONG NTAPI VexHandler(PEXCEPTION_POINTERS ExceptionInfo)
{
    PEXCEPTION_RECORD ExceptionRecord = ExceptionInfo->ExceptionRecord;

    switch (ExceptionRecord->ExceptionCode)
    {
    case DBG_PRINTEXCEPTION_WIDE_C:
    case DBG_PRINTEXCEPTION_C:

        if (ExceptionRecord->NumberParameters >= 2)
        {
            ULONG len = (ULONG)ExceptionRecord->ExceptionInformation[0];

            union {
                ULONG_PTR up;
                PCWSTR pwz;
                PCSTR psz;
            };

            up = ExceptionRecord->ExceptionInformation[1];

            HANDLE hOut = GetStdHandle(STD_ERROR_HANDLE);

            if (ExceptionRecord->ExceptionCode == DBG_PRINTEXCEPTION_C)
            {
                // localized text will be incorrect displayed, if used not CP_OEMCP encoding 
                // WriteConsoleA(hOut, psz, len, &len, 0);

                // assume CP_ACP encoding
                if (ULONG n = MultiByteToWideChar(CP_ACP, 0, psz, len, 0, 0))
                {
                    PWSTR wz = (PWSTR)alloca(n * sizeof(WCHAR));

                    if (len = MultiByteToWideChar(CP_ACP, 0, psz, len, wz, n))
                    {
                        pwz = wz;
                    }
                }
            }

            if (len)
            {
                WriteConsoleW(hOut, pwz, len - 1, &len, 0);
            }

        }
        return EXCEPTION_CONTINUE_EXECUTION;
    }

    return EXCEPTION_CONTINUE_SEARCH;
}

а для установки этого обработчика нужно вызвать:

AddVectoredExceptionHandler(TRUE, VexHandler);

внедрение системы OutputDebugString как здесь - это действительно называется RaiseException именно с этими аргументами, только в обработчике исключений вместо MessageBox - код, описанный здесь.

Другие вопросы по тегам