Author Topic: AutoCAD 2020 and Random System.AccessViolationExceptions  (Read 7816 times)

0 Members and 1 Guest are viewing this topic.

lamarn

  • Swamp Rat
  • Posts: 636
Re: AutoCAD 2020 and Random System.AccessViolationExceptions
« Reply #15 on: April 03, 2020, 02:55:25 PM »
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


Design is something you should do with both hands. My 2d hand , my 3d hand ..

lCine7ic

  • Mosquito
  • Posts: 12
Re: AutoCAD 2020 and Random System.AccessViolationExceptions
« Reply #16 on: October 19, 2020, 04:33:58 PM »
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

  • Swamp Rat
  • Posts: 861
  • .net stuff
Re: AutoCAD 2020 and Random System.AccessViolationExceptions
« Reply #17 on: October 19, 2020, 06:21:45 PM »
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

  • Mosquito
  • Posts: 12
Re: AutoCAD 2020 and Random System.AccessViolationExceptions
« Reply #18 on: October 29, 2020, 11:36:41 AM »
Thank you for the suggestion.

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


Code - Visual Basic: [Select]
  1. Dim TargetDocument As Document = Application.DocumentManager.MDIActiveDocument
  2. Dim TargetDocumentDB As Database = TargetDocument.Database
  3. Using dockLock As DocumentLock = TargetDocument.LockDocument()
  4.      Using transOuterMost As Transaction = TargetDocumentDB.TransactionManager.StartTransaction()
  5.           ...
  6.          
  7.                 ' INSIDE BlockDef Class
  8.                '**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.
  9.                ' At this Point, the block has been imported into the TargetDocument.
  10.                'newBTR: BlockTableRecord of Block Recently Added to TargetDocument
  11.                'idBlockTableRecord: ObjectId of BlockTableRecord recently added to BlockTable of TargetDocument's Database
  12.                'AttIdsByTag: Dictionary with Non-Constant Attribute Reference Tag as key, AttributeDefinition ObjectId as value
  13.                'AttIdxByTag: Dictionary with Non-Constant Attribute Reference Tag as key, AttributeDefinition 0-based Index (not counting constant) as value
  14.                'DynamicPropertyIndexByName: Dictionary with DynamicBlockReferenceProperty PropertyName as Key (skipping "ORIGIN"), and 0-based Index as value)
  15.                Using oTrans As Transaction = idBlockTableRecord.Database.TransactionManager.StartTransaction()
  16.                     Dim eBRE As IEnumerator = newBTR.GetEnumerator
  17.                     Dim iIndex As Integer = 0
  18.                     Dim oEnt As Entity
  19.                     Dim oAD As AttributeDefinition
  20.                     While eBRE.MoveNext
  21.                         oEnt = DirectCast(oTrans.GetObject(eBRE.Current, OpenMode.ForRead), Entity)
  22.                         If TypeOf oEnt Is AttributeDefinition Then
  23.                             oAD = DirectCast(oEnt, AttributeDefinition)
  24.                             If Not oAD.Constant Then
  25.                                 doc.WriteLine("Adding NonConstant Attribute:{Tag:'" + oAD.Tag + "', Index:" + iIndex.ToString + ", ObjectId:" + HexIdVal(oAD.ObjectId) + "} to Dictionaries")
  26.                                 AttIdsByTag.Add(oAD.Tag, oAD.ObjectId)
  27.                                 AttIdxByTag.Add(oAD.Tag, iIndex )
  28.                                 iIndex += 1
  29.                             End If
  30.                         End If
  31.                     End While
  32.                     If newBTR.IsDynamicBlock Then
  33.                         iIndex = 0
  34.                         'Cause of Failures since AutoCAD 2020.  If This Section (lines 35 through 47) is Commented out, no issues.
  35.                        Using tempBR As New BlockReference(Point3d.Origin, idBlockTableRecord)
  36.                                 For Each cDBRP As DynamicBlockReferenceProperty In tempBR.DynamicBlockReferencePropertyCollection
  37.                                     iIndex += 1
  38.                                     If cDBRP.PropertyName.ToUpper = "ORIGIN" Then
  39.                                         Debug.WriteLine("Skipping Index " + iIndex.ToString + ", <ORIGIN>")   ' < Updated per n.yaun's post immediately below
  40.                                        Continue For
  41.                                     End If
  42.                                     DynamicPropertyIndexByName.Add(cDBRP.PropertyName.ToUpper, iIndex)   ' < Updated per n.yaun's post immediately below
  43.                                    doc.WriteLine("Adding DynamicBlockReferenceProperty:{PropertyName.ToUpper():'" + cDBRP.PropertyName.ToUpper + "', Index:" + iIndex.ToString + "} to Dictionaries")
  44.                                 Next
  45.                             tempBR.Dispose()
  46.                         End Using
  47.                         'End Cause of Failures.  
  48.                    End If
  49.                 End Using
  50.         ...
  51.         Try
  52.             transOuterMost.Commit()
  53.         Catch ex As System.Exception
  54.  
  55.         End Try
  56.     End Using
  57. End Using
  58.  
  59.  
  60.  

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
« Last Edit: October 30, 2020, 10:37:13 AM by lCine7ic »

n.yuan

  • Bull Frog
  • Posts: 348
Re: AutoCAD 2020 and Random System.AccessViolationExceptions
« Reply #19 on: October 30, 2020, 10:11:07 AM »
Code: [Select]
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


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:

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.


lCine7ic

  • Mosquito
  • Posts: 12
Re: AutoCAD 2020 and Random System.AccessViolationExceptions
« Reply #20 on: October 30, 2020, 10:33:49 AM »
Code: [Select]
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


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:

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.

n.yuan: You're absolutely correct about the indices all being 0 -- truth is, what I showed is not my actual code.  I tried to simplify my actual code and clearly failed to do a sanity check.  The "real" code actually does assign the correct index.  I'll update the other post to reflect the correction. 

The issue is not with the dictionary; in fact, the dictionary is only used when there is a block reference added to the drawing that is actually used, and the failure occurs even when there isn't one.

When it fails, the thread containing the failure shows the following callstack.
Acdbmgd.dll!<Module>.AcArray<AcDbDynBlockReferenceProperty,AcArrayObjectCopyReallocator<AcDbDynBlockReferenceProperty> >.setPhysicalLength(AcArray<AcDbDynBlockReferenceProperty,AcArrayObjectCopyReallocator<AcDbDynBlockReferenceProperty> >*, int) < Failure occurs here
Acdbmgd.dll!Autodesk.AutoCAD.DatabaseServices.DynamicBlockReferencePropertyCollection.DeleteUnmanagedObject()
Acdbmgd.dll!Autodesk.AutoCAD.DatabaseServices.BlockTableRecordEnumerator.DeleteUnmanagedObject()
Acdbmgd.dll!Autodesk.AutoCAD.Runtime.DisposableWrapper.~DisposableWrapper()

Again, this code has worked in previous versions of AutoCAD (AutoCAD 2013, 2016, 2018); it only started failing in AutoCAD 2020.
I'm wondering if the problem has to do changes in the native code that help implement the updated 'INSERT' and 'PURGE' commands.
« Last Edit: October 30, 2020, 10:37:46 AM by lCine7ic »

lCine7ic

  • Mosquito
  • Posts: 12
Re: AutoCAD 2020 and Random System.AccessViolationExceptions
« Reply #21 on: November 16, 2021, 12:07:36 PM »
Just an update.  I was able to reuse the code below still in 2020 -- the issue seemed to be with the 'Continue For'.  Not sure why it's causing problems but be warned.