Access Violation in TOracleQuery

Lars Hammer

Member²
I made a combobox component, that uses a TOracleQuery to get its data from the database.

When the query is performed I get an access violation (write of some address). The access violation arrives, when I call FQuery->Field(). The other functions are working correctly. See the code sample below.

Is there any explanation on why this happens?

FQuery->Execute();

while (!FQuery->Eof)
{
try
{
int FieldNum = FQuery->FieldIndex(FDisplayField);
int FieldCount = FQuery->FieldCount();
int FieldSize = FQuery->FieldSize(FieldNum);
// The following gives an access violation.
Variant V = FQuery->Field(FieldNum);
AnsiString DispFld = V;
FQuery->Next();
}
 
I see no obvious clues. What is the value of FieldNum when this AV occurs?

------------------
Marco Kalter
Allround Automations
 
Sorry, it is obviously not easy to see what is going on in the code:

int FieldNum = FQuery->FieldIndex(FDisplayField); // Value of FieldNum is 1
int FieldCount = FQuery->FieldCount(); // Value of FieldCount is 2
int FieldSize = FQuery->FieldSize(FieldNum); // Value of field size is 30 - it is really a VARCHAR2(30)
// The following gives an access violation.
// We have tried different return values, but they all give an AV.
Variant V = FQuery->Field(FieldNum);
AnsiString DispFld = V;

Yours
Lars Hammer
 
It's very strange. I would normally think that the FQuery instance is already freed, but that doesn't make sense because everything else works. What does FQuery->FieldByName(FDisplayField) do?

------------------
Marco Kalter
Allround Automations
 
I guess you mean calling the overloaded FQuery->Field(FDisplayField). It makes an AV the same way as FQuery->Field(FieldIndex) does. Actually this was the function that I called in the first place. But when I got the AV, I tried calling the other functions, to debug into the problem.

Yours
Lars Hammer
 
Yes, sorry, that's what I meant.

Can you send me a small demo project that reproduces this error?

------------------
Marco Kalter
Allround Automations
 
I just made a simple project using this component, and in this simple project nothing fails.

The AV is:

Access violation at address 77f6750B in module 'ntdll.dll'. Read of address 00000018

Does this make any sense?
 
I tried to debug the application using Turbopower's Sleuth QA Suite 3 - codewatch. Codewatch states that there is a GetProcAddress that fails, namely, when it tries to get the address of OCIEnvCreate.

Time Thread ID Event
0.12:407 E9h API Failure:GetProcAddress : Error:The specified procedure could not be found
0.12:407 E9h hModule:10000000h
0.12:408 E9h lpProcName:OCIEnvCreate

And this is the calling sequence:

Order Address Location
0 48CB29h P07.exe (OracleCI::_16431 + 02Dh)
1 48DA9Bh P07.exe (Oracleci:
biggrin.gif
LLInit() + 0ED7h)
2 48E990h P07.exe (Oracleci::InitOCI() + 03Ch)
3 48BE21h P07.exe (Oracleci::TNSNames() + 035h)
4 48C133h P07.exe (Oracleci::BuildOracleAliasList() + 04Fh)
5 48C17Eh P07.exe (Oracleci::OracleAliasList() + 01Eh)
6 488E67h P07.exe (Oraclelogon::LogonDialog(Oracle::TOracleSession *, int, int, System::Set&) + 01ABh)
7 44CDEEh P07.exe (Oracle::TOracleLogon::Execute + 0C6h)
8 403B0Eh P07.exe D:\Source\LMApps\p07\P07Main.cpp line 170 (P07Main::TP07MainForm::AfterInit + 072h)
9 60A964h P07.exe (System::AnsiString::~AnsiString() + 014h)
10 401CEAh P07.exe D:\Source\LMLibs\MainForm\MAINFORM.cpp line 87 (MAINFORM::TMainForm::TMainForm(Classes::TComponent *) + 046Ah)
11 4036CBh P07.exe D:\Source\LMApps\p07\P07Main.cpp line 90 (P07Main::TP07MainForm::TP07MainForm(Classes::TComponent *) + 033h)
12 401653h P07.exe D:\Source\LMApps\Release 1.0 Bpr\P07.cpp line 18 (P07::WinMain + 06Fh)
13 3257E14Ch cc3250mt.dll (_startup + 014Ch)

Maybe this helps a bit more on what could be wrong.

Yours
Lars Hammer
 
It seems to me that there is something wrong with your Net8 installation. The ntdll.dll where the AV occurs is a library that is user internally by Net8. Can you try this on a different PC?

------------------
Marco Kalter
Allround Automations
 
I have investigated further into the problem. The problem occurs when InitOCI() is called. The first time it is called in the logon process, it looks and works just fine. Later my Query->Execute() is called, and down the line it also calls InitOCI(), and this is the one that fails. In the last InitOCI(), OCISection is NULL, when CriticalSection function is called, and this triggers the AV. Maybe more important the code for the last InitOCI() is at a different address, than the first InitOCI().

I don't understand, how there should be 2 InitOCI's loaded. Looking at my debugger output there only seems to be one load of doa34c5.bpl.

Yours
Lars Hammer
 
I found a fix and maybe an explanation.

The explanation:
The first time InitOCI() is called, it is not yet relocated. The second time it is called, it is relocated, and somehow looses some information. The OCISection is NULL the second time InitOCI() is called and thus the calls are invalid and causes an AV.

The fix:
In my WinMain i call LoadPackage() loading doa34c5.bpl before creating any forms, and thus before calling InitOCI() for the first and second time. After the program is run, I naturally unload it again. Maybe this will help others too.

Yours
Lars Hammer

// Added 22. may 2002 LCH
HINST h = LoadPackage("doa34c5.bpl");
// InitOCI();
// ShowDOAInfo(NULL);

Application->CreateForm(__classid(TP07MainForm), &P07MainForm);
Application->CreateForm(__classid(TPlyGroupForm), &PlyGroupForm);
Application->CreateForm(__classid(TConstructionLineForm), &ConstructionLineForm);
Application->CreateForm(__classid(TP07ChartForm), &P07ChartForm);

Application->Run();

// Added 22. may 2002 LCH
UnloadPackage(h);
 
Back
Top