Como você deve diagnosticar o erro SEHException - O componente externo lançou uma exceção

86

Sempre que um usuário relata um erro como

System.Runtime.InteropServices.SEHException - O componente externo lançou uma exceção?

há algo que eu, como programador, possa fazer para determinar a causa?

Cenário: um usuário (usando um programa que minha empresa escreveu) relatou este erro. Isso pode ou não ter sido um erro único. Eles mencionaram que no último mês, o computador 'parou de funcionar' duas vezes. Aprendi com a experiência a não interpretar essa descrição muito literalmente, pois geralmente significa que alguém que está se relacionando com o computador não está funcionando como esperado. Eles não puderam me fornecer mais detalhes e eu não consegui encontrar nenhum erro registrado. Portanto, pode ou não ter sido esse erro.

A partir do rastreamento da pilha, o erro real foi ao construir uma classe que não chama diretamente nenhum código de interoperabilidade, mas talvez complicado pelo fato de que o objeto pode fazer parte de uma lista que é ligada a um DevExpress Grid.

O erro foi 'detectado' por uma rotina de exceção não tratada que normalmente fecha o programa, mas tem a opção de ignorar e continuar. Se eles optaram por ignorar o erro, o programa continuou funcionando, mas o erro voltou a ocorrer na próxima execução dessa rotina. No entanto, isso não ocorreu novamente após fechar e reiniciar nosso aplicativo.

O computador em questão não parecia estressado. Ele está rodando o Vista Business, tem 2 GB de memória e de acordo com o Gerenciador de Tarefas estava usando apenas cerca de metade disso com nosso aplicativo apenas cerca de 200 Mb.

Existe uma outra informação que pode ou não ser relevante. Outra seção do mesmo programa usa um componente de terceiros que é efetivamente um wrapper dotnet em torno de uma dll nativa e este componente tem um problema conhecido onde, muito ocasionalmente, você obtém um

Tentativa de ler ou gravar memória protegida. Isso geralmente é uma indicação de que outra memória está corrompida

Os fabricantes de componentes dizem que isso foi corrigido na versão mais recente de seus componentes, que estamos usando internamente, mas isso ainda não foi fornecido ao cliente.

Dado que as consequências do erro são baixas (nenhum trabalho é perdido e reiniciar o programa e voltar para onde estava leva apenas um minuto no máximo) e dado que o cliente em breve receberá uma nova versão (com o terceiro atualizado componente de festa), obviamente posso cruzar os dedos e esperar que o erro não ocorra novamente.

Mas há algo mais que eu possa fazer?

Sgmoore
fonte

Respostas:

28

Sim. Este erro é uma exceção estruturada que não foi mapeada para um erro .NET. Provavelmente é o mapeamento do DataGrid lançando uma exceção nativa que não foi capturada.

Você pode saber qual exceção está ocorrendo observando a propriedade ExternalException.ErrorCode . Eu verificaria seu rastreamento de pilha e, se estiver vinculado à grade DevExpress, relataria o problema a eles.

Reed Copsey
fonte
1
StackTrace não mencionou DevExpress em lugar nenhum, apenas minha classe. Terá que verificar para ver qual era o ErrorCode.
sgmoore
Nesse caso, tente descobrir o que exatamente gerou a mensagem de erro.
Reed Copsey de
4
"observando a propriedade ExternalException.ErrorCode" - você tem alguma dica sobre como exatamente fazer isso? O VS me mostra "Ocorreu uma exceção não tratada do tipo 'System.Runtime.InteropServices.SEHException' em .... dll Informações adicionais: Eine externe Komponente hat eine Ausnahme ausgelöst.", Mas diferente de, por exemplo, aplicativos C #, não há link para ver os "Detalhes" do objeto de exceção em qualquer lugar.
OR Mapper
O depurador do VSCode mostra uma instância $ exception em Locals - isso inclui um campo Message, que inclui o código e uma mensagem de erro legível por humanos.
nightblade9
8

Eu tive um problema semelhante com uma SEHException que foi lançada quando meu programa usou pela primeira vez um wrapper dll nativo. Descobri que a DLL nativa desse wrapper estava faltando. A exceção não ajudou de forma alguma a resolver isso. O que ajudou no final foi executar o procmon em segundo plano e verificar se havia algum erro ao carregar todas as DLLs necessárias.

