Могу ли я использовать SetErrorMode в процессе C #? - PullRequest
6 голосов
/ 21 мая 2011

Я готовлюсь к написанию ядра онлайн-судьи,
Программа, которая может скомпилировать код пользователя и запустить программу, чтобы проверить ответ, как Uva Online судья.

И у меня возникла проблема с обнаружением исключения из программы отправки, как показано ниже.

int main()
{
    while(~scanf("%d %d",n,&m))
    {   
        printf("%d\n",n+m);
    }
    return 0;
}

в первой строке отказано в доступе, поскольку он сканирует целое число в позицию ошибки.
Как я могу отловить ошибки во время выполнения для моего процесса?

Раньше я использовал «try catch», чтобы поймать исключение,
но он ничего не ответил об ошибке во время выполнения.

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

Я должен закрыть окно сообщения об ошибке вручную,
и я нашел решение, которое заключается в использовании DLL-библиотеки SEH для этого процесса.

SetErrorMode(SEM_NOGPFAULTERRORBOX);

но я не знаю, как использовать его в процессе C #.

и ниже мой код судьи

timer = new Stopwatch();
timer.Reset();

submitProg = new Process();
submitProg.StartInfo.FileName = outputFile;
submitProg.StartInfo.UseShellExecute = false;
submitProg.StartInfo.CreateNoWindow = true;
submitProg.StartInfo.RedirectStandardInput = true;
submitProg.StartInfo.RedirectStandardOutput = true;
submitProg.StartInfo.RedirectStandardError = true;
submitProg.StartInfo.ErrorDialog = false;
submitProg.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
submitProg.EnableRaisingEvents = true;

submitProg.Start();
timer.Start();

progInput = submitProg.StandardInput;
progOutput = submitProg.StandardOutput;

progInput.Write(inputStream.ReadToEnd());
submitProg.StandardInput.Close();
while (!submitProg.HasExited)
{
    peakPagedMem = submitProg.PeakPagedMemorySize64;
    peakVirtualMem = submitProg.PeakVirtualMemorySize64;
    peakWorkingSet = submitProg.PeakWorkingSet64;
    if (peakPagedMem > memLimit)
    {
        submitProg.Kill();
    }
    if (timer.ElapsedMilliseconds > timeLimit)
    {
        timeLimitExceed = true;
        submitProg.Kill();
    }
}

timeUsed = timer.ElapsedMilliseconds;
timer.Stop();

if(submitProg.ExitCode!=0)systemRuntimeError = true;

Спасибо за помощь и извините за мой плохой английский.

==================================
приписка
Вопрос в том, как установить режим ошибки для дочернего процесса в C #.
Мой английский недостаточно хорош, чтобы объяснить проблему, извините. <(_ _)>

Ответы [ 2 ]

10 голосов
/ 21 мая 2011

Если вы имеете в виду функцию Win32 API SetErrorMode, тогда вам нужно будет использовать P / Invoke, , что легко с такой простой сигнатурой:

[DllImport("kernel32.dll")]
static extern ErrorModes  SetErrorMode(ErrorModes uMode);

[Flags]
public enum ErrorModes : uint {
    SYSTEM_DEFAULT             = 0x0,
    SEM_FAILCRITICALERRORS     = 0x0001,
    SEM_NOALIGNMENTFAULTEXCEPT = 0x0004,
    SEM_NOGPFAULTERRORBOX      = 0x0002,
    SEM_NOOPENFILEERRORBOX     = 0x8000
}

(Сайт http://www.pinvoike.net/ всегда является хорошим местом для начала, чтобы получить правильную декларацию.)

5 голосов
/ 21 мая 2011

Нельзя установить режим ошибки в другом процессе , не вставляя код в этот процесс. Что невозможно сделать легко в C #. Это не будет хорошо работать и в C / C ++, такого рода программы не живут достаточно долго, чтобы дать вам время для инъекций.

В любом случае, это не решит вашу проблему, вы также должны защищать от программ, которые никогда не завершаются после того, как застряли в бесконечном цикле. Простое решение - дать каждой программе ограниченное количество времени для выполнения. Скажи 10 секунд. Если это не завершается, тогда Process.Kill () это и объявляет ошибку. Это также позаботится о программах, которые запускают окно сообщений.

Тривиально для реализации с перегрузкой Process.WaitForExit (миллисекунды).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...