У нас есть серьезная проблема с тихим завершением приложения C # в случайные и редкие моменты времени при установке 32-разрядной версии Windows 10. Например, это может быть месяц между событиями. Или иногда просто день.
Основные технические характеристики системы:
Microsoft Windows 10 Enterprise 2016 LTSB
Version 10.0.14393 Build 14393
32-bit
Используя https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/setting-and-clearing-flags-for-silent-process-exit, мы настроили бесшумный мониторинг выхода из процесса. И у нас наконец есть несколько образцов этого:
The process 'APPLICATIONPATH\APPLICATIONNAME.exe' was terminated by
the process 'C:\Windows\System32\svchost.exe' with termination code 1067.
The creation time for the exiting process was 0x01d43bd8689073eb.
Рассматривая дампы для этого, который был настроен для мониторинга, мы получили идентификатор процесса для svchost. Эта служба все еще работала в системе, и она показывает следующий список служб:
Который, кажется, список "netsvcs" для Windows. Открыв дамп из svchost.exe
и посмотрев на него, был найден единственный поток с интересным стеком вызовов:
ntdll.dll!_KiFastSystemCallRet@0 ()
ntdll.dll!_NtWaitForSingleObject@12 ()
ntdll.dll!RtlReportSilentProcessExit()
KERNELBASE.dll!TerminateProcess()
ubpm.dll!_UbpmpTerminateProcessCallback@12 ()
ubpm.dll!UbpmUtilsTimerCallback()
ntdll.dll!TppTimerpExecuteCallback()
ntdll.dll!TppWorkerThread()
kernel32.dll!@BaseThreadInitThunk@12 ()
ntdll.dll!__RtlUserThreadStart()
ntdll.dll!__RtlUserThreadStart@8 ()
UBPM - это унифицированный диспетчер фоновых процессов. Но как это может прекратить наше приложение? И почему? А что говорит нам код завершения 1067
?
Ниже приведена запись в журнале от Silent Process Monitoring:
Log Name: Application
Source: Microsoft-Windows-ProcessExitMonitor
Date: 2018-08-31 15:26:09
Event ID: 3001
Task Category: None
Level: Information
Keywords: Classic
User: SYSTEM
Computer: PC
Description:
The process 'APPLICATIONPATH\APPLICATIONNAME.exe' was terminated by the process 'C:\Windows\System32\svchost.exe' with termination code 1067. The creation time for the exiting process was 0x01d43ed2aee892ab.
Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft-Windows-ProcessExitMonitor" Guid="{FD771D53-8492-4057-8E35-8C02813AF49B}" EventSourceName="Process Exit Monitor" />
<EventID Qualifiers="16384">3001</EventID>
<Version>0</Version>
<Level>4</Level>
<Task>0</Task>
<Opcode>0</Opcode>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2018-08-31T13:26:09.988216500Z" />
<EventRecordID>4853</EventRecordID>
<Correlation />
<Execution ProcessID="0" ThreadID="0" />
<Channel>Application</Channel>
<Computer>PC</Computer>
<Security UserID="S-1-5-18" />
</System>
<EventData Name="EVENT_PROCESSTERMINATION_CROSSPROCESS">
<Data Name="param1">APPLICATIONPATH\APPLICATIONNAME.exe</Data>
<Data Name="param2">C:\Windows\System32\svchost.exe</Data>
<Data Name="param3">1067</Data>
<Data Name="param4">01d43ed2aee892ab</Data>
</EventData>
</Event>
ЗАМЕЧАНИЯ: ПК не выключается в момент завершения работы приложения, и в журналах событий отсутствуют какие-либо другие указания относительно того, почему процесс был остановлен.
ОБНОВЛЕНИЕ 1: Здесь несколько дополнительных деталей (пытаясь ответить столько же, сколько в комментариях):
- Процесс (иногда) запускается через TaskScheduler, когда Windows запускается да. В другое время пользователем. Не совсем уверен, что проблема возникает только при запуске через TaskScheduler. Но интересный момент? Может ли Windows по какой-то причине убить задачу? Обратите внимание, что время между выходом из процесса может составлять до месяца.
- У нас есть исходный код для основной программы, но могут возникнуть проблемы с его запуском в отладчике, так как он выполняется на клиенте, но, возможно,. Мы не можем запустить его скомпилировано для отладки. Вовсе нет, из-за производительности. Это живое производство.
- Приложение - это обычное приложение WPF без каких-либо дочерних процессов или какого-либо другого межпроцессного взаимодействия. Он использует несколько сторонних устройств, например, библиотеки и драйверы.
- У нас есть настроенная обработка событий исключений приложений, доменов приложений и т.д. Ничего из этого не происходит. Процесс завершается без каких-либо признаков возникновения исключения. Это сложный процесс выхода.
- Мы подозревали, что источником может быть сторонний драйвер, но как? И как мы могли определить, было ли это так?
ОБНОВЛЕНИЕ 2: Мы используем пакет TaskScheduler
для настройки задачи с помощью кода. Обратите внимание, что мы не устанавливаем ExecutionTimeLimit, который, следовательно, должен быть Nothing и, следовательно, бесконечным.
using (TaskService m_service = new TaskService())
{
var task = m_service.NewTask();
task.Principal.UserId = userId;
task.Principal.LogonType = TaskLogonType.InteractiveToken;
task.Principal.RunLevel = TaskRunLevel.Highest;
task.Settings.Enabled = true;
task.Settings.MultipleInstances = TaskInstancesPolicy.IgnoreNew;
task.Settings.Hidden = false;
// NOTICE: A subset of the following 4 settings will cause app to hang on Win10
//task.Settings.AllowHardTerminate = true;
//task.Settings.DisallowStartOnRemoteAppSession = false;
//task.Settings.RunOnlyIfLoggedOn = true;
var trigger = (LogonTrigger)task.Triggers.Add(new LogonTrigger());
trigger.Enabled = true;
trigger.UserId = userId;
task.Actions.Add(new ExecAction(executableFilePath, arguments: null,
workingDirectory: m_installDirectoryPath));
if (!IsAdministrator())
{
var message = "Cannot register task with your current identity's permissions level.";
m_logger.Error(message);
}
m_service.RootFolder.RegisterTaskDefinition(taskName, task, TaskCreation.Create,
userId, password: null, logonType: TaskLogonType.InteractiveToken);
}
ОБНОВЛЕНИЕ 3: Возможно, вышеупомянутое утверждение было неверным, по умолчанию в библиотеке TaskScheduler
кажется, 3 дня или 72 часа.
//
// Summary:
// Gets or sets the amount of time that is allowed to complete the task. By default,
// a task will be stopped 72 hours after it starts to run.
//
// Remarks:
// If a task is started on demand, the ExecutionTimeLimit setting is bypassed. Therefore,
// a task that is started on demand will not be terminated if it exceeds the ExecutionTimeLimit.
[DefaultValue(typeof(TimeSpan), "3")]
public TimeSpan ExecutionTimeLimit { get; set; }
ОБНОВЛЕНИЕ 4: Единственное, что мы наблюдаем, - тихий процесс завершается после того, как процесс запущен гораздо дольше, чем 3 дня, например, 30 дней, поэтому не уверен, что это так.
ОБНОВЛЕНИЕ 5: более 3 дней не было правильно соблюдено, поэтому после всего, что теперь стало ясно, это было связано с неправильными настройками для задачи планировщика задач. Неправильные настройки показаны ниже:
Правильные настройки: