Pergunta

Estou trabalhando em um projeto usando o ANTLR biblioteca de analisador para C#.Eu construí uma gramática para analisar algum texto e funciona bem.No entanto, quando o analisador encontra um token ilegal ou inesperado, ele lança uma das muitas exceções.O problema é que, em alguns casos (não todos), meu bloco try/catch não o detecta e, em vez disso, interrompe a execução como uma exceção não tratada.

O problema para mim é que não posso replicar esse problema em nenhum outro lugar, exceto em meu código completo.A pilha de chamadas mostra que a exceção definitivamente ocorre no meu bloco try/catch(Exception).A única coisa que consigo pensar é que existem algumas chamadas de assembly ANTLR que ocorrem entre meu código e o código que gera a exceção e esta biblioteca não tem a depuração habilitada, então não posso percorrê-la.Gostaria de saber se os assemblies não depuráveis ​​inibem o surgimento de exceções?A pilha de chamadas se parece com isto;chamadas de assembly externas estão em Antlr.Runtime:

    Expl.Itinerary.dll!TimeDefLexer.mTokens() Line 1213 C#
    Antlr3.Runtime.dll!Antlr.Runtime.Lexer.NextToken() + 0xfc bytes 
    Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.FillBuffer() + 0x22c bytes   
    Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.LT(int k = 1) + 0x68 bytes
    Expl.Itinerary.dll!TimeDefParser.prog() Line 109 + 0x17 bytes   C#
    Expl.Itinerary.dll!Expl.Itinerary.TDLParser.Parse(string Text = "", Expl.Itinerary.IItinerary Itinerary = {Expl.Itinerary.MemoryItinerary}) Line 17 + 0xa bytes C#

O trecho de código da chamada inferior em Parse() se parece com:

     try {
        // Execution stopped at parser.prog()
        TimeDefParser.prog_return prog_ret = parser.prog();
        return prog_ret == null ? null : prog_ret.value;
     }
     catch (Exception ex) {
        throw new ParserException(ex.Message, ex);
     }

Para mim, uma cláusula catch (Exception) deveria ter capturado qualquer exceção.Existe alguma razão para que isso não aconteça?

Atualizar: Rastreei a montagem externa com o Reflector e não encontrei nenhuma evidência de rosqueamento.O assembly parece ser apenas uma classe de utilitário de tempo de execução para o código gerado pelo ANTLR.A exceção lançada é do método TimeDefLexer.mTokens() e seu tipo é NoViableAltException, que deriva de RecognitionException -> Exception.Esta exceção é lançada quando o lexer não consegue entender o próximo token no fluxo;em outras palavras, entrada inválida.Esta exceção é SUPOSTA, mas deveria ter sido detectada pelo meu bloco try/catch.

Além disso, o relançamento de ParserException é realmente irrelevante para esta situação.Essa é uma camada de abstração que aceita qualquer exceção durante a análise e a converte em minha própria ParserException.O problema de tratamento de exceções que estou enfrentando é nunca atingir essa linha de código.Na verdade, comentei a parte "lançar nova ParserException" e ainda recebi o mesmo resultado.

Mais uma coisa: modifiquei o bloco try/catch original em questão para capturar NoViableAltException, eliminando qualquer confusão de herança.Ainda recebi o mesmo resultado.

Certa vez, alguém sugeriu que às vezes o VS fica hiperativo na captura de exceções tratadas no modo de depuração, mas esse problema também acontece no modo de liberação.

Cara, ainda estou perplexo!Eu não tinha mencionado isso antes, mas estou executando o VS 2008 e todo o meu código é 3.5.A montagem externa é 2.0.Além disso, alguns dos meus códigos subclassificam uma classe no assembly 2.0.Uma incompatibilidade de versão pode causar esse problema?

Atualização 2: Consegui eliminar o conflito de versão do .NET portando partes relevantes do meu código .NET 3.5 para um projeto .NET 2.0 e replicando o mesmo cenário.Consegui replicar a mesma exceção não tratada ao executar consistentemente no .NET 2.0.

Aprendi que o ANTLR lançou recentemente o 3.1.Então, atualizei do 3.0.1 e tentei novamente.Acontece que o código gerado foi um pouco refatorado, mas a mesma exceção não tratada ocorre em meus casos de teste.

Atualização 3:Eu repliquei esse cenário em um projeto simplificado do VS 2008.Sinta-se à vontade para baixar e inspecionar o projeto você mesmo.Apliquei todas as ótimas sugestões, mas ainda não consegui superar esse obstáculo.

Se você puder encontrar uma solução alternativa, compartilhe suas descobertas.Obrigado novamente!


Obrigado, mas o VS 2008 quebra automaticamente em exceções não tratadas.Além disso, não tenho uma caixa de diálogo Debug->Exceptions.A NoViableAltException lançada é totalmente intencional e projetada para ser capturada pelo código do usuário.Como não é capturado conforme o esperado, a execução do programa é interrompida inesperadamente como uma exceção não tratada.

A exceção lançada é derivada de Exception e não há multithreading acontecendo com ANTLR.

Foi útil?

Solução

Acredito que entendo o problema.A exceção está sendo detectada, o problema é a confusão sobre o comportamento do depurador e as diferenças nas configurações do depurador entre cada pessoa que tenta reproduzi-lo.

No terceiro caso da sua reprodução, acredito que você esteja recebendo a seguinte mensagem:"NoViableAltException não foi tratado pelo código do usuário" e uma pilha de chamadas semelhante a esta:

         [External Code]    
    >   TestAntlr-3.1.exe!TimeDefLexer.mTokens() Line 852 + 0xe bytes   C#
        [External Code] 
        TestAntlr-3.1.exe!TimeDefParser.prog() Line 141 + 0x14 bytes    C#
        TestAntlr-3.1.exe!TestAntlr_3._1.Program.ParseTest(string Text = "foobar;") Line 49 + 0x9 bytes C#
        TestAntlr-3.1.exe!TestAntlr_3._1.Program.Main(string[] args = {string[0x00000000]}) Line 30 + 0xb bytes C#
        [External Code] 

Se você clicar com o botão direito na janela da pilha de chamadas e executar a ativação de mostrar código externo, verá isto:

        Antlr3.Runtime.dll!Antlr.Runtime.DFA.NoViableAlt(int s = 0x00000000, Antlr.Runtime.IIntStream input = {Antlr.Runtime.ANTLRStringStream}) + 0x80 bytes   
        Antlr3.Runtime.dll!Antlr.Runtime.DFA.Predict(Antlr.Runtime.IIntStream input = {Antlr.Runtime.ANTLRStringStream}) + 0x21e bytes  
    >   TestAntlr-3.1.exe!TimeDefLexer.mTokens() Line 852 + 0xe bytes   C#
        Antlr3.Runtime.dll!Antlr.Runtime.Lexer.NextToken() + 0xc4 bytes 
        Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.FillBuffer() + 0x147 bytes   
        Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.LT(int k = 0x00000001) + 0x2d bytes  
        TestAntlr-3.1.exe!TimeDefParser.prog() Line 141 + 0x14 bytes    C#
        TestAntlr-3.1.exe!TestAntlr_3._1.Program.ParseTest(string Text = "foobar;") Line 49 + 0x9 bytes C#
        TestAntlr-3.1.exe!TestAntlr_3._1.Program.Main(string[] args = {string[0x00000000]}) Line 30 + 0xb bytes C#
        [Native to Managed Transition]  
        [Managed to Native Transition]  
        mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x39 bytes    
        Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x2b bytes  
        mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x3b bytes   
        mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x81 bytes    
        mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x40 bytes

A mensagem do depurador informa que uma exceção originada fora do seu código (de NoViableAlt) está passando pelo código que você possui em TestAntlr-3.1.exe!TimeDefLexer.mTokens() sem ser tratada.

A redação é confusa, mas não significa que a exceção não foi detectada.O depurador está informando que o código que você possui mTokens()" precisa ser robusto contra essa exceção lançada por meio dele.

Coisas para brincar para ver como fica para quem não reproduziu o problema:

  • Vá para ferramentas/opções/depuração e desligue "Ativar apenas meu código (apenas gerenciado)".ou opção.
  • Vá para o depurador/exceções e desative o "User-Indled" para obter exceções de tempo de execução em língua comum.

Outras dicas

Independentemente de o assembly ter sido compilado como uma compilação de lançamento, a exceção certamente deve 'borbulhar' para o chamador, não há razão para que um assembly não sendo compilado no modo de depuração tenha qualquer efeito sobre isso.

