Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Usersession Randon Access Violation


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 16 - Last Post: Apr 11, 2017 1:22 PM Last Post By: Chad Hower
Paul Woodhams

Posts: 8
Registered: 4/12/07
Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 30, 2017 3:59 AM
I am fairly new to Intraweb however I seem to be having a problem with what seems like a random access violation.

I have an application which contains multiple forms.

Form 1 contains a list of tasks, the data is retrieved from a MySQL component within the Usersession unit.
Form 2 is used to create a new item on the task lists using a table component within the Usersession.

Here is a step-through of what happens.

Form 1 is opened, showing a list of tasks using component in the usersession called qrytasks.
Form 2 is triggered from a hyperlink which adds a record to a table component tbltasks within the usersession. When this form is released, Form 1 is re-shown after the list query 'qrytasks' has bee opened with the new data.

I am finding that the qrytasks component results in access violaton. It allows me to clear the query, add a new one, but it fails when I open the query to get the results.

This does not seem to happen at a specific time.
One time I can go to form 2 twice then the query on form 1 fails, the next time I can go through 3 times before it fails.
I have tried looking at the component using inspect/Modify in the debugger and cannot see any problems before the open command that causes the violation.

I have tried using a datamodule and creating an instance of this datamodule each time a new usersession is created. I have also tried putting the components directly onto the usersession.
I have also changed the database and query components from MysqlDAQ to Firedaq components. There was no difference.

I am using Delphi 10 Seattle with Intraweb 14.1.7, however I have also tried previous builds of Intraweb with no luck.

Can someone please assist?
Eitan Arbel

Posts: 508
Registered: 2/24/13
Re: Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 30, 2017 6:11 AM   in response to: Paul Woodhams in response to: Paul Woodhams
I am fairly new to Intraweb however I seem to be having a problem with what seems like a random access violation.
welcome to this great community :)

it looks to me like it's in the open\close of the forms.
how do you create\show and close\hide the forms?

unlike Desktop apps that pre-create all the forms - IW create only 1 form, and set it as the MainForm.
the rest of the forms are not created, and you need to create them in order to show them (i guess you know that, because you already showed the second...)
so let's say your Form1 is SetAsMainForm by default.
but, you don't have to release the MainForm in order to show another form.
so in a case you show Form2 - you will see Form2, but Form1 is already "under" Form2.
and when you want something in Form1 when you are in Form2, you can (or even better - should) Release Form2.
now, if you show Form2, do what ever, hide it (not releasing) - (now you see Form1) and now that you want Form2 again you try to RE-create it - you will end up with an exception because you didn't Release Form2 before, and now you want to create another form with the same name.

here is what i do when "moving" between forms :
in Form1 - when "calling" Form2 :
  TForm2.Create(WebApplication).Show;

note, that i DON'T release the form - it stays "under"

in Form2 - when "calling" Form1 :

  Release;

That would just show up Form1, and free Form2 from memory

I have tried using a datamodule and creating an instance of this datamodule each time a new usersession is created.
you don't need a (another\)DataModule, the UserSession is by itself a DataModule.

(sorry for my broken english...)
Paul Woodhams

Posts: 8
Registered: 4/12/07
Re: Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 31, 2017 2:01 AM   in response to: Eitan Arbel in response to: Eitan Arbel
Hello Eitan,

Many thanks for your feedback,
I can confirm that I am using TForm2.Create(WebApplication).Show to switch to form 2.

Form 2 is also switched back to form 1 using the release method.

I tried the hide instead of release, however it made no difference.

I have also used the usersession as the datamodule as you described, I only tried the method of using a separate datamodule in the hope it would help with the issue.

Many thanks for your help.

Your English is very clear and easier to read than a lot of English people, so please don't worry.

Regards

Paul.
Eitan Arbel

