2016-05-31 5 views
9

J'ai deux fonctions différentes dans un addon sur lequel j'ai travaillé en C#. Récemment (Apparemment) SolidWorks s'est écrasé quand il a atteint certaines parties de ces deux fonctions (peut-être plus, mais ce sont les deux seules que j'ai trouvées jusqu'ici.) Sous débogage, les deux fonctions me donnent une "violation d'accès mémoire" Erreur". Cette erreur se produit, à chaque fois, sur la ligne où je ferme le document actif et se produit environ 95% du temps.Solidworks, recherche d'une erreur de violation d'accès à la mémoire sur Isldworks.CloseDoc

Il est presque toujours sur la même partie. Il semble être indépendant du temps d'exécution, ou du nombre de pièces qui ont été ouvertes et fermées. Si je ne ferme pas les fichiers, je ne semble pas avoir l'erreur. Mais lors de l'exécution d'un grand assemblage, cela présente ses propres problèmes. Ajout dans une attente de 1s avant la fermeture semble réduire la fréquence de l'erreur (Comme, je peux parfois passer à travers l'ensemble de l'ensemble sans erreur)

Une explication rapide de ce que la fonction que je suis principalement préoccupé est de faire ; Il fonctionne depuis le niveau supérieur d'un assemblage, propageant les propriétés personnalisées de l'assemblage principal et des sous-assemblages dans leurs enfants. Donc, je suis constamment en train d'ouvrir et de fermer différents fichiers d'assemblage et de pièces.

Le code ci-dessous a été réduit à peu près au strict minimum qui réplique l'erreur. L'erreur se produit à la ligne 59. De ce que j'ai vu en ligne jusqu'ici, il semble que ce soit difficile à traquer. Toute aide est grandement appréciée.

public void propagateProps(bool overwrite) 
    { 
     List<string> assemblies = new List<string>(); 
     string topAssem; 
     string compName = ""; 
     int i = 0; 
     int j = 0; 
     int errors = 0, warnings = 0; 
     int partType = 1; 
     swModel = iSwApp.ActiveDoc; 
     if (swModel == null) 
     { 
      MessageBox.Show("No assembly document open. Please open an assembly and try again.", "Avengers Assemble Error"); 
      return; 
     } 
     if (swModel.GetType() != 2) 
     { 
      MessageBox.Show("No assembly document open. Please open an assembly and try again.", "Avengers Assemble Error."); 
      return; 
     } 
     topAssem = swModel.GetPathName(); 
     assemblies.Add(swModel.GetPathName()); 
     swAssy = iSwApp.ActiveDoc; 
     while (i < assemblies.Count) 
     { 
      List<string> beenDone = new List<string>(); 
      iSwApp.OpenDoc(assemblies[i], 2); 
      swModel = iSwApp.ActivateDoc(assemblies[i]);     
      swAssy = iSwApp.ActiveDoc; 
      foreach (Component2 swComp in swAssy.GetComponents(true)) 
      { 
       partType = 1; 
       compName = swComp.GetPathName(); 
       if (compName.IndexOf(").SLD") > 0 || compName.IndexOf("REF") > 0) 
       { 
        continue; 
       } 
       if (Path.GetExtension(compName).ToUpper() == ".SLDASM") 
       { 
        partType = 2; 
        assemblies.Add(compName); 
       } 
       iSwApp.OpenDoc(compName, partType); 
       swModel = iSwApp.ActivateDoc(compName); 
       if (swModel == null) 
       { 
        continue; 
       } 


       #region things that might not be in 


      #endregion 


       boolstatus = swModel.Save3(5, errors, warnings); 
       System.Threading.Thread.Sleep(500); 
       iSwApp.CloseDoc(swModel.GetPathName()); 
      swPart = null; 
      swModel = null; 
      } 
      ++i; 
      System.Threading.Thread.Sleep(500); 
     } 


     return; 
    } 

Mise à jour: après avoir vu cette question; What's causing the memory access violation? J'ai essayé de jouer avec certaines variables globales que j'utilise dans mes fonctions sans aucun effet. J'ai cependant réussi à enrouler mon code essentiel dans une structure logique différente pour faire défiler des parties, ce qui semble éviter ce problème. Mais je pense que c'est un pansement au mieux et je voudrais être en mesure d'éviter ce problème à l'avenir.

+0

Personne n'a d'influence sur celui-ci? – Nick

+1

Vous écrivez du code en C# - à moins que vous ne travailliez avec PInvokes, des blocs dangereux ou similaires, il devrait être impossible de provoquer des exceptions d'accès à la mémoire. La seule réponse raisonnable est alors que SolidWorks a un bogue qui provoque un crash avec des entrées raisonnables, ou qui provoque un crash car il ne valide pas les entrées déraisonnables. Est-ce que vous le passez nulle part? Essayez-vous d'utiliser des objets après leur fermeture? Utilisez-vous des opérations asynchrones? Fournissez-vous des crochets? – antiduh

+0

[OpenDoc] (http://help.solidworks.com/2012/English/api/sldworksapi/SolidWorks.Interop.sldworks~SolidWorks.Interop.sldworks.ISldWorks~OpenDoc.html) semble être obsolète. Une raison pour laquelle vous n'utilisez pas les nouvelles méthodes? Pourquoi n'utilisez-vous pas la valeur de retour d'OpenDoc? – antiduh

Répondre

4

Vous écrivez du code en C# - à moins que vous ne travailliez avec PInvokes, des blocs dangereux ou similaires, il devrait être impossible de provoquer des exceptions d'accès à la mémoire. La seule réponse raisonnable est alors que SolidWorks a un bogue qui provoque un crash avec des entrées raisonnables, ou qui provoque un crash car il ne valide pas les entrées déraisonnables.

Le vrai problème serait de contacter SolidWorks pour qu'ils reproduisent le bogue et le corrigent; sauf cela, nous pourrions analyser votre code pour rechercher des interactions qui sont des déclencheurs communs de bugs et de failles. Par exemple, ils peuvent ne pas valider correctement toutes leurs entrées - vous pouvez fournir des valeurs non valides qu'ils acceptent silencieusement; il ne se casse que beaucoup plus tard.

Si vous transmettiez accidentellement une valeur null et qu'ils ne vérifiaient pas, cela pourrait entraîner des violations d'accès à la mémoire s'ils essayaient par la suite de prendre un pointeur à partir de cette valeur nulle. Si vous utilisiez des ressources après leur fermeture, et qu'ils ne validaient pas pour une telle condition, ils peuvent utiliser un pointeur éventé sous le capot, provoquant également une violation d'accès à la mémoire.

Dans d'autres situations, des opérations asynchrones peuvent être à l'origine du problème. Si vous démarrez une opération asynchrone puis fermez la ressource liée à cette opération, lorsque cette opération se déroule ultérieurement en arrière-plan, des erreurs peuvent se produire.

Il est possible que la façon dont vous utilisez les handles renvoyés provoque des violations de l'accès à la mémoire. J'ai remarqué que vous n'utilisez pas la valeur de retour de OpenDoc, et essayez plutôt d'accéder aux documents par d'autres moyens. Que se passe-t-il lorsque la valeur de retour de OpenDoc est récupérée?Peut-être que SolidWorks ne compte pas correctement les références, et donc lorsque la valeur de retour est GC'd, la poignée sous le capot est fermée et annulée; cependant, d'autres opérations s'attendent toujours à ce qu'elle soit valide et donc à des violations d'accès à la mémoire.

Il est également possible que vous utilisiez une API obsolète. Dans ce cas, vous pouvez exercer un code dans SolidWorks qui a plus de chances d'être bogué car il n'est plus testé ni maintenu. J'ai remarqué que vous appelez la méthode OpenDoc, que leur documentation répertorie comme obsolète. Envisagez d'utiliser les méthodes recommandées à la place, telles que OpenDoc6. En dehors de la réparation du vrai problème avec l'API soit en panne, soit en ne validant pas assez bien les entrées cassées, votre seule option est d'étudier ces sources de problèmes API communs.

+1

Comme je l'ai dit plus haut, quels autres problèmes peuvent en être la cause, en utilisant l'appel OpenDoc6 semble avoir résolu le problème de ma part. Je vous remercie! – Nick