Eu concordo que Daniel está sugerindo que talvez a exceção esteja ocorrendo em um thread separado - tente conectar o evento de exceção do thread em Application.ThreadException.Isso deve ser gerado quando ocorrer qualquer exceção de thread não tratada.Você poderia adaptar seu código assim: -

using System.Threading;

...

void Application_ThreadException(object sender, ThreadExceptionEventArgs e) {
  throw new ParserException(e.Exception.Message, e.Exception);
}    

 ...

 var exceptionHandler = 
    new ThreadExceptionEventHandler(Application_ThreadException);
 Application.ThreadException += exceptionHandler;
 try {
    // Execution stopped at parser.prog()
    TimeDefParser.prog_return prog_ret = parser.prog();
    return prog_ret == null ? null : prog_ret.value;
 }
 catch (Exception ex) {
    throw new ParserException(ex.Message, ex);
 }
 finally {
    Application.ThreadException -= exceptionHandler;
 }

Você está usando .Net 1.0 ou 1.1?Nesse caso, catch(Exception ex) não capturará exceções de código não gerenciado.Você precisará usar catch {}.Veja este artigo para mais detalhes:

http://www.netfxharmonics.com/2005/10/net-20-trycatch-and-trycatchexception/

Posso te contar o que está acontecendo aqui...

O Visual Studio está quebrando porque acha que a exceção não foi tratada.O que significa não tratado?Bem, no Visual Studio, há uma configuração nas Ferramentas...Opções...Depurando...Em geral..."Ativar Just My Code (somente gerenciado)".Se isto estiver marcado e se a exceção se propagar para fora do seu código e para um quadro de pilha associado a uma chamada de método que existe em um assembly que é "NÃO SEU CÓDIGO" (por exemplo, Antlr), isso é considerado "não tratado".Desativei o recurso Ativar Just My Code por esse motivo.Mas, se você me perguntar, isso é ridículo...digamos que você faça isso:

ExternalClassNotMyCode c = new ExternalClassNotMyCode();
try {
    c.doSomething( () => { throw new Exception(); } );
}
catch ( Exception ex ) {}

doSomething chama sua função anônima e essa função lança uma exceção...

Observe que esta é uma "exceção não tratada" de acordo com o Visual Studio se "Ativar apenas meu código" estiver ativado.Além disso, observe que ele para como se fosse um ponto de interrupção quando está no modo de depuração, mas em um ambiente sem depuração ou de produção, o código é perfeitamente válido e funciona conforme o esperado.Além disso, se você apenas "continuar" no depurador, o aplicativo continuará alegremente (não interromperá o thread).É considerado "não tratado" porque a exceção se propaga através de um quadro de pilha que NÃO está no seu código (ou seja,na biblioteca externa).Se você me perguntar, isso é péssimo.Altere este comportamento padrão Microsoft.Este é um caso perfeitamente válido de uso de Exceções para controlar a lógica do programa.Às vezes, você não pode alterar a biblioteca de terceiros para se comportar de outra maneira, e esta é uma forma muito útil de realizar muitas tarefas.

Veja MyBatis, por exemplo, você pode usar esta técnica para interromper o processamento de registros que estão sendo coletados por uma chamada para SqlMapper.QueryWithRowDelegate.

É possível que a exceção esteja sendo lançada em outro thread?Obviamente, seu código de chamada é de thread único, mas talvez a biblioteca que você está consumindo esteja realizando algumas operações multithread nos bastidores.

Estou com @Shaun Austin - tente encerrar o try com o nome totalmente qualificado

catch (System.Exception)

e veja se isso ajuda. O documento ANTLR diz quais exceções devem ser lançadas?

Para mim, uma cláusula catch (Exception) deveria ter capturado qualquer exceção.Existe alguma razão para que isso não aconteça?

A única possibilidade que consigo pensar é que outra coisa esteja capturando-o antes de você e manipulando-o de uma maneira que pareça ser uma exceção não detectada (por exemplo,sair do processo).

meu bloco try/catch não o detecta e, em vez disso, interrompe a execução como uma exceção não tratada.

Você precisa descobrir o que está causando o processo de saída.Pode ser algo diferente de uma exceção não tratada.Você pode tentar usar o depurador nativo com um ponto de interrupção definido em "{,,kernel32.dll}ExitProcess".Então use SOS para determinar qual código gerenciado está chamando o processo de saída.