Posts: 508
Registered: 2/24/13
Re: Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 31, 2017 2:38 AM   in response to: Paul Woodhams in response to: Paul Woodhams
you know that we get an "Access Violation" when we try to access something that doesn't exists, right?
maybe you try to access something that wasn't created yet, and maybe you plan to create it "soon", but it still doesn't exist at that point.

can you see a specific point where it happens?
maybe set a break point (F5) and trace with F8 until it crashes ?
maybe we can help if we could see the code where it happens.
also, see if there are things you are trying to do in the OnCreate of Form2, that can't be accessed yet (OnCreate is very different then OnShow).

Your English is very clear and easier to read than a lot of English people, so please don't worry.
thanks, i wasn't sure if i helped or complicated things... :D
Paul Woodhams

Posts: 8
Registered: 4/12/07
Re: Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 31, 2017 8:03 AM   in response to: Eitan Arbel in response to: Eitan Arbel
Hi,

Yes I understand that access violations are caused by accessing something that doesn't exist.
I have attempted to step and trace where it happens. However when I look and the state of the query component I cant see any issues with it not being available.

Here is the section which fails the second or third time the web page returns to form 1.

What I have called form 1 for this message is called iwfrmTasks in the code.
The iwfrmTasts.OnShow event calls RefreshDisplay as shown below:

Is the open command on the usersession.sqlTasks that causes the access violation around line 29.

procedure TiwfrmTasks.RefreshDisplay;
var
ThisRow:integer;
LastUpdate:tdatetime;
begin
lblusermenu.Caption:='User Menu - ('+usersession.CurrentUser.Fullname+')';
cbOutstandingTasks.Checked:=Usersession.CookieDisplayOutstanding;
cbCompletedTasks.Checked:=Usersession.CookieDisplayCompleted;
// CookieDisplayAllTasks:boolean;
if Usersession.CookieDisplayAllTasks then
rgAllTasks.ItemIndex:=1
else
rgAllTasks.ItemIndex:=0;

// Display the outstanding items
if Usersession.CookieDisplayOutstanding then
begin
rgnOutstanding.Visible:=true;

with usersession.sqlTasks do
begin //with sqltasks
sql.Clear;
sql.Add('select * from task');
sql.Add('where TaskInLiveQue=1');
sql.Add('and Completed=0');
if not(usersession.CookieDisplayAllTasks) then
sql.Add('and RequestorID='+inttostr(usersession.CurrentUser.Userid));
usersession.sqlTasks.Database:=usersession.db1;
open; ---- Here is where the access violation is caused either the 2nd or third time around.
if recordcount>0 then
begin // recordcount >0
first;
GridOutstanding.TotalRows:=recordcount;
ThisRow:=0;
while not(eof) do
begin // while not eof
// task Number cell
GridOutstanding.Cells[0,ThisRow]:=fieldbyname('TaskID').AsString;
//Category
GridOutstanding.Cells[1,ThisRow]:=usersession.CategoryFromID(fieldbyname('CategoryID').AsInteger);
//Stage
GridOutstanding.Cells[2,ThisRow]:=usersession.StageFromID(fieldbyname('StageID').AsInteger);
//Company
GridOutstanding.Cells[3,ThisRow]:=usersession.CompanyFromID(fieldbyname('CompanyID').AsInteger);
//Title
GridOutstanding.Cells[4,ThisRow]:=fieldbyname('TaskTitle').AsString;
//Actionee
GridOutstanding.Cells[5,ThisRow]:=usersession.UsernameFromID(fieldbyname('Actionee').AsInteger);
//RaisedBy
GridOutstanding.Cells[6,ThisRow]:=usersession.UsernameFromID(fieldbyname('RequestorID').AsInteger);
//Priority
GridOutstanding.Cells[7,ThisRow]:=inttostr(fieldbyname('Priority').AsInteger);
//% Complete
GridOutstanding.Cells[8,ThisRow]:=inttostr(fieldbyname('PercentComplete').AsInteger);
//Date Raised
GridOutstanding.Cells[9,ThisRow]:=formatdatetime('dd/mm/yyyy',fieldbyname('RequestedDate').AsDateTime);
// Last Update
LastUpdate:=usersession.GetLastTaskUpdate(fieldbyname('TaskID').AsInteger,usersession.CurrentUser.SystemHistory);
if LastUpdate<>Null then
GridOutstanding.Cells[10,ThisRow]:=formatdatetime('dd/mm/yyyy',LastUpdate);
next;
inc(ThisRow);
end; // while not eof
end // recordcount >0
else
GridOutstanding.TotalRows:=0;
Close;
end; //with sqltasks

