Solidworks, tracking down a Memory Access Violation Error on Isldworks.CloseDoc
Asked Answered
P

1

10

I have two different functions inside an addon I have been working on in C#. Recently (Apparently) Solidworks has been crashing when it gets to certain parts of these two functions (possibly more, but these are the only two I have found it occurring in so far.) Under debug, both functions give me a "Memory Access Violation Error". This error occurs, every time, on the line where I am closing the active document, and occurs approximately 95% of the time.

It is almost always on the same part. It seems to be independent of run time, or number of parts that have been opened and closed. If I dont close the files, I dont seem to get the error. But when running a large assembly, that presents its own issues. Adding in a 1s wait before closing seems to reduce the frequency of the error (As in, I can occasionally get through the entire assembly without the error)

A quick explanation of what the function I am primarily concerned about is doing; It works from the top level of an assembly down, propagating the custom properties from the main assembly, and sub-assemblies, into their children. So I am constantly opening and closing different assembly and part files.

The code below has been stripped down to pretty much the bare minimum that replicates the error. The error occurs on line 59. From what Ive seen online so far, it it seems like these are hard to track down. Any help is greatly appreciated.

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

Update: After seeing this question; What's causing the memory access violation? I tried messing with some global variables I use in my functions to no effect. I have however managed to wrap my essential code in a different logical structure for looping through parts which seems to be avoiding this issue. But I feel thats a band-aid at best and would like to be able to avoid this problem in the future.

Personification answered 31/5, 2016 at 12:33 Comment(13)
No one has any input on this one?Personification
You're writing code in C# - unless you're working with PInvokes, unsafe blocks or similar, it should be impossible for you to cause memory access exceptions. The only reasonable answer then is that SolidWorks has a bug that either causes it to crash given reasonable inputs, or causes it to crash because it is not validating unreasonable inputs. Are you passing it null anywhere? Are you attempting to use objects after they're closed? Are you using any operations that are asynchronous? Are you providing it any hooks?Podium
OpenDoc seems to be deprecated. Any reason why you're not using the newer methods? Why don't you use the return value from OpenDoc?Podium
@antiduh, What is an asynchronous operation? And what do you mean by providing it hooks? OpenDoc could well be the problem! I am using it, as opposed to OpenDoc6, in both methods which are having issues. Ill need to test this!Personification
Asynch operation - an operation that typically returns immediately but starts some background task that will finish at some unknown time in the future. Dotnet has API examples of this - FileStream.BeginWrite, or in the case of explicit language support in C# - FileStream.AsyncWrite. Synchronous version would be FileStream.Write(). Note that an asynchronous operation could take the form of an IO operation (file write), a computation (hypothetical PiCalculator.BeginCalc( digits = 30000 ) ), or some simple statechange - myForm.BeginInvoke( (Action) delegate() { button.Text = "Sending.."; } )Podium
Hook - do you have any executable code of your creation that is called by SW? In C#, events are great examples of this - but they could take other forms. Win32 API has plenty of nasty examples of this, such as completion callbacks when some operation (file write) completes.Podium
Hacky workaround suggestion. use a try catch around the close document and don't close on that exception. Then at the end, use the CloseAllDocuments() method.Runnymede
Ok, I shouldnt have any Asynch operations. I do have a few event handlers for random things (such as on rebuild, file load etc) but I tested removing those initially.Personification
@andrewK, I have tried try catch statements and they had no effectPersonification
I would second @Podium that it is a SOLIDWORKS bug. Contact your VAR and provide the code with the files erroring and you may get some help from SOLIDWORKS directly.Runnymede
@Runnymede - perhaps, it would be worth a shot.. but it might be a bad idea (or not even possible). If he's getting that exception, then memory corruption has occurred and it may be impossible to continue execution.Podium
@Podium Yes this error is completely crashing out my Solidworks Session, I can get no data from it, even running in debug mode. I am beginning to believe it is a problem with the Solidworks install, or some similar factor, on my particular system. Ive been running a semi-automated test (Basically, I have a 0-40 FOR loop continually calling this method) on a different system, and with the old code, it didnt crash until the 22nd loop. Which honestly, was likely more to do with Solidworks derping out than my program. Doing more testing, but thats what it is looking like now.Personification
Update: Just came in after the weekend, my test ran for about 68 hours straight, it was on its 91 iteration. @antiduh, if you phrase the OpenDoc6 as an answer I will accept it, I believe that is the crux of my issue!Personification
P
5

You're writing code in C# - unless you're working with PInvokes, unsafe blocks or similar, it should be impossible for you to cause memory access exceptions. The only reasonable answer then is that SolidWorks has a bug that either causes it to crash given reasonable inputs, or causes it to crash because it is not validating unreasonable inputs.

The real fix would be to contact SolidWorks to have them reproduce the bug and fix it; barring that, we could analyze your code to look for interactions that are common triggers of bugs and faults. For instance, they may not be validating all of their input correctly - you could be providing invalid values that they're silently accepting; it doesn't break until much later.

If you were accidentally passing null and they weren't checking, that could cause memory access violations if they later try to take a pointer from that null. If you were using resources after they were closed, and they weren't validating for such a condition, they may use a stale pointer under the hood, also causing a memory access violation.

In other situations, asynchronous operations may be causing the fault - if you start some async operation and then close the resource tied to that operation, when that operation later progresses in the background, it could cause faults.

It's possible that the way you're using handles returned to you is causing memory access violations. I noticed that you don't use the return value from OpenDoc, and instead attempt to access documents by other means. What happens when the return value from OpenDoc gets garbage collected? Maybe SolidWorks isn't properly reference counting, and thus when the return value is GC'd, the handle under the hood is closed and nulled; yet other operations still expect it to be valid, and thus cause memory access violations.

It's also possible that you're using deprecated API - if so, you may be exercising code in SolidWorks that has a higher chance of being buggy because its no longer being tested or maintained. I noticed that you're invoking the OpenDoc method, which their documentation lists as deprecated. Consider using the recommended methods instead, such as OpenDoc6.

Outside of fixing the real problem with the API either being broken, or not validating against broken inputs well enough, your only option is to investigate these sources of common API problems.

Podium answered 11/7, 2016 at 15:46 Comment(1)
As I said above, what other issues may actually be causing it, using the OpenDoc6 call seems to have fixed the problem on my end. Thank you!Personification

© 2022 - 2024 — McMap. All rights reserved.