Перехват приложений Windows при сбое и очистка файловых буферов - PullRequest
2 голосов
/ 03 августа 2011

Этот вопрос немного далекий, но я подумал, что, может быть, кто-то знает умное решение.

У меня есть особая ситуация с RTS-игрой в Windows ( Гнев Кейна ),который сохраняет файлы воспроизведения.Неблагоприятный противник может вызвать сбой в игре.В этом случае было бы полезно иметь как можно более полный файл воспроизведения.

Однако вывод файла воспроизведения выглядит буферизованным и происходит только в наборах по 4096 байт (что является большим временем игры).Мне интересно, можно ли каким-то образом заставить программу сбросить все свои файловые дескрипторы в случае сбоя.Есть ли какая-то встроенная функция ОС, позволяющая отключить буферизацию для приложения?

В противном случае я мог бы написать средство запуска / оболочки для этой проблемы.Я предполагаю, что он должен внедрить некоторый код, который а) устанавливает обработчик сигнала для сбоя (это SIGSEGV?), И б) перенаправляет CreateFile (который, я знаю, программа использует после отслеживания) для хранения дескриптора.Обработчик сбоя затем просто сбрасывает все обработчики с помощью FlushFileBuffers.

Или, возможно, возможно получить дескрипторы открытого файла другого процесса?

Будет ли это иметьшанс работать, и не могли бы вы дать мне какой-нибудь совет о том, как наилучшим образом добиться этого с наименьшим количеством вторжения?


Небольшое обновление: @CatPlusPlus предложил Объезды, чтобы подключиться к программе, перехватывать вызовы открытия файлов и изменять их, чтобы они были буферизованы.Это вполне может быть решением!

Ответы [ 3 ]

1 голос
/ 04 августа 2011

Предполагая, что процесс не ваш, вам кажется, что единственным вариантом является перехват функции WriteFile, и вместо этого следует выполнить WriteFile с последующим сбросом.
WriteFile может быть перехвачен IAT перехватом напрямую или с использованиембиблиотека типа eashook .

1 голос
/ 03 августа 2011

Ну, вы можете начать с обертывания winmain в блок try / catch, как описано в этом разделе. статья:

XCrashReport: Обработка исключений и отчеты о сбоях - часть 1

, который в основном делает что-то вроде этого:

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
    int Result = -1;
    __try
    {
        Result = HandledWinMain(hInstance, NULL, lpstrCmdLine, nCmdShow);
    }

    __except(RecordExceptionInfo(hInstance,GetExceptionInformation(), "main thread"))
    {
        // Do nothing here - RecordExceptionInfo() has already done
        // everything that is needed. Actually this code won't even
        // get called unless you return EXCEPTION_EXECUTE_HANDLER from
        // the __except clause.
    }

    return Result;
}

Конечно, я не уверен, каким будет состояние ваших буферов, но это позволит вам подключиться к процессу.

0 голосов
/ 03 августа 2011

Единственное, о чем я могу думать, это подключить отладчик и тинкер к выходу ассемблера.

Я помню, как делал это с некоторыми программами, когда они зависали на мне: перепрыгивай через машинные инструкции до конца функции и запускай.примерно в 50% всех случаев это позволило бы программе достичь точки, в которой я мог сохранить свои данные.Конечно, перезагрузка была обязательной.

...