3 votes

Quel outil de débogage (s'il en existe un) me permet d'identifier le thread qui détient un verrou sur un fichier ?

Je suis en train de déboguer un test qui lève périodiquement un IOException Il est possible de supprimer un fichier parce qu'il est utilisé par un autre processus. Je soupçonne que le processus est en fait mon harnais de test, et qu'un autre thread dans le processus n'a pas éliminé ses ressources de fichiers quand je m'y attendais.

Existe-t-il un outil qui me permette de déterminer quel est le fil qui retient la serrure gênante ? Si je peux identifier le thread, je peux alors inspecter sa pile d'appels et au moins essayer de déterminer pourquoi la ressource n'est pas encore éliminée. L'outil Outil de débogage SOS semble prometteur, mais je ne vois aucune fonction qui permettrait d'éliminer une bonne part d'incertitude dans mon enquête.

Une solution consiste à identifier l'ID de thread du système d'exploitation natif, qui peut ensuite être mappé à un ID de thread géré via SOS. Comment faire ?

5voto

CodingWithSpike Points 17720

Vous pouvez utiliser Process Explorer à partir des outils SysInternals. http://technet.microsoft.com/en-us/sysinternals/bb896653 Il suffit de l'ouvrir et de rechercher le nom de votre fichier. Il vous indiquera les processus qui sont verrouillés.


Editer :

Oh, je viens de relire et j'ai remarqué que vous aviez demandé le fil spécifique. Je ne sais pas si ProcessExplorer peut le faire. Je m'en excuse.


Editer 2 :

Une deuxième réponse, qui développe la réponse d'agent-j :

Si vous pouvez modifier le code et ajouter un try/catch autour pour obtenir l'exception IO, vous pouvez également enregistrer la trace de la pile, puisqu'il semble que c'est ce que vous voulez inspecter :

catch(IOException)
{
    LogMessage( string.Format(
        "Managed Thread Id: {0}",
        System.Threading.Thread.CurrentThread.ManagedThreadId) );

    LogMessage( string.Format(
        "Stack Trace: {0}",
        new System.Diagnostics.StackTrace(true).ToString()) );
}

Édition 3

En utilisant l'approche ci-dessus, vous pouvez également enregistrer les threads et les traces de pile pour tous les threads du processus, ce qui facilite la consultation d'un journal et permet de comprendre ce qui s'est passé post-mortem. Code mis à jour :

catch(IOException)
{
  foreach (var thread in System.Diagnostics.Process.GetCurrentProcess().Threads)
  {
    LogMessage(string.Format(
      "Managed Thread Id: {0}",
      thread.ManagedThreadId));

    LogMessage(string.Format(
      "Stack Trace: {0}",
      new System.Diagnostics.StackTrace(thread, true).ToString()));

  }
}

2voto

agent-j Points 14703

Si vous placez un point d'arrêt dans un try{delete();}catch(IOException) clause de rattrapage. Ne pouvez-vous pas alors regarder la pile d'appels de chaque thread ?

0voto

agent-j Points 14703

Les threads ne détiennent pas de verrous sur les fichiers (du moins pas en ce qui concerne le système d'exploitation). Prenons l'exemple suivant. Le thread t crée un fichier et le verrouille. Le thread principal écrit dans le flux et le ferme. Cela montre que ce n'est pas le thread qui possède le verrou. C'est le processus qui le possède.

     Stream stream = null;
     Thread t = new Thread(() => stream = File.OpenWrite (@"c:\temp\junk111.txt"));
     t.Start();
     Thread.Sleep(1000);
     Console.WriteLine(t.ThreadState);
     stream.WriteByte(89);
     stream.Close();
     File.OpenWrite (@"c:\temp\junk222.txt");

Impressions stopped Le thread qui a ouvert le fichier n'est donc plus en cours d'exécution, mais la poignée de fichier qu'il a créée est toujours ouverte.

Voici la partie pertinente du résultat de FxCop pour le fichier ci-dessus

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop>FxCopCmd.exe /file:c:\code\jeremy.sellars\test\Junk\bin\Debug\Junk.exe /console
Microsoft (R) FxCop Command-Line Tool, Version 10.0 (10.0.30319.1) X86
Copyright (C) Microsoft Corporation, All Rights Reserved.

...
[Location not stored in Pdb] : warning  : CA2210 : Microsoft.Design : Sign 'Junk.exe' with a strong name key.
C:\code\jeremy.sellars\TEST\Junk\Program.cs(50,1) : warning  : CA2000 : Microsoft.Reliability : In method 'Program.Main()', call System.IDisposable.Dispose on object 'File.OpenWrite("c:\\temp\\junk2.txt")' before all references to it are out of scope.
Done:00:00:06.1251568

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X