Access violation errors
Hi,
we have been doing some fixes to the reportbuilder source (server version
7.02) to remove some AV errors.
Changes marked with ***:
ppComm.pas
procedure TppCommunicator.SendNotify(aCommunicator: TppCommunicator;
aOperation: TppOperationType);
var
liIndex: Integer;
lCommunicator: TppCommunicator;
begin
if (FNotifyList = nil) then Exit;
{note: process loop last to first because object that are notifiy will
likely remove themselves from the list}
for liIndex := FNotifyList.Count - 1 downto 0 do
begin
lCommunicator := TppCommunicator(FNotifyList[liIndex]);
*** if( lCommunicator.FIsDestroying = false ) then
lCommunicator.Notify(aCommunicator, aOperation);
end;
end; {procedure, SendNotify}
ppViewr.pas
destructor TppViewer.Destroy;
begin
FWalkieTalkie.Free;
{free screen device}
***if( FProducer <> nil ) then
*** FProducer.RemoveEventNotify( FScreenDevice );
FScreenDevice.Free;
{free paintbox}
FPaintBox.Free;
{free parent scrollbox last}
FScrollBox.Free;
inherited Destroy;
end; {destructor, TppViewer}
Does anyone have any insight to the impact of these changes?
Does anyone have knowledge of similar problems, because we still have
occasional AV errors in our application.
sincerely
frode
we have been doing some fixes to the reportbuilder source (server version
7.02) to remove some AV errors.
Changes marked with ***:
ppComm.pas
procedure TppCommunicator.SendNotify(aCommunicator: TppCommunicator;
aOperation: TppOperationType);
var
liIndex: Integer;
lCommunicator: TppCommunicator;
begin
if (FNotifyList = nil) then Exit;
{note: process loop last to first because object that are notifiy will
likely remove themselves from the list}
for liIndex := FNotifyList.Count - 1 downto 0 do
begin
lCommunicator := TppCommunicator(FNotifyList[liIndex]);
*** if( lCommunicator.FIsDestroying = false ) then
lCommunicator.Notify(aCommunicator, aOperation);
end;
end; {procedure, SendNotify}
ppViewr.pas
destructor TppViewer.Destroy;
begin
FWalkieTalkie.Free;
{free screen device}
***if( FProducer <> nil ) then
*** FProducer.RemoveEventNotify( FScreenDevice );
FScreenDevice.Free;
{free paintbox}
FPaintBox.Free;
{free parent scrollbox last}
FScrollBox.Free;
inherited Destroy;
end; {destructor, TppViewer}
Does anyone have any insight to the impact of these changes?
Does anyone have knowledge of similar problems, because we still have
occasional AV errors in our application.
sincerely
frode
This discussion has been closed.
Comments
--
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Fundamentally you have to call notify when a communicator is being
destroyed. We will need to see your code or an example which raises the AV.
Are you able to reproduce the AV with our demos? Please send all
attachments to support@digital-metaphors.com. You should not need to change
the source in the communicator.
--
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
[missing standard demo request from d-m]
Sorry, but we don't have the resources to create a bug demo for you. Instead I will try to elaborate a bit on the problem:
The reason for the change in ppComm.pas was an AV fault in the following code: ppClass.pas, procedure TppCustomReport.Notify, line 3419
else if (FTemplate.DatabaseSettings.DataPipeline = aCommunicator) then
FTemplate.DatabaseSettings was destroyed, and thereby inaccessible, causing the AV.
Here is the callstack when the fault occured:
TppCustomReport.Notify($28A9D30,ppopRemove)
TppReport.Notify($28A9D30,ppopRemove)
TppCommunicator.SendNotify($28A9D30,ppopRemove)
TppCommunicator.Destroy
If you could check this out and inform us about the proper fix, we would be more than happy helping you improve your product. (We have 200+ customers sharpening their knifes because they have to restart our application after each report they view).
We are a bit uncertain if the fix in ppViewr.pas is due to the fix we did in ppComm.pas, our if it is a fault on your behalf. Anyway, the problem is that FProducer is trying to communciate with FScreenDevice after it have been destroyed.
Please have a developer evaulate this ASAP, as we are counting on your product.
sincerely
frode
I am a Digital-Metaphors engineer . I consulted other engineers on this
issue and received confirmation that the communicator must call Notify when
being destroyed. As this is not a known issue with ReportBuilder, the
quickest way for us to resolve your problem is to see an example of what you
are experiencing. Please send a small example demonstrating the error to
support@digital-metaphors.com and we will work as fast as possible to find a
solution for you.
--
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
Unconditionaly? I assume you checked the fix I proposed, to not Notify objects that are in the process of being destroyed? Notifying an object that is beeing destroyed might be OK, but when the receiver is starting to use its objects without checking if they have been destroyed your are looking for trouble.
Eg. TppCustomReport.Destroy contain the following code at the end:
FTemplate.Free;
inherited Destroy;
This ends up in TppCustomReport.Notify which checks on
FTemplate.DatabaseSettings.DataPipeline
What other information do you expect to find with such an example besides what I already have provided you with?
When debugging, the only information you get is a callstack and an offending instruction. Please do a review of your code with the information provided, or be more spesific about what you are looking for.
frode
I'm very sorry if I was unclear in my last message. What I would like to
see is a running example of the original code you used when you began
receiving these AV errors (using the origonal RB Source). This way I will
be able to recreate these errors and find a solution for you without having
to change the ReportBuilder Source.
--
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
OK, here is what you do: Create any example that uses a TppCustomReport object, watch how the Destroy function is performing - that you through several calls to inherited Destroy ends up in TppCustomReport.Notify - TppCustomReport.Notify is accessing the FTemplate object which was freed just before you called the first inherited Destroy. Everyone should understand that this causes an AV.
When you have confirmed and understood the problem, please review other classes for the same kind of problem. (This is a design flaw in your notify mechanism, although some might insist that this is a design flaw in the Delphi dtor mechanism).
??? How do you expect to find a solution without using the TppCustomReport class?
frode
TppCustomReport exists as a common ancestor which should not be instantiated
by itself. Create a TppReport, not a TppCustomReport. Is there a reason
you can't use a TppReport?
--
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
Nico,
Where do you get the idea that I am instantiating a TppCustomReport from?
Have you looked at your source code as I suggested?
While you have been dodging this AV fault in your product we have been debugging and investigating your product further and come up with the following bug fixes that completely fixes our problems (for the time being).
The fix'es are for reportbuilder 7.02:
ppClass.pas line 2397 TppCustomReport.Destroy
insert the line FTemplate := nil after FTemplate has been freed
ppClass.pas line 3419 TppCustomReport.Notify
change the if test to else if ( (FTemplate <> nil) and (FTemplate.DatabaseSettings <> nil)
and (FTemplate.DatabaseSettings.DataPipeline = aCommunicator)) then
ppTmplat.pas line 599 TppCustomTemplate.Destroy
insert the line
FDatabaseSettings := nil
after fDatabaseSettings has been freed
ppViewr.pas line 374 TppViewer.Destroy
insert the following lines
if( FProducer <> nil ) then
FProducer.RemoveEventNotify( FScreenDevice );
before FScreenDevice is freed (this fix might not be necessary, but better safe than sorry)
For thoose that have followed this thread I would like to inform that we have removed the proposed fix to ppComm.pas because it seems like it not just fixed the original problem, but also introduced new ones. And d-m haven't found the time to comment on their design decision to communicate with objects that are in the process of being destroyed.
I see no need for further contact with d-m before you have done some real work on this matter on your side.
Thank you.
Frode Nilsen
System architect
Auticon AS
NORWAY
Please provide us with a simple example Delphi project which shows the AVs.
We have run thousands and thousands of reports in our QA tests and have
never encountered this error. We need to recreate your destroy sequence on
our machines. The only way to do this is for you to send us a simple
example. Describing the problem does not give us sufficient information to
recreate the issue.
--
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com