Hi all,
I have a framework 4.0 C# application launched through DOORS v8.1 as COM Object. Sometimes, I don't know why, I got an error while executing my app: "unexpected internal error, suggest save, exit and restart".
It is a generic error, but it also refers to a code line:
-R-E- DXL: <addins\Lib\script.dxl:251> An unexpected error has occurred: doors.exe caused an EXCEPTION_ACCESS_VIOLATION in module doors.exe at 0023:006D3672
This line just calls a function inside our COM Object:
oleMethod(myCOMObject, "MyMethod", autoArgs)
It seems like it's something wrong there. I checked that myCOMObject is not null, and the autoArgs have the right arguments that MyMethod receives.
By the way, I'm building the autoArgs this way (no problem, right?)
OleAutoArgs autoArgs = null
autoArgs = create
clear(autoArgs)
put(autoArgs, arg1)
put(autoArgs, arg2)
oleMethod(myCOMObject, "MyMethod", autoArgs)
clear(autoArgs)
delete(autoArgs)
The really strange thing is that it's not the first time that exactly this oleMethod call is executed, because DOORS may launch the error the 2nd, 3rd, 4th, …, 20th I launch my application.
In addition, the COM Object is managed in the startupFiles folder, and triggered in triggers folder:
evalTop_ ("OleAutoObj myCOMObject = null")
DOORS also launches a "diagnostic log" displaying the amount of memory in use, I don't know if it's valuable so I attach it.
I'd be very glad if you could help me. Regards,
Borja.
SystemAdmin - Mon Sep 17 03:48:11 EDT 2012 |
|
Re: DXL Unexpected error llandale - Mon Sep 17 13:51:11 EDT 2012
Don't know about COM.
The Diagnostic memory dump is useless except to perhaps 4 people in the world; I'm not one of them. The DXL file-line error is indeed useful.
Exception violations are usually attempting to address invalid memory, which you can get with Skip/Array retrieval type mis-matches but more likely by using a non-null yet-invalid Handle (such as an Object handle after you close the Module).
My first reaction to this error is myCOMObject has been closed. My second reaction is that this has something to do wtih putting that variable in the Top context which is just begging for trouble; and in this case the context of the DXL appears to not get the right handle on the COM object. I wonder if myCOMObject is being defined in the top context multiple times which will cause trouble.
Sure seems to me that your code snippette below should be preceeded with:
-
myCOMObject = get a handle on the existing COM link to Framework. Don't know the syntax.
-Louie
|
|
Re: DXL Unexpected error SystemAdmin - Tue Sep 18 04:12:19 EDT 2012
Hi,
thanks for your response.
First of all, I do not use Skip/Array items, so I think it's not the problem.
In addition, I put an ACK instruction when the trigger is triggered and, as far as I know, the module (and myCOMObject) is not closed.
About the top context, I don't know how to detect if it's the problem. This ACK is displayed just when I open DOORS (before selecting a project):
evalTop_ ("OleAutoObj myCOMObject = null")
ack("COM object defined")
And then, I manage it in the DXL script (this ACK is displayed just one time, when I open the module):
void CreateOrGetCOM() {
if (null myCOMObject) {
myCOMObject = oleCreateAutoObject("App.Name")
ack("COM created")
}
}
Just a couple of comments. What do you mean in your last message? "get a handle on the existing COM link to Framework"
And finally, when the memory problem occurs, the DOORS module is still (graphically) open, so I can choose the "Tools/Edit DXL" option from the menu to debug, so I can follow some instructions to check if there's something open wrongly in memory. The execution flow is (not the exact syntax):
Create COM
Project project = current
Module module = current
Object object = current
--[actions with object]--
object = next
--[actions with object]--
--Etcetera--
Close COM
Project and module are just one-time declared. And the memory exception error is happening without changing module, should I close the objects or something similar after using them?
Thank you so much, any idea is worthy for me.
Regards,
Borja.
|
|
Re: DXL Unexpected error Mathias Mamsch - Tue Sep 18 08:57:22 EDT 2012 SystemAdmin - Tue Sep 18 04:12:19 EDT 2012
Hi,
thanks for your response.
First of all, I do not use Skip/Array items, so I think it's not the problem.
In addition, I put an ACK instruction when the trigger is triggered and, as far as I know, the module (and myCOMObject) is not closed.
About the top context, I don't know how to detect if it's the problem. This ACK is displayed just when I open DOORS (before selecting a project):
evalTop_ ("OleAutoObj myCOMObject = null")
ack("COM object defined")
And then, I manage it in the DXL script (this ACK is displayed just one time, when I open the module):
void CreateOrGetCOM() {
if (null myCOMObject) {
myCOMObject = oleCreateAutoObject("App.Name")
ack("COM created")
}
}
Just a couple of comments. What do you mean in your last message? "get a handle on the existing COM link to Framework"
And finally, when the memory problem occurs, the DOORS module is still (graphically) open, so I can choose the "Tools/Edit DXL" option from the menu to debug, so I can follow some instructions to check if there's something open wrongly in memory. The execution flow is (not the exact syntax):
Create COM
Project project = current
Module module = current
Object object = current
--[actions with object]--
object = next
--[actions with object]--
--Etcetera--
Close COM
Project and module are just one-time declared. And the memory exception error is happening without changing module, should I close the objects or something similar after using them?
Thank you so much, any idea is worthy for me.
Regards,
Borja.
Well it is impossible to say from remote - you add a lot of variables in the equation. I think the general idea of declaring your myCOMObject on the top level context is flawed. The only reason to do this would be to try accessing the same variable from different DXL scripts. This however does not work, unless you create the COM object on top level.
The reason is, that DXL will free all memory allocated in a DXL context for reallocation, after the DXL ends. So the next allocation in any DXL script might overwrite the DATA that your object uses. So if you do in DXL script a)
myCOMObject = oleCreateAutoObj "..."
.. do something with the object
and in another script b) you do:
oleMethod (myCOMObject ...)
Then in 9 of 10 cases, you might be lucky that DOORS did not overwrite the memory for your COM object yet and the call works, although its buggy. But normally when you create the COM object in script a) you cannot access that COM object outside of script a even if myCOMObject itself is a global variable. The data of the object will be freed and the COM object will be pointing to invalid memory yielding an Access Exception when trying to access it.
Therefore remove that global variable or create the object only once on top level. Maybe this helps, regards, Mathias
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
|
|
Re: DXL Unexpected error llandale - Tue Sep 18 11:24:25 EDT 2012 SystemAdmin - Tue Sep 18 04:12:19 EDT 2012
Hi,
thanks for your response.
First of all, I do not use Skip/Array items, so I think it's not the problem.
In addition, I put an ACK instruction when the trigger is triggered and, as far as I know, the module (and myCOMObject) is not closed.
About the top context, I don't know how to detect if it's the problem. This ACK is displayed just when I open DOORS (before selecting a project):
evalTop_ ("OleAutoObj myCOMObject = null")
ack("COM object defined")
And then, I manage it in the DXL script (this ACK is displayed just one time, when I open the module):
void CreateOrGetCOM() {
if (null myCOMObject) {
myCOMObject = oleCreateAutoObject("App.Name")
ack("COM created")
}
}
Just a couple of comments. What do you mean in your last message? "get a handle on the existing COM link to Framework"
And finally, when the memory problem occurs, the DOORS module is still (graphically) open, so I can choose the "Tools/Edit DXL" option from the menu to debug, so I can follow some instructions to check if there's something open wrongly in memory. The execution flow is (not the exact syntax):
Create COM
Project project = current
Module module = current
Object object = current
--[actions with object]--
object = next
--[actions with object]--
--Etcetera--
Close COM
Project and module are just one-time declared. And the memory exception error is happening without changing module, should I close the objects or something similar after using them?
Thank you so much, any idea is worthy for me.
Regards,
Borja.
I'm over my head here on COM stuff, and really on the top-context stuff. But until someone who knows that stuff well chimes in....
I don't think you want to "close" the COM (close Frameword application). Maybe that is your problem, the COM is closed but top-context myCOMObject is still non-null pointing to corrupted data space which will certainly cause the exception violation. If you DO close the COM, then surely you also need this:
... so your next code knows to create the handle again.
I think this is right:
-
oleGetAutoObject("app.name") // Get handle IF the application is running
-
oleCreateAutoObject("app.name") // Ignore any running such application; start a new instance
If so, it sure seems to me you should first attempt to "get" the existing application, and if that is null then "create" it (meaning: start Framework if it is not already running). It seems to me then you don't need the top-context variable; instead:
-
OleAutoObj myCOMObject
-
myCOMObject = oleGetAutoObject("app.name")
-
if (null myCOMObject) then myCOMObject = oleCreateAutoObject("app.name")
-
deal with myCOMObject
-
delete(myCOMObject) // de-allocate handle; does not close the application
I think that should be the structure of your DXL.
-Louie
When I say "think" I mean I believe it is likely.
|
|
Re: DXL Unexpected error SystemAdmin - Tue Sep 18 12:54:25 EDT 2012
Hi,
thank you both again for the early response!
The reason why I am using evalTop_ to keep the COM Object alive is that I need to keep some data in the COM although DXL script execution has finished.
For example, the user opens a module, selects an object and opens my application. He does some stuff, closes the app and the DXL execution finishes. Consequently the COM Object (defined inside this DXL script, instead of being in evalTop_) is null for the next execution, although I try to recover it with myCOMObject = oleGetAutoObject("app.name"). So when the user opens another object inside the same module, my data is loaded again, because of the oleCreateAutoObject instruction is launched every time my script finishes.
So that's why I decided to declare myCOMObject in the context, because I do not lose data when the script execution (related to an object) finishes. I do not use several scripts, like you commented before, just one.
Do you manage any other solution than using the context?
Kind regards,
Borja.
|
|
Re: DXL Unexpected error Mathias Mamsch - Tue Sep 18 14:44:24 EDT 2012 SystemAdmin - Tue Sep 18 12:54:25 EDT 2012
Hi,
thank you both again for the early response!
The reason why I am using evalTop_ to keep the COM Object alive is that I need to keep some data in the COM although DXL script execution has finished.
For example, the user opens a module, selects an object and opens my application. He does some stuff, closes the app and the DXL execution finishes. Consequently the COM Object (defined inside this DXL script, instead of being in evalTop_) is null for the next execution, although I try to recover it with myCOMObject = oleGetAutoObject("app.name"). So when the user opens another object inside the same module, my data is loaded again, because of the oleCreateAutoObject instruction is launched every time my script finishes.
So that's why I decided to declare myCOMObject in the context, because I do not lose data when the script execution (related to an object) finishes. I do not use several scripts, like you commented before, just one.
Do you manage any other solution than using the context?
Kind regards,
Borja.
Using evalTop_ will not keep your COM object alive. It will only make the variable that you stored your object in available globally. If you want that COM object to keep alive, then you must only use oleCreateAutoObject once from the top level context and access that variable from your other DXL scripts, but do NOT close the handle. Just invoke oleMethod, oleGet, olePut on it. In this case you do NOT call oleGetAutoObject or oleCreateAutoObject from anywhere else.
Imagine you do:
evalTop_ "OleAutoObj oleDoc = oleCreateAutoObject(\"Microsoft.XMLDOM\")"
Then you will have a global XML document, that you can access from any DXL script without the need of getting a handle to it.
You can for example set the XML in there:
OleAutoArgs args = create()
put (args, "<my><xml/></my>")
bool bResult = false
print oleMethod (oleDoc, "LoadXML", args, bResult)
print "Result = " bResult "\n"
And later retrieve it from another (run of the same or a different) script, without the need of restoring handles:
string s
print oleGet(oleDoc, "xml",s)
print "XML = " s "\n"
So the important thing to ensuring your COM object staying alive is that you create it on the top level and never recreate it afterwards. However there is another way, which depends on your COM server. You can implement your COM server in a way, that it will stay alive (if the COM server implements the DllCanUnloadNow to return false). Then you can create it in a way, that the functions return some shared data, that is, even though you create and destroy your COM objects, the server will keep the data and return it for the next object. I do not know how you implemented your COM server, therefore it is hard to tell. Also from your answer it is not clear how you are handling the COM calls. If you post relevant code from the DXL scripts and tell us a bit about the context it might be clearer. At the moment it still seems to me, that your COM object will become invalid and you try to access it.
Maybe this helps, Regards, Mathias
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
|
|
Re: DXL Unexpected error SystemAdmin - Tue Sep 18 21:32:46 EDT 2012 Mathias Mamsch - Tue Sep 18 14:44:24 EDT 2012
Using evalTop_ will not keep your COM object alive. It will only make the variable that you stored your object in available globally. If you want that COM object to keep alive, then you must only use oleCreateAutoObject once from the top level context and access that variable from your other DXL scripts, but do NOT close the handle. Just invoke oleMethod, oleGet, olePut on it. In this case you do NOT call oleGetAutoObject or oleCreateAutoObject from anywhere else.
Imagine you do:
evalTop_ "OleAutoObj oleDoc = oleCreateAutoObject(\"Microsoft.XMLDOM\")"
Then you will have a global XML document, that you can access from any DXL script without the need of getting a handle to it.
You can for example set the XML in there:
OleAutoArgs args = create()
put (args, "<my><xml/></my>")
bool bResult = false
print oleMethod (oleDoc, "LoadXML", args, bResult)
print "Result = " bResult "\n"
And later retrieve it from another (run of the same or a different) script, without the need of restoring handles:
string s
print oleGet(oleDoc, "xml",s)
print "XML = " s "\n"
So the important thing to ensuring your COM object staying alive is that you create it on the top level and never recreate it afterwards. However there is another way, which depends on your COM server. You can implement your COM server in a way, that it will stay alive (if the COM server implements the DllCanUnloadNow to return false). Then you can create it in a way, that the functions return some shared data, that is, even though you create and destroy your COM objects, the server will keep the data and return it for the next object. I do not know how you implemented your COM server, therefore it is hard to tell. Also from your answer it is not clear how you are handling the COM calls. If you post relevant code from the DXL scripts and tell us a bit about the context it might be clearer. At the moment it still seems to me, that your COM object will become invalid and you try to access it.
Maybe this helps, Regards, Mathias
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
Hi guys,
good news! Finally I understood how to use properly the top level, and use the "oleCreate" instruction just right there.
It seems to have been the problem, now I cannot reproduce again the memory_exception error.
Anyway I'll do a full test suite this week and I'll keep you updated if I got the same problem.
One more time, thank you for the perfect support.
Regards,
Borja.
|
|