Temos um problema sério com um aplicativo C # sendo encerrado silenciosamente em pontos aleatórios e não freqüentes em uma instalação do Windows 10 de 32 bits.
Por exemplo. pode ser um mês entre ocorrências. Ou às vezes apenas um dia.
Especificações básicas do sistema:
Microsoft Windows 10 Enterprise 2016 LTSB
Version 10.0.14393 Build 14393
32-bit
Usando link configuramos o monitoramento silencioso da saída do processo. E finalmente temos algumas amostras disso:
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.
Olhando os despejos para isso, que foi configurado para o monitoramento, recebemos um ID de processo para o svchost. Este serviço ainda estava sendo executado no sistema e mostra a seguinte lista de serviços:
Oquepareceserumalistade"netsvcs" para o Windows. Abrindo o dump do svchost.exe
e observando isso, um único encadeamento foi encontrado com uma pilha de chamadas interessante:
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 ()
O UBPM é o Unified Background Process Manager. Mas como isso pode terminar nossa aplicação? E porque? E o que o código de encerramento 1067
nos diz?
Abaixo está a entrada de registro do 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>
NOTAS: O PC não está sendo desligado no momento em que o aplicativo é encerrado nem há outras indicações nos registros de eventos sobre o motivo pelo qual o processo foi encerrado.
UPDATE 1: Aqui estão alguns detalhes adicionais (tentando responder tantos quanto nos comentários):
- O processo é (às vezes) iniciado pelo TaskScheduler quando o Windows é iniciado, sim. Outras vezes pelo usuário. Problema não inteiramente certo só ocorre quando iniciado via TaskScheduler. Mas ponto interessante? Janelas poderiam matar uma tarefa por algum motivo? Observe que os tempos entre a saída do processo podem ser de até um mês.
- Temos a fonte do programa principal, mas teríamos problemas para executá-lo dentro de um depurador, já que isso está sendo executado em um cliente, mas talvez. Nós não podemos executá-lo compilado para Debug embora. Não, devido ao desempenho. Esta é a produção ao vivo.
- O aplicativo é um aplicativo normal do WPF sem nenhum processo filho ou qualquer outra comunicação entre processos. Ele usa alguns dispositivos de terceiros, por exemplo bibliotecas e drivers.
- Nós configuramos a manipulação de eventos de exceções de appdomain e exceções de aplicativos, etc. Nenhuma dessas ações ocorre. O processo sai sem qualquer indicação de uma exceção ocorrendo. É uma saída difícil do processo.
- Suspeitamos que talvez um driver de terceiros seja a fonte, mas como? E como poderíamos determinar se este era o caso?
UPDATE 2: Usamos o pacote nuget TaskScheduler
para configurar a tarefa via código. Note que não definimos o ExecutionTimeLimit, que deve ser Nothing e, portanto, infinito.
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);
}
UPDATE 3: Talvez a afirmação acima esteja errada, o padrão na biblioteca TaskScheduler
parece ser de 3 dias ou 72 horas.
//
// 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; }
ATUALIZAÇÃO 4: A única coisa é que observamos saídas de processo silenciosas depois que o processo foi executado por muito mais tempo que 3 dias, por ex. 30 dias, então não tenho certeza que é isso depois de tudo.
ATUALIZAÇÃO 5: O tempo de mais de 3 dias não foi corretamente observado, portanto, depois de tudo, ficou claro que isso ocorreu devido a configurações incorretas da tarefa do agendador de tarefas. As configurações incorretas mostradas abaixo:
Configuraçõescorretassendo: