2016-05-31 11 views
9

Mam dwie różne funkcje wewnątrz dodatku, nad którym pracowałem w C#. Ostatnio (Wygląda na to, że) Solidworks zawodzi, kiedy dotrze do niektórych części tych dwóch funkcji (prawdopodobnie więcej, ale są to jedyne dwa, na które udało mi się dotąd natrafić). Podczas debugowania obie funkcje dają mi "naruszenie praw dostępu do pamięci". Błąd". Ten błąd występuje za każdym razem, gdy zamykam aktywny dokument i występuje w przybliżeniu w 95% przypadków.Solidworks, śledzenie błędu naruszenia dostępu do pamięci na Isldworks.CloseDoc

To prawie zawsze na tej samej części. Wydaje się być niezależny od czasu wykonywania lub liczby części, które zostały otwarte i zamknięte. Jeśli nie zamykam plików, nie wydaje mi się, aby błąd. Ale podczas pracy z dużym zespołem przedstawia on własne problemy. Dodanie 1-sekundowego czekania przed zamknięciem wydaje się zmniejszać częstotliwość błędu (jak w, mogę sporadycznie przedostać się przez cały zespół bez błędu)

Szybkie wyjaśnienie, na czym polega przede wszystkim funkcja, której się przede wszystkim martwię ; Działa z poziomu najwyższego złożenia, propagując właściwości niestandardowe z głównego zespołu i podzespołów do ich elementów podrzędnych. Dlatego ciągle otwieram i zamykam różne pliki montażowe i częściowe.

Poniższy kod został usunięty do prawie absolutnego minimum, które replikuje błąd. Błąd występuje w linii 59. Z tego, co dotychczas widziałem w sieci, wynika, że ​​trudno je wyśledzić. Każda pomoc jest bardzo doceniana.

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; 
    } 

Aktualizacja: Po obejrzeniu tego pytania; What's causing the memory access violation? Próbowałem mieszać z niektórymi globalnymi zmiennymi, których używam w moich funkcjach, bez efektu. Udało mi się jednak zawrzeć mój zasadniczy kod w innej strukturze logicznej, aby zapętlić części, które zdają się unikać tego problemu. Ale czuję, że jest to w najlepszym przypadku pomoc zespołowa i chciałbym móc uniknąć tego problemu w przyszłości.

+0

Nikt nie ma żadnych danych wejściowych na ten temat? – Nick

+1

Piszemy kod w C# - chyba że pracujesz z PInvokes, niebezpiecznymi blokami lub podobnymi, nie powinno być możliwe wywoływanie wyjątków dostępu do pamięci. Jedyną sensowną odpowiedzią jest to, że SolidWorks ma błąd, który powoduje jego awarię z powodu uzasadnionych danych wejściowych lub powoduje awarię, ponieważ nie zatwierdza nieuzasadnionych danych wejściowych. Czy przekazujesz null nigdzie? Czy próbujesz użyć obiektów po ich zamknięciu? Czy używasz jakichkolwiek operacji, które są asynchroniczne? Czy zapewniasz mu jakieś haki? – antiduh

+0

[OpenDoc] (http://help.solidworks.com/2012/English/api/sldworksapi/SolidWorks.Interop.sldworks~SolidWorks.Interop.sldworks.ISldWorks~OpenDoc.html) wydaje się być przestarzałe. Każdy powód, dla którego nie używasz nowszych metod? Dlaczego nie używasz wartości zwracanej z OpenDoc? – antiduh

Odpowiedz

4

Piszemy kod w C# - chyba że pracujesz z PInvokes, niebezpiecznymi blokami lub podobnymi, nie powinno być możliwe wywoływanie wyjątków dostępu do pamięci. Jedyną sensowną odpowiedzią jest to, że SolidWorks ma błąd, który powoduje jego awarię z powodu uzasadnionych danych wejściowych lub powoduje awarię, ponieważ nie zatwierdza nieuzasadnionych danych wejściowych.

Prawdziwą poprawką byłoby skontaktowanie się z SolidWorks w celu odtworzenia błędu i naprawienia go; poza tym możemy przeanalizować kod w poszukiwaniu interakcji, które są typowymi wyzwalaczami błędów i usterek. Na przykład mogą nie sprawdzać poprawnie wszystkich swoich danych wejściowych - możesz podawać nieprawidłowe wartości, które milcząco akceptują; nie pęka, aż znacznie później.

Jeśli przez pomyłkę podano wartość null i nie sprawdzano, może to spowodować naruszenie praw dostępu do pamięci, jeśli później spróbują pobrać wskaźnik od tej wartości. Jeśli korzystasz z zasobów po ich zamknięciu i nie sprawdzają poprawności takiego stanu, mogą użyć przestarzałego wskaźnika pod maską, powodując również naruszenie praw dostępu do pamięci.

W innych sytuacjach przyczyną problemu mogą być operacje asynchroniczne - jeśli rozpoczniesz operację asynchroniczną, a następnie zamkniesz zasób powiązany z tą operacją, gdy ta operacja będzie później postępować w tle, może to spowodować awarie.

Jest możliwe, że sposób, w jaki używasz uchwytów zwróconych do Ciebie, powoduje naruszenie praw dostępu do pamięci. Zauważyłem, że nie używasz wartości zwracanej z OpenDoc, a zamiast tego próbujesz uzyskać dostęp do dokumentów w inny sposób. Co stanie się, gdy wartość zwracana z OpenDoc zostanie zebrana?Być może SolidWorks nie jest poprawnie odliczany, a zatem gdy zwracana jest wartość GC, to uchwyt pod maską jest zamknięty i zerowany; jeszcze inne operacje nadal oczekują jej ważności, a tym samym powodują naruszenie praw dostępu do pamięci.

Możliwe jest również, że używasz przestarzałego API - jeśli tak, możesz ćwiczyć kod w SolidWorks, który ma większą szansę na bycie w błędzie, ponieważ nie jest już testowany ani konserwowany. Zauważyłem, że wywołujesz metodę OpenDoc, której dokumentacja jest uznawana za przestarzałą. Rozważ użycie zalecanych metod, takich jak OpenDoc6.

Poza naprawianiem prawdziwego problemu z interfejsem API, który jest zepsuty lub nieprawidłowo sprawdzany pod kątem uszkodzonych danych wejściowych, jedyną opcją jest zbadanie źródeł typowych problemów z interfejsem API.

+1

Jak już wspomniałem powyżej, jakie inne problemy mogą być przyczyną tego problemu, użycie wywołania OpenDoc6 prawdopodobnie rozwiązało problem po mojej stronie. Dziękuję Ci! – Nick

Powiązane problemy