Hi!
I have a strange crash problem on _some_ pc's, depending on installation. It happens when closing a pointer to a newly created AcDbTableRecord, although I'm quite sure the code is in principle correct. It happens on AutoCAD Map 3D 2012. I am currently checking if it happens on other versions, but any hints on how to approach this would be appreciated!
Here is the code:
AcDbLayerTable *pLayerTable = NULL;
if (acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pLayerTable,AcDb::kForWrite) != Acad::eOk)
return FALSE;
AcDbLayerTableRecord *ptblRec = new AcDbLayerTableRecord;
ptblRec->setName(layer); // layer is a valid layer string, already checked this layer doesn't exist
// Code for setting color, lineweight and linetype omitted
if (pLayerTable->add(ptblRec) == Acad::eOk)
{
ptblRec->close(); // Crashes here!
pLayerTable->close();
}
Thank you!
By "can't debug it", do you mean you don't know how, or the user won't allow you?
Eh, well, I'm afraid the answer might be the first
I can't install Visual Studio on this pc. And I don't know how I can find out anything useful without it?
What I _have_ found, is that it seems to crash anytime the program tries to store something into the database.
Thanks for trying to help!
Can you install the Visual Studio remote debug monitor? If not, there are ways to get a stack trace when software crashes by enabling Dr. Watson or other crash dump utilities.
I debugged on my own pc with AutoCAD Map 3D 2012 in normal mode. The result was a crash in:
{
AcDbObjectPointer<AcDbObject> obj(theObjId, AcDb::kForWrite);
if (obj.openStatus() == Acad::eOk)
{
struct resbuf *pHead= obj.xData(_T("OurAppName"));
if (pHead)
{
// Added some extra info at the end of the resbuf, quite sure there is no error there
Acad::ErrorStatus es = obj.upgradeOpen();
if (Acad::eOk==es || Acad::eWasOpenForWrite==es)
es = obj.setXData(pHead); // This does get called
acutRelRb(pHead); // Tried without this as well, no difference
}
}
obj.close(); // Crashes here! If omitted (as should be allowed when using AcDbObjectPointer) it crashes in the same place
}
The crash happens in dbobjptr.h:
template <classT_OBJECT> inlineAcad::ErrorStatus
AcDbObjectPointerBase <T_OBJECT>::closeInternal()
{
if (m_ptr == NULL)
returnAcad::eOk;
Acad::ErrorStatuses = Acad::eOk;
if (m_ptr->objectId().isNull()) {
// ...
}
else {
es = m_ptr->close(); // Crashes here
If anyone has a clue, I'll be thankful for any help!
What does "crashes here" mean? Is there an exception? If so, what is the exception? Are you determining the location from the stack trace, or some other means? If stack trace, are you looking at the stack trace at the exception, or somewhere else? Whose code is crashing?
--
Owen Wengerd
ManuSoft
During debugging, first things that happens (when I try to step into the obj.close() call:
Unhandled exception at 0x0000000140539d15 in acad.exe: 0xC0000005: Access violation reading location 0x0000000000000000.
When I then press "Break", the debugger shows the following stack trace:
acad.exe!0000000140539d15()
[Frames below may be incorrect and/or missing, no symbols loaded for acad.exe]
acdb18.dll!000007fee5f7e8ae()
acdb18.dll!000007fee5f926b1()
Aviation.arx!AcDbObjectPointerBase<AcDbObject>::closeInternal() Line 581 + 0xe bytes C++
Which doesn't tell me anything, really...
Thanks for keeping up!
Oh, yes, and with "Crashes here", I mean that's where the debugger shows with a green arrow where I am when I have pressed "Break"...
FYI, I have another thread dealing with the same problem from a different angle here: http://forums.autodesk.com/t5/Installation-Licensing/AutoCAD-Map-3D-2012-together-with-Citrix/m-p/33...
Describing this as an access violation in acad.exe and providing the stack trace provides much more useful information and improves your odds of getting help. Unfortunately, in this case I don't see any obvious reason for the exception.
The problem may be related to the context from which your code is being called. You could test by putting the same code in a command handler and calling it by entering the command at the command prompt. If it works there, then the crash is propbably due to calling code from an invalid context or during an unsettled application state.
--
Owen Wengerd
ManuSoft
I'm beginning to think context and document locking might be involved. This is an old application...
Look at this:
// We are in application context right now and I want to change some object
AcAxDocLock lockdoc;
if (lockdoc.lockStatus() == Acad::eOk)
{
// Should be OK to do it here
AcAxDocLock lockdoc;
if (lockdoc.lockStatus() == Acad::eOk)
{
// OK here, too, I assume
}
// But what about here? Is the document still properly locked for writing or not?
}
I couldn't find this specific question answered anywhere! Can you just throw around with AcAxDocLock everywhere you need to be sure the document is locked or might that get you into trouble?
Hm, after removing all calls to:
AcAxDocLock lockdoc;
if (lockdoc.lockStatus() == Acad::eOk
from the paths that lead to the crash, the crash has disappeared! I thought this was a safe function to call anytime, but maybe it's not. If so, that could explain a lot!