BCB + AfterConnect + AV

Discussion of open issues, suggestions and bugs regarding MyDAC (Data Access Components for MySQL) for Delphi, C++Builder, Lazarus (and FPC)
Antaeus
Posts: 2098
Joined: Tue 14 Feb 2006 10:14

Post by Antaeus » Wed 12 Jul 2006 09:03

In last test application we can reproduce access violation, but sequence of log messages looks correct. The reason of access violation is that you are trying to use slLog object (on MyConnection1BeforeConnect event) before it is created (on DataModuleCreate event). MyConnection1BeforeConnect event arises before DataModuleCreate event because you have MyConnection component connected in design-time. You should change behaviour of your program or disconnect in design-time.
But

> onConnect events only before Connect() method, after dont
AfterConnect event is raised only after connection was successfully established.

> there is resource leak ...
It looks like the problem discussed in this thread.

bedla.czech
Posts: 23
Joined: Wed 10 Aug 2005 09:10

Post by bedla.czech » Wed 12 Jul 2006 10:16

Antaeus wrote:In last test application we can reproduce access violation, but sequence of log messages looks correct. The reason of access violation is that you are trying to use slLog object (on MyConnection1BeforeConnect event) before it is created (on DataModuleCreate event). MyConnection1BeforeConnect event arises before DataModuleCreate event because you have MyConnection component connected in design-time. You should change behaviour of your program or disconnect in design-time.
But

> onConnect events only before Connect() method, after dont
AfterConnect event is raised only after connection was successfully established.

> there is resource leak ...
It looks like the problem discussed in this thread.
ok, i will correct sample application, but i still dont understand why is OnBeforeConnect event fired after setting MyConnection1->Server property?!

thanks

Antaeus
Posts: 2098
Joined: Tue 14 Feb 2006 10:14

Post by Antaeus » Wed 12 Jul 2006 13:50

We have checked source code of MyDAC. MyDAC doesn't try to connect after changing server name. But if connection is active and new server name differs from current one, MyConnection disconnects. So AfterDisconnect event arises, but not BeforeConnect.

bedla.czech
Posts: 23
Joined: Wed 10 Aug 2005 09:10

Post by bedla.czech » Thu 13 Jul 2006 07:11

Antaeus wrote:> there is resource leak ...
It looks like the problem discussed in this thread.
try/catch error has been removed :-) thanks ... and as i grasp there is not solution to handle exception in this cases?


so, try to look into next version of my sample application. significant is #define MYLOG 2, as you can see from debug2.txt i dont have activated connection from design time and after setting server name bad things happend :-( ... see debug2.txt

Code: Select all

http://tnpw.6v-webdesign.com/crlab02.zip
thanks for your response (actually all your responses :-) )

nice day Bedla

Antaeus
Posts: 2098
Joined: Tue 14 Feb 2006 10:14

Post by Antaeus » Thu 13 Jul 2006 11:24

> as i grasp there is not solution to handle exception in this cases?
As pointed in this topic, to avoid memory leak you should change
catch (...)
to
catch (Exception &E)
Even if you don't need E variable.

> try to look into next version of my sample ...
We couldn't reproduce the problem. Please supply us with exact version of MyDAC you use. If you are user of MyDAC Professional version please check if there are no changes in source code made by your own. If you want we will send you program built from your source code and log files made by your program.
Last edited by Antaeus on Thu 13 Jul 2006 11:32, edited 1 time in total.

bedla.czech
Posts: 23
Joined: Wed 10 Aug 2005 09:10

Post by bedla.czech » Thu 13 Jul 2006 11:31

Antaeus wrote:> as i grasp there is not solution to handle exception in this cases?
As pointed in this topic, to avoid memory leak you shoul change
catch (...)
to
catch (Exception &E)
Even if you don't need E variable.

> try to look into next version of my sample ...
We couldn't reproduce the problem. Please supply us with exact version of MyDAC you use. If you are user of MyDAC Professional version please check if there are no changes in source code made by your own. If you want we will send you program built from your source code and log files made by your program.
ok, please send me (e-mail is in my profile) log files generated by my program on your side.
i am using MyDAC 4.30.1.15 Professional, i havent made any changes in a source code.