Maurice Gilden
fonte
3

Os fabricantes de componentes dizem que isso foi corrigido na versão mais recente de seus componentes, que estamos usando internamente, mas isso já foi fornecido ao cliente.

Pergunte ao fabricante do componente como testar se o problema que o cliente está tendo é o problema que ele afirma ter corrigido em sua versão mais recente, sem / antes de implantar a versão mais recente para o cliente.

ChrisW
fonte
1

Encontrei este erro quando o aplicativo reside em um compartilhamento de rede e o dispositivo (laptop, tablet, ...) é desconectado da rede enquanto o aplicativo está em uso. No meu caso, foi devido a um tablet Surface sair do alcance sem fio. Sem problemas após instalar um WAP melhor.

Conrad
fonte
1
Eu estava recebendo aleatoriamente enquanto acessava diferentes tipos de reflexão (GetAssemblyName, GetProperty, Activator, etc.) em meu código e em bibliotecas de terceiros, e apenas em um ambiente de cliente, da mesma forma com bibliotecas em local remoto. Há muitas evidências de que é um bug do framework .net.
Andriy K
Andriy K: Não acho que seja um problema do .NET, acho que os identificadores de arquivo (s) aberto (s) no compartilhamento de rede foram perdidos / eliminados de alguma forma, talvez um bug no Windows ou problema de rede. Os assemblies são mapeados na memória e serão paginados do disco sob demanda (bomba-relógio), possivelmente a memória também pode ser descartada em situações de pouca memória. Se os identificadores de arquivo abertos não forem estáveis, isso provavelmente explodirá em fumaça. O .NET poderia talvez ter lidado com isso e reaberto o arquivo (suavizar o problema), mas pode ser complicado.
osexpert
Eu tenho o mesmo problema. Eu obtenho System.Runtime.InteropServices.SEHException (0x80004005) sem rastreamento de pilha. Esta é a InnerException de um TargetInvocationException. O TargetInvocationException tem rastreamento de pilha, mas não fazia sentido para mim, pois parecia vir de main ou Application.Run. Acontece de forma muito aleatória, principalmente à noite \ noite. Acho que a única "solução" é não executar a partir da unidade de rede: - | Talvez eu adicione uma verificação que pode bloquear este cenário: stackoverflow.com/questions/8633680/…
osexpert
0

Apenas mais uma informação ... Tive esse problema hoje em um sistema Windows 2012 R2 x64 TS onde o aplicativo foi iniciado a partir de um caminho unc / rede. O problema ocorreu em um aplicativo para todos os usuários do servidor de terminal. Executar o aplicativo localmente funcionou sem problemas. Após uma reinicialização, ele começou a funcionar novamente - a SEHException lançada foi Construtor init e TargetInvocationException


fonte
0

Configurações da minha máquina:

Sistema operacional: Windows 10 versão 1703 (x64)

Eu enfrentei este erro ao depurar meu projeto C # .Net no Visual Studio 2017 Community edition. Eu estava chamando um método nativo executando p / invoke em um assembly C ++ carregado em tempo de execução. Encontrei o mesmo erro relatado pelo OP.

Percebi que o Visual Studio foi iniciado com uma conta de usuário que não era de administrador na máquina. Em seguida, reiniciei o Visual Studio com uma conta de usuário diferente, que era um administrador na máquina. Isso é tudo. Meu problema foi resolvido e não o encarei novamente.

Uma coisa a notar é que o método que estava sendo invocado no assembly C ++ deveria escrever algumas coisas no registro. Não fui depurar o código C ++ para fazer um RCA, mas vejo a possibilidade de que tudo estava falhando, pois são necessários privilégios administrativos para escrever o registro no sistema operacional Windows 10. Portanto, antes, quando o Visual Studio estava sendo executado em uma conta de usuário que não tinha privilégios administrativos na máquina, as chamadas nativas estavam falhando.

RBT
fonte
0

Recebi este erro ao executar testes de unidade no cache de memória que estava configurando. Ele inundou o cache. Depois de invalidar o cache e reiniciar a VM, funcionou bem.

atreyHazelHispanic
fonte