Pessoalmente, não estou nem um pouco convencido pela teoria do threading.

A única vez que vi isso antes, eu estava trabalhando com uma biblioteca que também definia Exception e os usos que eu queria dizer que o Catch real estava se referindo a um tipo de "Exceção" diferente (se tivesse sido totalmente qualificado, seria Company. Lib.Exception, mas não foi por causa do uso), então, quando se tratava de capturar uma exceção normal que estava sendo lançada (algum tipo de exceção de argumento, se bem me lembro), ela simplesmente não a capturava porque o tipo não correspondia.

Então, em resumo, existe outro tipo de exceção em um namespace diferente que esteja em uso nessa classe?

EDITAR:Uma maneira rápida de verificar isso é certificar-se de que em sua cláusula catch você qualifique totalmente o tipo de exceção como "System.Exception" e experimente!

EDITAR2:OK, tentei o código e admito a derrota por enquanto.Terei que dar uma nova olhada nisso pela manhã se ninguém encontrar uma solução.

Hum, não entendo o problema.Baixei e testei seu arquivo de solução de exemplo.

Uma exceção é lançada em TimeDefLexer.cs, linha 852, que é posteriormente tratada pelo bloco catch em Program.cs que apenas diz Exceção tratada.

Se eu descomentar o bloco catch acima dele, ele entrará nesse bloco.

O que parece ser o problema aqui?

Como Kibbee disse, o Visual Studio irá parar nas exceções, mas se você pedir para continuar, a exceção será capturada pelo seu código.

Baixei o projeto VS2008 de amostra e também estou um pouco perplexo aqui.No entanto, consegui superar as exceções, embora provavelmente não de uma forma que funcione bem para você.Mas aqui está o que encontrei:

Esse postagem na lista de discussão discutimos o que parece ser o mesmo problema que você está enfrentando.

A partir daí, adicionei algumas classes fictícias no arquivo program.cs principal:

class MyNoViableAltException : Exception
{
    public MyNoViableAltException()
    {
    }
    public MyNoViableAltException(string grammarDecisionDescription, int decisionNumber, int stateNumber, Antlr.Runtime.IIntStream input)
    {
    }
}
class MyEarlyExitException : Exception
{
    public MyEarlyExitException()
    {
    }

    public MyEarlyExitException(int decisionNumber, Antlr.Runtime.IIntStream input)
    {
    }
}

e então adicionei as linhas using em TimeDefParser.cs e TimeDefLexer.cs:

using NoViableAltException = MyNoViableAltException;
using EarlyExitException = NoViableAltException; 

Com isso, as exceções apareceriam nas classes de exceção falsas e poderiam ser tratadas lá, mas ainda havia uma exceção sendo lançada no método mTokens em TimeDefLexer.cs.Envolver isso em um try catch naquela classe capturou a exceção:

            try
            {
                alt4 = dfa4.Predict(input);
            }
            catch
            {
            }

Eu realmente não entendo por que envolvê-lo no método interno, em vez de onde ele está sendo chamado, para lidar com o erro se o threading não estiver em jogo, mas de qualquer forma, espero que isso aponte alguém mais inteligente do que eu aqui na direção certa.

Baixei seu código e tudo funcionou conforme o esperado.

O depurador do Visual Studio intercepta corretamente todas as exceções.Os blocos Catch funcionam conforme o esperado.

Estou executando o servidor Windows 2003 SP2, VS2008 Team Suite (9.0.30729.1 SP)

Tentei compilar seu projeto para .NET 2.0, 3.0 e 3.5

@Steve Steiner, as opções do depurador que você mencionou não têm nada a ver com esse comportamento.

Tentei brincar com essas opções sem efeitos visíveis - os blocos catch conseguiram interceptar todas as exceções.

Steve Steiner está correto ao afirmar que a exceção se origina na biblioteca antlr, passa pelo método mTokens() e é capturada na biblioteca antlr.O problema é que esse método é gerado automaticamente pelo antlr.Portanto, quaisquer alterações para lidar com a exceção em mTokens() serão substituídas quando você gerar suas classes de analisador/lexer.

Por padrão, o antlr registrará erros e tentará recuperar a análise.Você pode substituir isso para que parser.prog() gere uma exceção sempre que um erro for encontrado.Pelo seu código de exemplo, acho que esse é o comportamento que você esperava.

Adicione este código ao seu arquivo gramatical (.g).Você também precisará desativar "Ativar Just My Code" no menu de depuração.

@members {

    public override Object RecoverFromMismatchedSet(IIntStream input,RecognitionException e,    BitSet follow)  
    {
        throw e;
    }
}

@rulecatch {
    catch (RecognitionException e) 
    {
        throw e;
    }
}

Esta é minha tentativa de uma versão C# do exemplo dado no capítulo "Saindo do reconhecedor no primeiro erro" do livro "Referência Definitiva do ANTLR".

Espero que isto seja o que você estava procurando.

Você pode configurar o VS.Net para quebrar assim que ocorrer qualquer exceção.Basta executar seu projeto no modo de depuração e ele será interrompido assim que a exceção for lançada.Então você deve ter uma ideia melhor de por que ele não está sendo detectado.

Além disso, você pode colocar algum código em capturar todas as exceções não tratadas.Leia o link para mais informações, mas o básico são essas duas linhas.

Application.ThreadException += new ThreadExceptionEventHandler(ThreadExceptionHandler);

 // Catch all unhandled exceptions in all threads.
 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);

Ah, e em referência ao que Kibbee disse;se você selecionar Debug|Exceptions no VS e apenas clicar em todas as caixas na coluna 'lançada', deverá escolher tudo considera o AFAIK uma 'exceção de primeira chance', ou seja,VS indicará quando a exceção for sobre para ser processado por todo o resto e quebrar o código relevante.Isso deve ajudar na depuração.

A melhor opção é configurar o Visual Studio para interromper todas as exceções não tratadas (caixa de diálogo Depurar -> Exceções, marque a caixa "Exceções do Common Language Runtime" e possivelmente as outras também).Em seguida, execute seu programa em modo de depuração.Quando o código do analisador ANTLR lança uma exceção, ele deve ser capturado pelo Visual Studio e permitir que você veja onde está ocorrendo, o tipo de exceção, etc.

Com base na descrição, o bloco catch parece estar correto, então uma de várias coisas pode estar acontecendo:

  1. o analisador não está realmente lançando uma exceção
  2. o analisador está lançando algo que não deriva de System.Exception
  3. há uma exceção sendo lançada em outro thread que não está sendo tratado

Parece que você potencialmente descartou o problema nº 3.

Rastreei a montagem externa com o Reflector e não encontrei nenhuma evidência de rosqueamento.

Você não consegue encontrar nenhum encadeamento, não significa que não haja encadeamento

O .NET possui um 'pool de threads', que é um conjunto de threads 'sobressalentes' que ficam quase ociosos.Certos métodos fazem com que coisas sejam executadas em um dos threads do pool de threads para que não bloqueiem seu aplicativo principal.

Os exemplos flagrantes são coisas como ThreadPool.QueueUserWorkItem, mas há muitas outras coisas que também podem executar coisas no pool de threads que não parecem tão óbvias, como Delegado.BeginInvoke

Realmente, você precisa faça o que o kibbee sugere.

você tentou imprimir (Console.WriteLine()) a exceção dentro da cláusula catch e não usar o visual studio e executar seu aplicativo no console?

Acredito que Steve Steiner esteja correto.Ao pesquisar as sugestões de Steve, me deparei este tópico falando sobre a opção "Ativar Just My Code" em Ferramentas|Opções|Depurador|Geral.Sugere-se que o depurador irá quebrar em certas condições quando o código que não é do usuário lança ou trata uma exceção.Não sei exatamente por que isso importa ou por que o depurador diz especificamente que a exceção não foi tratada quando realmente foi.

Consegui eliminar as falsas quebras desativando a opção "Ativar Just My Code".Isso também altera a caixa de diálogo Debug|Exceptions, removendo a coluna "Manuseado pelo usuário", pois ela não se aplica mais.Ou você pode simplesmente desmarcar a caixa "Manuseado pelo usuário" para CLR e obter o mesmo resultado.

Muito obrigado pela ajuda de todos!

"Além disso, você pode colocar algum código para capturar todas as exceções não tratadas.Leia o link para obter mais informações, mas o básico são essas duas linhas ".

Isto é falso.Isso costumava capturar todas as exceções não tratadas no .NET 1.0/1.1, mas era um bug e não deveria e foi corrigido no .NET 2.0.

AppDomain.CurrentDomain.UnhandledException 

Destina-se apenas a ser usado como um salão de registro de última chance para que você possa registrar a exceção antes do encerramento do programa.Ele não capturará a exceção a partir da versão 2.0 (embora no .NET 2.0 haja pelo menos um valor de configuração que você pode modificar para fazê-lo agir como 1.1, mas não é uma prática recomendada usar isso).

É importante notar que há poucas exceções que você não pode catch, como StackOverflowException e OutOfMemoryException.Caso contrário, como outras pessoas sugeriram, pode ser uma exceção em um tópico em segundo plano em algum lugar.Além disso, tenho certeza de que você também não conseguirá capturar algumas/todas as exceções não gerenciadas/nativas.

Não entendi... seu bloco catch apenas lança uma nova exceção (com a mesma mensagem).O que significa que sua declaração de:

O problema é que, em alguns casos (não todos), meu bloco try/catch não o detecta e, em vez disso, interrompe a execução como uma exceção não tratada.

é exatamente o que é esperado acontecer.

Eu concordo com Daniel Auger e coroa que isso cheira a uma exceção que tem algo a ver com threads.Além disso, aqui estão minhas outras perguntas:

  1. O que diz a mensagem de erro completa?Que tipo de exceção é essa?
  2. Com base no rastreamento de pilha que você forneceu aqui, a exceção lançada pelo seu código não é TimeDefLexer.mTokens()?

Não tenho certeza se não estou claro, mas, em caso afirmativo, estou vendo o depurador interromper a execução com uma "Exceção não tratada" do tipo NoViableAltException.Inicialmente, eu não sabia nada sobre este item de menu Debug->Exceptions porque a MS espera que você, no momento da instalação do VS, se comprometa com um perfil quando você não tem ideia de como eles são diferentes.Aparentemente, Eu não estava no perfil de desenvolvimento C# e estava faltando essa opção.Depois de finalmente depurar todas as exceções CLR lançadas, infelizmente não consegui descobrir nenhum novo comportamento que levasse ao motivo desse problema de exceção não tratada.Todas as exceções lançadas eram esperadas e supostamente tratadas em um bloco try/catch.

Revisei a montagem externa e não há evidência de multithreading.Com isso, quero dizer que não existe nenhuma referência a System.Threading e nenhum delegado foi usado.Estou familiarizado com o fato de que constitui instanciar um thread.Eu verifico isso observando a caixa de ferramentas Threads no momento da exceção não tratada para ver que há apenas um thread em execução.

Tenho um problema em aberto com o pessoal da ANTLR, então talvez eles já tenham conseguido resolver esse problema antes.Consegui replicá-lo em um projeto simples de aplicativo de console usando .NET 2.0 e 3.5 no VS 2008 e VS 2005.

É apenas um problema porque força meu código a funcionar apenas com entradas válidas conhecidas do analisador.Usando um IsValid() seria arriscado se lançasse uma exceção não tratada com base na entrada do usuário.Manterei esta questão atualizada quando soubermos mais sobre esse assunto.

@spoulson,

Se você puder replicá-lo, poderá publicá-lo em algum lugar?Um caminho que você pode tentar é usar o WinDBG com as extensões SOS para executar o aplicativo e capturar a exceção não tratada.Ele será interrompido na primeira exceção (antes que o tempo de execução tente encontrar um manipulador) e você poderá ver nesse ponto de onde ele vem e de qual thread.

Se você nunca usou o WinDBG antes, pode ser um pouco cansativo, mas aqui está um bom tutorial:

http://blogs.msdn.com/johan/archive/2007/11/13/getting-started-with-windbg-part-i.aspx

Depois de iniciar o WinDBG, você pode alternar a quebra de exceções não tratadas acessando Debug->Filtros de Eventos.

Uau, dos relatórios até agora, 2 funcionaram corretamente e 1 teve o problema que relatei.Quais são as versões do Windows, Visual Studio usadas e .NET framework com números de compilação?

Estou executando XP SP2, VS 2008 Team Suite (9.0.30729.1 SP), C# 2008 (91899-270-92311015-60837) e .NET 3.5 SP1.

Se você estiver usando objetos com em seu projeto e tentar bloquear blocos para não capturar as exceções, será necessário desabilitar Ferramentas/Depuração/Quebra quando as exceções cruzarem a opção AppDomain ou limites gerenciados/nativos (somente gerenciado).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top