Hi. I have a very specific issue where our code fails only when compiled without "Enable Optimizations" checked in advanced compile options in vs 2012. However, the code works fine when the flag is unchecked. The code also works on other layers in other drawings. I'm looking for assistance to either find the issue with the layer in question, or figure out why autocad blows up when my code is in release mode.
Repro Steps:
download code
open in vs 2012
open project properties
open compile tab
click Advanced Compile Options
check enable optimizations
Save
Compile project
Open Autocad
netload copylayerreleasemode.dll
open enableoptimizationtest.dwg
run command LYAPTEST
observe error: FATAL ERROR unhandled access violation reading 0xbb0352a8 Exception at 8a87e7c9h
Additional Information:
Acad Version = 2012
When running sysinternals dbgview, i observe the following:
[5608] Error -
[5608] ReadProcessMemory failed while trying to read PebBaseAddress
[5608]
[5608] Error -
[5608] Failed to read the peb from the process
I've attached the code, the dwg, screenshot of the error message, and dump file from autocad.
Solved! Go to Solution.
Solved by Balaji_Ram. Go to Solution.
From your code:
For Each thisPair As IdPair In IDMap If thisPair.IsCloned Then Select Case thisPair.Value.ObjectClass.Name Case "AcDbDictionary", "AcDbBlockRepresentationData", "AcDbXrecord", "AcDbSpatialFilter" 'Do nothing here Case Else Dim myEnt As Entity = CType(myTrans.GetObject(thisPair.Value, OpenMode.ForWrite, False, True), Entity) myEnt.LayerId = DestID End Select End If Next
While I didn't try to repro your problem, based on the code above, I am guessing that there's a null
reference exception when the object is not an Entity, nor any of the types that your code erroneously
checks for explicitly. The Case test that compares the ObjectClass.Name to one of several known types
is a problem, because if the object is not one of those types, that does not mean it is an Entity.
I would get rid of the Select Case entirely and Just use TryCast() to try to cast the object to an Entity,
and if the result is null, skip it and go to the next object.
DiningPhilosopher,
Thanks for the suggestion. I changed the code that you called out to the following:
For Each thisPair As IdPair In IDMap If thisPair.IsCloned Then Dim myent As Entity myent = TryCast(myTrans.GetObject(thisPair.Value, OpenMode.ForWrite, False, True), Entity) If myent IsNot Nothing Then myent.LayerId = DestID End If End If Next
However, the issue still persists. If you have any further insights, please let me know.
Thanks,
Jon
Try use OpenMode.ForRead instead:
For Each thisPair As IdPair In IDMap If thisPair.IsCloned Then Dim myent As Entity myent = TryCast(myTrans.GetObject(thisPair.Value, OpenMode.ForRead, False, True), Entity) If myent IsNot Nothing Then myent.UpgradeOpen() myent.LayerId = DestID End If End If Next
Hallex,
Thanks for your reply. I tried making that modification and no luck. It still errors when built in release mode.
-Jon
Sorry, just saw a typo in the first section. it should read, "I have a very specific issue where our code fails only when compiled with "Enable Optimizations" checked in advanced compile options in vs 2012."
Hi Jon,
After testing the code in release mode in various AutoCAD versions, I find the crash only in AutoCAD 2012. Both AutoCAD 2013 and 2014 versions require the .Net framework 4.0 and the sample code worked ok in the release mode.
In AutoCAD 2012, if the "IDMap" is disposed, then it worked in Release mode too.
//... Other code
IDMap.Dispose()
End If
myTrans.Commit()
End Using
Sorry, I am not aware of the reason why the dispose would be necessary especially when the optimisations are enabled.
Please try this and see if it works at your end.
Regards,
Balaji
Can't find what you're looking for? Ask the community or share your knowledge.