end // if region outstanding is visible
else
rgnOutstanding.Visible:=false;

// display the Completed Items
if Usersession.CookieDisplayCompleted then
begin
rgnCompleted.visible:=true;
with usersession.sqlTasks do
begin //with sqltasks
sql.Clear;
sql.Add('select * from task');
sql.Add('where Completed=1');
if not(usersession.CookieDisplayAllTasks) then
sql.Add('and RequestorID='+inttostr(usersession.CurrentUser.Userid));
open;
if recordcount>0 then
begin // recordcount >0
first;
GridCompleted.TotalRows:=recordcount;
ThisRow:=0;
while not(eof) do
begin // while not eof
// task Number cell
GridCompleted.Cells[0,ThisRow]:=fieldbyname('TaskID').AsString;
//Category
GridCompleted.Cells[1,ThisRow]:=usersession.CategoryFromID(fieldbyname('CategoryID').AsInteger);
//Stage
GridCompleted.Cells[2,ThisRow]:=usersession.StageFromID(fieldbyname('StageID').AsInteger);
//Company
GridCompleted.Cells[3,ThisRow]:=usersession.CompanyFromID(fieldbyname('CompanyID').AsInteger);
//Title
GridCompleted.Cells[4,ThisRow]:=fieldbyname('TaskTitle').AsString;
//Actionee
GridCompleted.Cells[5,ThisRow]:=usersession.UsernameFromID(fieldbyname('Actionee').AsInteger);
//RaisedBy
GridCompleted.Cells[6,ThisRow]:=usersession.UsernameFromID(fieldbyname('RequestorID').AsInteger);
//Priority
GridCompleted.Cells[7,ThisRow]:=inttostr(fieldbyname('Priority').AsInteger);
//Completed Date
GridCompleted.Cells[8,ThisRow]:=formatdatetime('dd/mm/yyyy',fieldbyname('CompletionDate').AsDateTime);
//Date Raised
GridCompleted.Cells[9,ThisRow]:=formatdatetime('dd/mm/yyyy',fieldbyname('RequestedDate').AsDateTime);
// Last Update
LastUpdate:=usersession.GetLastTaskUpdate(fieldbyname('TaskID').AsInteger,usersession.CurrentUser.SystemHistory);
if LastUpdate<>Null then
GridCompleted.Cells[10,ThisRow]:=formatdatetime('dd/mm/yyyy',LastUpdate);
next;
inc(ThisRow);
end; // while not eof
end // recordcount >0
else
GridCompleted.TotalRows:=0;
Close;
end; //with sqltasks
end
else
rgnCompleted.visible:=false;

// display the pre-live items
with usersession.sqlTasks do
begin //with sqltasks
sql.Clear;
sql.Add('select * from task');
sql.Add('where TaskInLiveQue=0');
sql.Add('and Completed=0');
if not(usersession.CookieDisplayAllTasks) then
sql.Add('and RequestorID='+inttostr(usersession.CurrentUser.Userid));
open;
if recordcount>0 then
begin // recordcount >0
first;
gridprelive.TotalRows:=recordcount;
ThisRow:=0;
while not(eof) do
begin // while not eof
// task Number cell
gridprelive.Cells[0,ThisRow]:=fieldbyname('TaskID').AsString;
//Category
gridprelive.Cells[1,ThisRow]:=usersession.CategoryFromID(fieldbyname('CategoryID').AsInteger);
//Stage
gridprelive.Cells[2,ThisRow]:=usersession.StageFromID(fieldbyname('StageID').AsInteger);
//Company
gridprelive.Cells[3,ThisRow]:=usersession.CompanyFromID(fieldbyname('CompanyID').AsInteger);
//Title
gridprelive.Cells[4,ThisRow]:=fieldbyname('TaskTitle').AsString;
//Actionee
gridprelive.Cells[5,ThisRow]:=usersession.UsernameFromID(fieldbyname('Actionee').AsInteger);
//RaisedBy
gridprelive.Cells[6,ThisRow]:=usersession.UsernameFromID(fieldbyname('RequestorID').AsInteger);
//Priority
gridprelive.Cells[7,ThisRow]:=inttostr(fieldbyname('Priority').AsInteger);
//% Complete
gridprelive.Cells[8,ThisRow]:=inttostr(fieldbyname('PercentComplete').AsInteger);
//Date Raised
gridprelive.Cells[9,ThisRow]:=formatdatetime('dd/mm/yyyy',fieldbyname('RequestedDate').AsDateTime);
// Last Update
LastUpdate:=usersession.GetLastTaskUpdate(fieldbyname('TaskID').AsInteger,usersession.CurrentUser.SystemHistory);
if LastUpdate<>Null then
gridprelive.Cells[10,ThisRow]:=formatdatetime('dd/mm/yyyy',LastUpdate);
next;
inc(ThisRow);
end; // while not eof
end // recordcount >0
else
gridprelive.TotalRows:=1;
Close;
end; //with sqltasks
rgnprelivetasks.Height:=gridprelive.Height;

end;

Eitan Arbel

Posts: 508
Registered: 2/24/13
Re: Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 31, 2017 8:19 AM   in response to: Paul Woodhams in response to: Paul Woodhams
see if closing the Query before you clear it will change.

