PR# 13413 bad behavior when opening and closing EV_NOTIFY_DIALOG
Problem Report Summary
Submitter: darppp
Category: .NET
Priority: High
Date: 2007/09/20
Class: Bug
Severity: Critical
Number: 13413
Release: 6.0.6.9367
Confidential: No
Status: Closed
Responsible: ted_eiffel
Environment: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; WOW64; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; InfoPath.2; .NET CLR 1.1.4322)
Synopsis: bad behavior when opening and closing EV_NOTIFY_DIALOG
Description
I'm having various crashes with fairly simple code under Eiffel.NET. Bellow is the code that I use for testing. I press a button, open a EV_INFORMATION_DIALOG, close the dialog and then press the button again. After several iterations one of several things happen:
- The dialog doesn't draw completelly. A button may be missing or positioned at the wrong place
- GetLastError with code 1406 shows up
- Exception that indicates write into a protected memory and that memory may have been corrupted.
The EiffelStudio version is 6.0.6.9367. Interestingly enough when I try with EV_COLOR_DIALOG instead of EV_INFORMATION_DIALOG the problems go away. Julian mentioned that it uses different implementation. I tried also with an agent opening EV_TITLED_WINDOWs and after 6-7 windows opened I usually get GetLastError with 1406.
You can give me a call and shadow me if you have trouble reproducing the problem
Thanks,
Darin
925-253-3472
e: EV_TITLED_WINDOW
a: EV_APPLICATION
b: EV_BUTTON
d: EV_INFORMATION_DIALOG
make is
-- Creation procedure.
local
do
create a
create e
create b.make_with_text_and_action ("Do It", agent doit)
e.extend (b)
e.show
a.launch
end
doit is
--
local
do
create d
d.show_modal_to_window (e)
end
To Reproduce
use the code from the description
Problem Report Interactions
It should now be fixed with a slightly different fix (see rev#74532).
No, I don't get the precondition violation.
It is about the same problem. Are you getting the precondition violation in `eif_id_object' in?
I cannot reproduce with the code posted originally. However, I can still get something similar with either of the following `doit':
doit is
do
create d
d.show_relative_to_window (e)
end
and
doit is
local
ge: INTEGER
do
create d
d.show_relative_to_window (e)
{GC}.collect
end
To reproduce, keep clicking "Do It". Do not close dialogs.
Fix is included in rev#74504.
I think I found the problem. Can you replace `dispose' in WEL_WINDOW by the following:
dispose is
-- Free allocated memory.
local
l_null, l_data: POINTER
l_object_id: INTEGER
do
-- Free memory taken by `internal_data'.
l_data := internal_data
if l_data /= l_null then
l_object_id := {WEL_INTERNAL_DATA}.object_id (l_data)
check
l_object_id_valid: l_object_id > 0
end
eif_object_id_free (l_object_id)
-- To mark that area as been freed
{WEL_INTERNAL_DATA}.set_object_id (l_data, -1)
if item /= l_null then
-- The data is not usable anymore so we need to
-- remove it from GWLP_USERDATA otherwise bad things
-- might happen.
cwin_set_window_long (item, gwlp_userdata, l_null)
end
l_data.memory_free
internal_data := l_null
end
Precursor {WEL_ANY}
end
Could you confirm it works?
One thing I just noticed is that if I run your code outside a debugger (be it VisualStudio or EiffelStudio) the program does not crash. Can you confirm this too? If this is the case, then it is clearly a Microsoft bugs. Debugging it when it failed showed that most likely there is either a problem with global variable or with WeakReference. It is hard for me to tell which one since although reproducible, it is always happening to a different object.
Maybe I am wrong. I looked at the runtime again, object put into `object_id_stack' can be collected. Now I don't know why windows on Windows are kept in such case, they should be collected too. (This happens on Linux) Do you have any ideas?