Antaeus
Posts: 2098
Joined: Tue 14 Feb 2006 10:14

Post by Antaeus » Thu 13 Jul 2006 11:43

We have sent you log files by e-mail.

bedla.czech
Posts: 23
Joined: Wed 10 Aug 2005 09:10

Post by bedla.czech » Thu 13 Jul 2006 12:24

Antaeus wrote:We have sent you log files by e-mail.
email arrived :-)

but i dont understand what are difference of "log files with correct settings.zip" and "log files with wrong settings.zip" ... but generally log files in both archives looks good. but i still cant understand why i have so different log files (... means sequeance of event, as you can see in my log files)?! especialy i have connection disconnected in design time but after setting server property, connection is trying to reastablish! is there some other diagnostic? i realy need to solve this problem, because i still using versing 4.00.1.3 in my commercial application, because this is only newest version with correct sequence of events. and as you can see, in my sample application, i do do nothing special.
i am a litle bit discomposed :-(

Antaeus
Posts: 2098
Joined: Tue 14 Feb 2006 10:14

Post by Antaeus » Thu 13 Jul 2006 12:46

Try to download the lastest version of MyDAC (4.30.1.16). You can do it for free using your current license. Please see your registration mail for details.

bedla.czech
Posts: 23
Joined: Wed 10 Aug 2005 09:10

Post by bedla.czech » Fri 14 Jul 2006 08:54

Antaeus wrote:Try to download the lastest version of MyDAC (4.30.1.16). You can do it for free using your current license. Please see your registration mail for details.
i have tried version 4.30.1.17 07.07.06 with the same effect :-( is there some way to debug your mydac vcl? please give me a hint :-)

Antaeus
Posts: 2098
Joined: Tue 14 Feb 2006 10:14

Post by Antaeus » Fri 14 Jul 2006 10:02

Please perform following steps:
- open your second sample application in IDE
- select option "Stop on Delphi Exceptions" (Language Exceptions tab of Debugger Options editor);
- set wrong server name in your code to raise exception when connecting after setting server name;
- run your application
- after exception is raised please show Call Stack window (CTRL+F3), copy all text from there and send it to us (evgeniyD*crlab*com)

bedla.czech
Posts: 23
Joined: Wed 10 Aug 2005 09:10

Post by bedla.czech » Fri 14 Jul 2006 12:04

Antaeus wrote:Please perform following steps:
- open your second sample application in IDE
- select option "Stop on Delphi Exceptions" (Language Exceptions tab of Debugger Options editor);
- set wrong server name in your code to raise exception when connecting after setting server name;
- run your application
- after exception is raised please show Call Stack window (CTRL+F3), copy all text from there and send it to us (evgeniyD*crlab*com)
i cannt understand how but in my sample application error doesnt occurs :-) but in my commercial application still occurs :-(
here is call stack of my commercial application:

Code: Select all

7C81EB33 C:\WINDOWS\system32\kernel32.dll
004F2111 ExceptionLog::_16860
00A3A834 System::NotifyNonDelphiException()
7C90378B ntdll.dll
7C90EAFA ntdll.dll
008FA4DE Dbaccess::TCustomDAConnection::PerformConnect
008FA483 Dbaccess::TCustomDAConnection::Connect
008D81C8 Myaccess::TMyCommand::Execute
008D038F Myaccess::TCustomMyConnection::ExecSQL
00410F0D TDMSystem::DataModuleCreate(this=:0267F120, Sender=:0267F120)
00A18492 Classes::TDataModule::DoCreate(Self=:0267F120)
00A18324 Classes::TDataModule::AfterConstruction(Self=:0267F120)
00AF1D23 __AfterConstruction()
00A8D64B Forms::TApplication::CreateForm(Self=:02407A50, InstanceClass=:00C27A04, Reference=:00C9C29C)
00402F0A WinMain( =:00400000,  =NULL,  =:00141F22,  =9)
00AED0A3 __startup
edit: i have it compleatly rebuilded of course (deleted my obj and tds files)

Antaeus
Posts: 2098
Joined: Tue 14 Feb 2006 10:14

Post by Antaeus » Fri 14 Jul 2006 12:37

This stack shows that you call ExecSQL method of a TCustomMyConnection object in DataModuleCreate procedure. Execution of ExecSQL, Open, etc. methods of MyDAC causes connecting to server.

bedla.czech
Posts: 23
Joined: Wed 10 Aug 2005 09:10

Post by bedla.czech » Fri 14 Jul 2006 12:46

Antaeus wrote:This stack shows that you call ExecSQL method of a TCustomMyConnection object in DataModuleCreate procedure. Execution of ExecSQL, Open, etc. methods of MyDAC causes connecting to server.
but i dont call it, maybe i am blind :-)

here are my involved functions:
edit: now i investigated that my work-around doesnt work :-(

Code: Select all

void __fastcall TDMSystem::DataModuleCreate(TObject *Sender)
{
 checkConnectionSQL(this);
 checkUpdateSQLConnection(this);

// isMyConnectionSystemDB = false; // this is my work-around - Connection->Server

 AppKettlerWindowClass.style = 0;
 AppKettlerWindowClass.lpfnWndProc = &DefWindowProc;
 AppKettlerWindowClass.cbClsExtra = 0;
 AppKettlerWindowClass.cbWndExtra = 0;
 AppKettlerWindowClass.hInstance = 0;
 AppKettlerWindowClass.hIcon = 0;
 AppKettlerWindowClass.hCursor = 0;
 AppKettlerWindowClass.hbrBackground = 0;
 AppKettlerWindowClass.lpszMenuName = NULL;
 AppKettlerWindowClass.lpszClassName = AppKettlerWindowName.c_str();

 if ( FindWindow(AppKettlerWindowClass.lpszClassName, NULL) == 0 )
 {
  RegisterClass(&AppKettlerWindowClass);
  AppKettlerHWND = CreateWindowEx(0, AppKettlerWindowClass.lpszClassName, AppKettlerWindowName.c_str(), 0, 0, 0, 0, 0, 0, 0, HInstance, NULL);
 }
 else
 {
  ShowMessage("Chyba! Program muže být spuštìn pouze jednou.");
  Application->Terminate();
  return ;
 } // end if

 TIniFile *ini = new TIniFile( ChangeFileExt( Application->ExeName, ".ini" ) );
 try
 {
  ServerPort = ini->ReadInteger( "Global", "sqlport", 3307 );
  ServerHost = ini->ReadString( "Global", "server", "128.0.0.1" );
  HttpPort = ini->ReadInteger( "Global", "httpport", 81 );
 }
 __finally
 {
  delete ini;
  ini = NULL;
 } // end try/finally

 SystemDBUsername = GetHTTPGetData(TYPE_SYSTEMDB_USER, "root1");
 SystemDBPassword = GetHTTPGetData(TYPE_SYSTEMDB_PASSWORD, "1");
 ServerSubnet = GetHTTPGetData(TYPE_SERVER_SUBNET, "192.168.1.%");

 SW_ftpServer = GetHTTPGetData(TYPE_SW_FTP_SERVER, "ftp://192.168.1.100:21");
 SW_ftpUser = GetHTTPGetData(TYPE_SW_FTP_USER, "bedla_swftpuser");
 SW_ftpPassword = GetHTTPGetData(TYPE_SW_FTP_PASSWORD, "bedla_swftppassword");
 SW_ftpUser_PriceList = GetHTTPGetData(TYPE_SW_FTP_USER_PL, "bedla_swftpuser_pl");
 SW_ftpPassword_PriceList = GetHTTPGetData(TYPE_SW_FTP_PASSWORD_PL, "bedla_swftppassword_pl");
 SW_httpScript = GetHTTPGetData(TYPE_SW_HTTP_SCRIPT, "http://192.168.1.100:80/sitewizard/publish.php");
 SW_httpScript_PriceList = GetHTTPGetData(TYPE_SW_HTTP_SCRIPT_PL, "http://192.168.1.100:80/sitewizard/publish_pricelist.php");

 MyConnectionSystemDB->Port = ServerPort;
// try // this is my work-around - Connection->Server
// { // this is my work-around - Connection->Server
  MyConnectionSystemDB->Server = ServerHost;
// }// this is my work-around - Connection->Server
// catch (const Exception &E) // this is my work-around - Connection->Server
// {// this is my work-around - Connection->Server
//  if ( MyConnectionSystemDB->Connected ) // this is my work-around - Connection->Server
//   MyConnectionSystemDB->Disconnect(); // this is my work-around - Connection->Server
// } // end try/catch // this is my work-around - Connection->Server
 
 MyConnectionSystemDB->Username = SystemDBUsername;
 MyConnectionSystemDB->Password = SystemDBPassword;
 MyConnectionSystemDB->Database = "kettler_systemdb";

 try
 {
  MyConnectionSystemDB->Connect();
//  isMyConnectionSystemDB = true;
 }
 catch (EMyError &myError)
 {
  ShowMessage("Chyba! Neporaøilo se pøipojit k SQL serveru.\n\n"+myError.Message);
  Application->Terminate();
 } // end try/catch

} // end function

Code: Select all

void __fastcall TDMSystem::checkConnectionSQL(TComponent *AComponent)
{
 AnsiString errorMsg;
 bool connectionAktivni = false;
 for (int i=0; iComponentCount; i++)
 {
  if ( AComponent->Components[i]->ClassNameIs("TMyConnection") )
  {
   TMyConnection *myconnection = dynamic_cast(AComponent->Components[i]);
   if ( myconnection && myconnection->Connected )
   {
    connectionAktivni = true;
    errorMsg += AComponent->Components[i]->Name + " ";
   } // end if
  } // end if
 } // end for

 if ( connectionAktivni )
 {
  ShowMessage("Chyba! " + errorMsg);
  Application->Terminate();
 } // end if
} // end function

Code: Select all

void __fastcall TDMSystem::checkUpdateSQLConnection(TComponent *AComponent)
{
 AnsiString errorMsg;
 bool nenastavenyUpdateObjekty = false;
 for (int i=0; iComponentCount; i++)
 {
  if ( AComponent->Components[i]->ClassNameIs("TMyQuery") )
  {
   AnsiString baseName = AComponent->Components[i]->Name.Delete(1,3);
   TComponent *updsqlComponent = AComponent->FindComponent("updsql"+baseName);
   TMyQuery *myquery = dynamic_cast(AComponent->Components[i]);
   if ( updsqlComponent && myquery && myquery->UpdateObject == NULL )
   {
    nenastavenyUpdateObjekty = true;
    errorMsg += AComponent->Components[i]->Name + " ";
   } // end if
  } // end if
 } // end for

 if ( nenastavenyUpdateObjekty )
 {
  ShowMessage("Chyba! " + errorMsg);
  Application->Terminate();
 } // end if
} // end function

Code: Select all

void __fastcall TDMSystem::MyConnectionSystemDBAfterConnect(
      TObject *Sender)
{
// if ( !isMyConnectionSystemDB )  // this is my work-around - Connection->Server
//  return ;

 mysqlCommand->SQL->Clear();
 mysqlCommand->SQL->Add("SET AUTOCOMMIT=1;");
 mysqlCommand->Execute(1);

 if ( !hasQueryData("SELECT 1 FROM kettler_update WHERE update_number = "+IntToStr(PROGRAM_NUMBER)) )
 {
  ShowMessage("Chyba! Nesouhlasí èísla verzí programù ("+IntToStr(PROGRAM_NUMBER)+"). Proveïte update programu.");
  Application->Terminate();
  return ;
 } // end function

} // end function

Antaeus
Posts: 2098
Joined: Tue 14 Feb 2006 10:14

Post by Antaeus » Mon 17 Jul 2006 08:41

Try to simplify your commercial application step by step, removing event handlers and units, changing variables to constants, removing code that doesn't use MyDAC. Finally only few lines of code must remain. This must help to localize the reason of the problem.

Post Reply