for example with sqlTasks :
with usersession.sqlTasks do
begin //with sqltasks
  If Active Then Close;
  sql.Clear;
  sql.Add('select * from task');
  sql.Add('.....
  ...
  ...
  ...
  Open;
  ...
end;
Paul Woodhams

Posts: 8
Registered: 4/12/07
Re: Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 31, 2017 8:33 AM   in response to: Paul Woodhams in response to: Paul Woodhams
No change in doing that.

Close works fine. Open still fails.

This is starting to drive me nuts.
I think I'm going to start commenting out other sections of the program to see if I can find an alternative cause.
Eitan Arbel

Posts: 508
Registered: 2/24/13
Re: Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 31, 2017 8:51 AM   in response to: Paul Woodhams in response to: Paul Woodhams
not that it should matter, but why do you set usersession.sqlTasks.Database:=usersession.db1; in runtime and not set it in the FDQuery DataSet in design time?
is it possible that usersession.sqlTasks.Database is not fully "ok" with db1 ?
Paul Woodhams

Posts: 8
Registered: 4/12/07
Re: Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 31, 2017 9:14 AM   in response to: Eitan Arbel in response to: Eitan Arbel
Hi Eitan,

I'm afraid it didn't make any difference.
Zane Leo

Posts: 55
Registered: 12/29/09
Re: Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 31, 2017 8:58 AM   in response to: Paul Woodhams in response to: Paul Woodhams
Paul Woodhams wrote:
No change in doing that.

Close works fine. Open still fails.

This is starting to drive me nuts.
I think I'm going to start commenting out other sections of the program to see if I can find an alternative cause.

For debugging purposes wrap the following snippet around your Open and you can also put break points at each E.Message line and investigate the E.Message value:

    try
      Open;
    except
      on E: EADOError do
        WebApplication.ShowMessage('ADO ERROR: ' + E.Message);
      on E: EDatabaseError do
        WebApplication.ShowMessage('DB ERROR: ' + E.Message);
      on E: Exception do
        WebApplication.ShowMessage('GENERAL ERROR: ' + E.Message);
    end;


Hope it helps
Paul Woodhams

Posts: 8
Registered: 4/12/07
Re: Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 31, 2017 9:17 AM   in response to: Zane Leo in response to: Zane Leo
Hi Zane,

I have done as you suggested.
The General Error was triggered, however the message was empty.

I'm going to continue commenting out other sections of the program later tonight in the hope it may affect this section.
Eitan Arbel

Posts: 508
Registered: 2/24/13
Re: Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 31, 2017 9:27 AM   in response to: Paul Woodhams in response to: Paul Woodhams
just a thought :
i don't know how it works with MySQL, but is it possible that the engine is not working or properly installed?
Paul Woodhams

Posts: 8
Registered: 4/12/07
Re: Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 3, 2017 1:55 AM   in response to: Paul Woodhams in response to: Paul Woodhams
Well this has been an interesting weekend.

Looks like the access violation with the data components is a red herring.
I have been commenting out other areas of the program and it's completely pointing the issue in another area now.

My second form just before it closes, posts the data to the database and also sends out an email using Indy STMP components in the usersession.
These emails have been working and the data has been posting to the database correctly. However I have two routines within my email procedures that get the User Name and Machine Name that the web application is running on.
This I have done to re-direct emails when running in the development environment.

I have narrowed it down to these two routines. If I comment them out of the email section, then the later random access violation on data components stops happening.

How interesting!

Paul.
Eitan Arbel

Posts: 508
Registered: 2/24/13
Re: Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 3, 2017 3:44 AM   in response to: Paul Woodhams in response to: Paul Woodhams
My second form just before it closes...
is it in the OnDestroy?
do you have any data components on the form?
if so, maybe the form destroys the data components and after that it tries to access the db?

also, your procedure is called ".RefreshDisplay;" - is it possible you try to use it when the form is being destroyed, and you no longer have a connection to the data\db and\or also can't render the page anymore?
Paul Woodhams

Posts: 8
Registered: 4/12/07
Re: Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 11, 2017 7:09 AM   in response to: Paul Woodhams in response to: Paul Woodhams
Hi All,

Many thanks for your efforts in trying to resolve this what seemed to be a random Access Violation.

I have now sorted the issue.

The problem was happening as a result of running some code in an email routine before releasing form 2.

The code was old and returned the windows username from the host machine. This routine I has in place to stop email being sent to everyone while the system is being developed or debugged.

The routine which caused the issue had the following code:

function ReturnWindowsUser: string;
var
PC: PChar;
Car: cardinal;
begin
Car := 0;
PC := nil;
GetUserName(PC, Car);
if Car <> 0 then
begin
GetMem(PC, Car);
GetUserName(PC, Car);
Result := string(PC);
FreeMem(PC);
end else
Result := 'UNKNOWN';
end;


As to why calling this code would sometimes cause an access violation within database components further down the line I cannot answer, however I replaced the code with the following which has now totally removed the problem:

function ReturnWindowsUser: string;
var
nSize: DWord;
begin
nSize := 1024;
SetLength(Result, nSize);
if GetUserName(PChar(Result), nSize) then
SetLength(Result, nSize-1)
else
RaiseLastOSError;
end;

Eitan Arbel

Posts: 508
Registered: 2/24/13
Re: Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 11, 2017 8:12 AM   in response to: Paul Woodhams in response to: Paul Woodhams
good for you, and thanks for sharing code.
and yet, it's really strange why it crashed only in the Open of the db...
Chad Hower

Posts: 613
Registered: 3/2/07
Re: Usersession Randon Access Violation  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 11, 2017 1:22 PM   in response to: Eitan Arbel in response to: Eitan Arbel
On 4/11/2017 11:12 AM, Eitan Arbel wrote:
good for you, and thanks for sharing code.
and yet, it's really strange why it crashed only in the Open of the db...

Most likely memory corruption caused by the older code.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02