"Тихий" запуск служебного подпроцесса

Тема в разделе ".NET", создана пользователем evan, 28 мар 2007.

Статус темы:
Закрыта.
  1. evan

    evan Гость

    Здравствуйте.
    В общем, стоит такая задача: создать систему автоматического тестирования для некоей сложной функции, находящейся в Win32 unmanaged DLL. Система тестирования должна вызывать эту функцию много раз с разными входными данными, сохраняя результат вызова в логах. Исходников DLL нет (имеет место нечто вроде аутсорсинговой разработки).
    Для решения задачи решено сделать на c# два модуля: маленький консольный wrapper принимает во входных параметрах примерно то же самое, что надо передать в функцию, делает LoadLibrary/GetProcAddress, вызывает функцию, и результаты через сокет передает второму модулю, который рисует GUI и ведет логи. Если wrapper умирает, второй модуль отмечает этот факт в логах, перезапускает wrapper и продолжает тестирование. Исключения, которые выбрасываются из DLLки, ловятся в try/catch во wrapper'е, и пишутся в логи.
    Теперь собственно проблема: в DLLке могут быть ошибки выделения памяти и другие неприятные вещи, которые в этом дотнетовском wrapper'е кончаются тем, что try/catch никаких исключений не видит, но после завершения функции main() вдруг вываливается исключение, сообщение о котором выводится, как положено, в MessageBox'е. Вот этот эффект (вывод MessageBox с сообщением об ошибке) необходимо побороть, т.е. сделать так, чтобы процесс просто молча умирал. Можно также скрыть и консоль wrapper'а, но это не обязательно. Добиваться этого можно как модификацией самого wrapper'а, так и запускающего его модуля.
    Приветствуются идеи любой степени смутности :rolleyes:
     
  2. mr_ST

    mr_ST Гость

    1) ИМХО, лучше бы писать враппер на обычных плюсах (С++) бо там простор для маневра больше, плюс вожности системы по отлову нестандартных ситуаций.

    2) Врапперу, после окончания тестировани произвести самоубийство, а не просто выходить из мэйна :rolleyes: То бишь TerminateProcess(self, uExitCode)


    Да, и посмотри что пишут в msdn на тему SEH вообще и SetUnhandledExceptionFilter функции в частности.
     
  3. evan

    evan Гость

    1) Такой вариант (с wrapper'ом на с++) тоже пробовали, разницы особой нет.
    2) С TerminateProcess щас попробую, спасибо.
     
  4. mr_ST

    mr_ST Гость

    Там с системой проще работать, с тем же Structured Exception Handling, все ж native среда.
     
  5. evan

    evan Гость

    Для: mr_ST
    Вдохновившись твоими советами, нашел сразу две интересных вещи. Во-первых, вариант с TerminateProcess (точнее, с дотнетовским System.Diagnostics.Process.GetCurrentProcess().Kill() ) срабатывает, хотя я пока не понимаю почему :rolleyes:
    Во-вторых, Win32'шные SetErrorMode и SetUnhandledExceptionFilter - вообще прям то что доктор прописал. К сожалению, перевод всего враппера на win32 нужно согласовывать с заказчиком, и еще неизвестно чем это кончится. В принципе, SetErrorMode нормально отрабатывает и когда я его вызываю из c#, но с SetUnhandledExceptionFilter я так извращаться не стал.
    Не знаешь, нет ли дотнетовских аналогов у этих функций? У AppDomain есть event UnhandledException, но это лишь дает возможность добавить свой обработчик, как загасить с его помощью MessageBox, генерируемый дефолтовым обработчиком, я не нашел. Да и при GP fault он почему-то не вызывается, видимо, чисто под System.Exception заточен.
     
  6. mr_ST

    mr_ST Гость

    Все дело в волшебных пузырьках :rolleyes: Дело в том, что когда выходишь из main, там может выполняться еще куча кода, типа деструкции статических обьектов, провека хипа на консистентность и т.п. При самоубийстве этого не происходит, т.е. code flow уходит в TerminateProcess и уже не возвращается. Как это работает в .NET затрудняюсь ответить, но, видимо, в DLL просто не вызывается код отвечающий за окнчание работы оной.

    Скорее всего нет, т.к. это сильно платформозависимые вещи. А у домена только обработка .NET исключений.
     
  7. karlito

    karlito Гость

    try
    {

    }
    catch(Exception ex)
    {

    }
    catch
    {
    // здесь перехватываются исключения не производные от System.Exception
    // смотри класс System.Runtime.InteropServices.Marshal,
    // там найдёшь некоторые функции для работы c неуправляемым кодом
    }
     
  8. evan

    evan Гость

    Для: karlito
    Спасибо за неравнодушие, но это всё я и так знаю. Исключение возникает после выхода из main.
     
  9. evan

    evan Гость

    Проблема решена путем перехода на win32 (VC++ 6.0) и использования функций SetErrorMode и SetUnhandledExceptionFilter. Для надежности вызываю TerminateProcess из UnhandledExceptionFilter.
    Спасибо всем ответившим.
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей