Code Red > .NET

AutoCAD 2020 and Random System.AccessViolationExceptions

<< < (4/5) > >>

lamarn:
This was a message

"
BIM 360 Plugin Survey:

If you do not want to take the very short survey, and have access to BIM 360, here is the download location of the plugin.

AutoCAD File Locking Plugin for BIM 360"

A possibility to provide feedback is available. Please check


lCine7ic:
All,

I know this is an old topic, but I've recently had the opportunity to do a bit more digging and have some more leads.  If you have the time, please take a look and let me know if there is a solution.

I enabled the extended debugger features and noticed that the failure always occured in thread other than the 'MAIN' thread.  The methods being called are:
Acdbmgd.dll!Autodesk.AutoCAD.DatabaseServices.DynamicBlockReferencePropertyCollection.DeleteUnmanagedObject()
Acdbmgd.dll!<Module>.AcArray<AcDbDynBlockReferenceProperty,AcArrayObjectCopyReallocator<AcDbDynBlockReferenceProperty> >.setPhysicalLength(AcArray<AcDbDynBlockReferenceProperty,AcArrayObjectCopyReallocator<AcDbDynBlockReferenceProperty> >*, int)  - < crash occurs in this method;

This made me think it was a Dynamic Block Issue. 
I removed the vast majority of the dynamic blocks that were imported into the drawing at startup, leaving only 1.  CRASH.
I created a static version of the remaining Dynamic block and ran the plugin.  No CRASH.
I replaced the static version back with the Dynamic block and ran the plugin.  CRASH.
I swapped out this dynamic block with another dynamic block (still only importing 1).  CRASH.
Before running the addin, I inserted the Dynamic Block and so that it had 1 active (non-purged) Block Reference and ran the Addin.  NO CRASH
Before running the addin, I inserted the Dynamic Block and so that it had 1 active (non-purged) Block Reference.  I then deleted the Block Reference but did not purge.  I then ran the Addin.  CRASH.

If you have any ideas on how to resolve this, please let me know.

Best Regards,
Chris

nobody:
I don't know if it will help you but you could try the assembly binding log viewer tool

https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-1.1/e74a18c4(v=vs.71)?redirectedfrom=MSDN

lCine7ic:
Thank you for the suggestion.

I figured out where the problem lies, and a crude (not ideal) work around.



--- Code - Visual Basic: ---Dim TargetDocument As Document = Application.DocumentManager.MDIActiveDocumentDim TargetDocumentDB As Database = TargetDocument.DatabaseUsing dockLock As DocumentLock = TargetDocument.LockDocument()     Using transOuterMost As Transaction = TargetDocumentDB.TransactionManager.StartTransaction()          ...                           ' INSIDE BlockDef Class                '**The purpose of the BlockDef class is so that other classes that work with BlockReferences based on each block can do quick lookups against the relevant BlockDef's dictionaries to access/modify the AttributeReferences or DynamicBlockReferenceProperties w/o enumerating each time.                ' At this Point, the block has been imported into the TargetDocument.                'newBTR: BlockTableRecord of Block Recently Added to TargetDocument                'idBlockTableRecord: ObjectId of BlockTableRecord recently added to BlockTable of TargetDocument's Database                'AttIdsByTag: Dictionary with Non-Constant Attribute Reference Tag as key, AttributeDefinition ObjectId as value                'AttIdxByTag: Dictionary with Non-Constant Attribute Reference Tag as key, AttributeDefinition 0-based Index (not counting constant) as value                'DynamicPropertyIndexByName: Dictionary with DynamicBlockReferenceProperty PropertyName as Key (skipping "ORIGIN"), and 0-based Index as value)                Using oTrans As Transaction = idBlockTableRecord.Database.TransactionManager.StartTransaction()                    Dim eBRE As IEnumerator = newBTR.GetEnumerator                    Dim iIndex As Integer = 0                    Dim oEnt As Entity                    Dim oAD As AttributeDefinition                    While eBRE.MoveNext                        oEnt = DirectCast(oTrans.GetObject(eBRE.Current, OpenMode.ForRead), Entity)                        If TypeOf oEnt Is AttributeDefinition Then                            oAD = DirectCast(oEnt, AttributeDefinition)                            If Not oAD.Constant Then                                doc.WriteLine("Adding NonConstant Attribute:{Tag:'" + oAD.Tag + "', Index:" + iIndex.ToString + ", ObjectId:" + HexIdVal(oAD.ObjectId) + "} to Dictionaries")                                AttIdsByTag.Add(oAD.Tag, oAD.ObjectId)                                AttIdxByTag.Add(oAD.Tag, iIndex )                                iIndex += 1                            End If                        End If                    End While                    If newBTR.IsDynamicBlock Then                        iIndex = 0                        'Cause of Failures since AutoCAD 2020.  If This Section (lines 35 through 47) is Commented out, no issues.                        Using tempBR As New BlockReference(Point3d.Origin, idBlockTableRecord)                                For Each cDBRP As DynamicBlockReferenceProperty In tempBR.DynamicBlockReferencePropertyCollection                                    iIndex += 1                                    If cDBRP.PropertyName.ToUpper = "ORIGIN" Then                                        Debug.WriteLine("Skipping Index " + iIndex.ToString + ", <ORIGIN>")   ' < Updated per n.yaun's post immediately below                                        Continue For                                    End If                                    DynamicPropertyIndexByName.Add(cDBRP.PropertyName.ToUpper, iIndex)   ' < Updated per n.yaun's post immediately below                                    doc.WriteLine("Adding DynamicBlockReferenceProperty:{PropertyName.ToUpper():'" + cDBRP.PropertyName.ToUpper + "', Index:" + iIndex.ToString + "} to Dictionaries")                                Next                            tempBR.Dispose()                        End Using                        'End Cause of Failures.                      End If                End Using        ...        Try            transOuterMost.Commit()        Catch ex As System.Exception         End Try    End UsingEnd Using   
My crude workaround is to statically define the Indices of the Dynamic Block Reference Properties I need in the classes that uses them... I will regret this later I know  :straight:



MODIFICATION: Corrected simplified code insert based on n.yuan's post below

n.yuan:

--- Quote from: lCine7ic on October 29, 2020, 11:36:41 AM ---
--- Code: ---Thank you for the suggestion.

I figured out where the problem lies, and a crude (not ideal) work around.

...

                    If newBTR.IsDynamicBlock Then
                        iIndex = 0
                        ...
                                Dim iTemp As Integer = 0
                                For Each cDBRP As DynamicBlockReferenceProperty In tempBR.DynamicBlockReferencePropertyCollection
                                    iIndex += 1
                                    If cDBRP.PropertyName.ToUpper = "ORIGIN" Then
                                        Debug.WriteLine("Skipping Index " + iTemp.ToString + ", <ORIGIN>")
                                        Continue For
                                    End If
                                    DynamicPropertyIndexByName.Add(cDBRP.PropertyName.ToUpper, iTemp)
                                    doc.WriteLine("Adding DynamicBlockReferenceProperty:{PropertyName.ToUpper():'" + cDBRP.PropertyName.ToUpper + "', Index:" + iIndex.ToString + "} to Dictionaries")
                                Next
                        ...
 
                    End If


--- End code ---

My crude workaround is to statically define the Indices of the Dynamic Block Reference Properties I need in the classes that uses them... I will regret this later I know  :straight:

--- End quote ---

I assume DynamicPropertyIndexByName is a Dictionary<string, int>, where string key is dynamic property name, and int value is what you are to use later (looking up as you mentioned). However, I do not see why you need the Dictionary for looking up, because the value of every item in the dictionary is the same: 0, according to your code in the foreach(){...} loop, where you set iTemp=0 before the loop, and never change its value during the loop where it is added into the Dictionary. I am not sure if it is intentional, or it is code mistake (of forgetting to change/increment its value).

Could this be the reason of the crash? Imagine that if the dynamic blocks you worked on only have one dynamic property (or 2, but one of it is named "ORIGIN", thus does not count here), the dictionary would only have 1 item, therefore there would be no problem for later lookup. But if there are more dynamic property name collected in the dictionary but all have its value equal 0, then the later lookup might cause trouble (have no idea what the later process doing here), hence the crash. More often than not, even it appears as random crash, 99.9% would come from our own code mistake.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version