BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

DBX3 driver raises AV when loaded by DynaLink DBX 4

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Databases (dbExpress)
View previous topic :: View next topic  
Author Message
Martijn Tonies
Guest





PostPosted: Wed Apr 11, 2007 4:30 pm    Post subject: DBX3 driver raises AV when loaded by DynaLink DBX 4 Reply with quote



Hi,

I'm working on making our driver DBX3 compatible. So far so good, I'd say.

D2006 loads the driver without problems and displays data.

However, when trying to use the driver with D2007, the DBXDynalink thingy
tries to load it and the driver raises an error.


It happens here:
function TDBXDynalinkDriverCommonLoader.Load(DriverDef: TDBXDriverDef):
TDBXDriver;

....
ErrorResult := FMethodTable.FDBXLoader_GetDriver(Count, Names,
Values,

TDBXWideStringBuilder(ErrorMessageBuilder),
FDriverHandle);
....

I have no idea whatsoever what's going on. I cannot debug the driver
from the D2007 IDE, cause it cannot compile it (due to missing dbExpress
interfaces, as those are deprecated).


How are we supposed to compile DBX3 drivers with D2007??


Got any clue with regard to the driver?
--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com
Back to top
Martijn Tonies
Guest





PostPosted: Wed Apr 11, 2007 7:13 pm    Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 Reply with quote



Quote:
I have no idea whatsoever what's going on. I cannot debug the driver
from the D2007 IDE, cause it cannot compile it (due to missing
dbExpress interfaces, as those are deprecated).

You should be able to use the D2006 PAS or DCU files for these in
D2007.

Right, that worked.

It fails here:

ISQLDriver(Obj) := DriverInstance;

Where "Obj" is defined as:

function getSQLDriverFB(sVendorLib : PChar; sResourceFile : PChar; out Obj):
SQLResult; stdcall;


This works fine in D2006, but somehow fails inside the dynalink loader...



--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com
Back to top
Martijn Tonies
Guest





PostPosted: Wed Apr 11, 2007 7:34 pm    Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 Reply with quote



Quote:
function getSQLDriverFB(sVendorLib : PChar; sResourceFile : PChar;
out Obj): SQLResult; stdcall;

Is this CodeGear's code or yours? I don't know much about dbExpress
innards, but returning an interface as an untyped argument is odd to
say the least.

That is my function.

Here's how Borland (BDS 2006 and before) defined the "get driver func":

type
TGetDriverFunc = function(SVendorLib, SResourceFile: PChar; out Obj):
SQLResult; stdcall;


So, this is what I was doing. And it worked in D6, D7 and D2006... :-/

The dbExpress interfaces don't have GUIDs, so "Supports" or "as" don't work.

--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com
Back to top
Craig Stuntz [TeamB]
Guest





PostPosted: Wed Apr 11, 2007 7:44 pm    Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 Reply with quote

Martijn Tonies wrote:

Quote:
I have no idea whatsoever what's going on. I cannot debug the driver
from the D2007 IDE, cause it cannot compile it (due to missing
dbExpress interfaces, as those are deprecated).

You should be able to use the D2006 PAS or DCU files for these in
D2007.

--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz
Everything You Need to Know About InterBase Character Sets:
http://blogs.teamb.com/craigstuntz/articles/403.aspx
Back to top
Craig Stuntz [TeamB]
Guest





PostPosted: Wed Apr 11, 2007 8:28 pm    Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 Reply with quote

Martijn Tonies wrote:

Quote:
function getSQLDriverFB(sVendorLib : PChar; sResourceFile : PChar;
out Obj): SQLResult; stdcall;

Is this CodeGear's code or yours? I don't know much about dbExpress
innards, but returning an interface as an untyped argument is odd to
say the least.

--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz
Everything You Need to Know About InterBase Character Sets:
http://blogs.teamb.com/craigstuntz/articles/403.aspx
Back to top
Martijn Tonies
Guest





PostPosted: Wed Apr 11, 2007 8:30 pm    Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 Reply with quote

Quote:
So, this is what I was doing. And it worked in D6, D7 and D2006... :-/

The dbExpress interfaces don't have GUIDs, so "Supports" or "as"
don't work.

Right, you'd have to do the hard cast. That's not really the question,
though; it's the untyped argument which I found odd. But yes you'd have
to conform to the type of TGetDriverFunc.

Is it this assignment:

ISQLDriver(Obj) := DriverInstance;

...itself which raises the AV? If so then it may be failing in trying
to dereference DriverInstance. You can test this with a dummy
assignment to a typed variable:

var
Foo: ISQLDriver;

begin
[...]
Foo := DriverInstance; // does it fail here?

This works.

Quote:
ISQLDriver(Obj) := DriverInstance; // or only here?

This fails with the AV (read of address 00000001A).



--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com
Back to top
Craig Stuntz [TeamB]
Guest





PostPosted: Wed Apr 11, 2007 9:10 pm    Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 Reply with quote

Martijn Tonies wrote:

Quote:
So, this is what I was doing. And it worked in D6, D7 and D2006... :-/

The dbExpress interfaces don't have GUIDs, so "Supports" or "as"
don't work.

Right, you'd have to do the hard cast. That's not really the question,
though; it's the untyped argument which I found odd. But yes you'd have
to conform to the type of TGetDriverFunc.

Is it this assignment:

ISQLDriver(Obj) := DriverInstance;

...itself which raises the AV? If so then it may be failing in trying
to dereference DriverInstance. You can test this with a dummy
assignment to a typed variable:

var
Foo: ISQLDriver;

begin
[...]
Foo := DriverInstance; // does it fail here?
ISQLDriver(Obj) := DriverInstance; // or only here?

-Craig

--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz
Everything You Need to Know About InterBase Character Sets:
http://blogs.teamb.com/craigstuntz/articles/403.aspx
Back to top
Martijn Tonies
Guest





PostPosted: Wed Apr 11, 2007 9:18 pm    Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 Reply with quote

Quote:
ISQLDriver(Obj) := DriverInstance; // or only here?

This fails with the AV (read of address 00000001A).

Hmmm... I'd suggest rebuilding with debug DCUs and trace into the
assignment to see if you can get any closer to the error.

procedure _IntfCopy(var Dest: IInterface; const Source: IInterface);
{$IFDEF PUREPASCAL}
var
P: Pointer;
begin
P := Pointer(Dest);
if Source <> nil then
Source._AddRef;
Pointer(Dest) := Pointer(Source);
if P <> nil then
IInterface(P)._Release;
end;
{$ELSE}
asm
{
The most common case is the single assignment of a non-nil interface
to a nil interface. So we streamline that case here. After this,
we give essentially equal weight to other outcomes.

The semantics are: The source intf must be addrefed *before* it
is assigned to the destination. The old intf must be released
after the new intf is addrefed to support self assignment (I := I).
Either intf can be nil. The first requirement is really to make an
error case function a little better, and to improve the behaviour
of multithreaded applications - if the addref throws an exception,
you don't want the interface to have been assigned here, and if the
assignment is made to a global and another thread references it,
again you don't want the intf to be available until the reference
count is bumped.
}
TEST EDX,EDX // is source nil?
JE @@NilSource
PUSH EDX // save source
PUSH EAX // save dest
MOV EAX,[EDX] // get source vmt
PUSH EDX // source as arg
CALL DWORD PTR [EAX] + VMTOFFSET IInterface._AddRef
POP EAX // retrieve dest
MOV ECX, [EAX] // get current value
POP [EAX] // set dest in place
TEST ECX, ECX // is current value nil?
JNE @@ReleaseDest // no, release it

It jumps to ReleaseDest (current value <> nil).

RET // most common case, we return here
@@ReleaseDest:
MOV EAX,[ECX] // get current value vmt
PUSH ECX // current value as arg
CALL DWORD PTR [EAX] + VMTOFFSET IInterface._Release

Here, it fails with the AV.

Would this mean the "Out" parameter isn't NIL? Even if so, why should it?
Isn't it "Out" only?

RET



--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com
Back to top
Martijn Tonies
Guest





PostPosted: Wed Apr 11, 2007 9:27 pm    Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 Reply with quote

Quote:
ISQLDriver(Obj) := DriverInstance; // or only here?

This fails with the AV (read of address 00000001A).

This seems to work:

Pointer(Obj) := nil;
ISQLDriver(Obj) := DriverInstance;



--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com
Back to top
Martijn Tonies
Guest





PostPosted: Wed Apr 11, 2007 9:45 pm    Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 Reply with quote

Quote:
Would this mean the "Out" parameter isn't NIL? Even if so, why should
it? Isn't it "Out" only?

Yes and no. "out" is the same as "var". "out" params *should* be used
as out only, but the compiler doesn't enforce it.

Yes, it means the out is non-nil. Calling _Release on a non-nil and
not-pointing-to-any-allocated-object-implementing-an-interface can
indeed raise an AV, since _Release is virtual. Your workaround seems
correct to me.

So I thought.

I'm a bit puzzled as why this used to work before though.



All this being said, I'm now getting another weird error in the
DynalinkNative when FDBXConnection_GetIsolation is being
used.


Off to the debugger.


--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com
Back to top
Craig Stuntz [TeamB]
Guest





PostPosted: Wed Apr 11, 2007 10:03 pm    Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 Reply with quote

Martijn Tonies wrote:

Quote:
ISQLDriver(Obj) := DriverInstance; // or only here?

This fails with the AV (read of address 00000001A).

Hmmm... I'd suggest rebuilding with debug DCUs and trace into the
assignment to see if you can get any closer to the error.

--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz
Please read and follow Borland's rules for the user of their
server: http://support.borland.com/entry.jspa?externalID=293
Back to top
Craig Stuntz [TeamB]
Guest





PostPosted: Wed Apr 11, 2007 10:38 pm    Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 Reply with quote

Martijn Tonies wrote:

Quote:
Would this mean the "Out" parameter isn't NIL? Even if so, why should
it? Isn't it "Out" only?

Yes and no. "out" is the same as "var". "out" params *should* be used
as out only, but the compiler doesn't enforce it.

Yes, it means the out is non-nil. Calling _Release on a non-nil and
not-pointing-to-any-allocated-object-implementing-an-interface can
indeed raise an AV, since _Release is virtual. Your workaround seems
correct to me.

--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz
IB 6 versions prior to 6.0.1.6 are pre-release and may corrupt
your DBs! Open Edition users, get 6.0.1.6 from http://mers.com
Back to top
Peter Sawatzki
Guest





PostPosted: Fri Apr 13, 2007 11:50 pm    Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 Reply with quote

Martijn,

this is a bug in dbxadapter30 because the C++ definitions of
ISQLCommand30.execute, ISQLCommand30.executeImmediate and
ISQLCommand30.getNextCursor define their parameters as OUT while the
Pascal definition is VAR. I filed a bug report on this earlier (QC
#41784) already and this should be fixed for the RTM release, it is
marked as fixed for build 2620 (RTM= 2627). I'm wondering why you are
still seeing this. In my own driver I circumvented the crash by
explicitly assigning nil to the variable casted to a pointer.

from the QC: "Original definition for ISQLCommand30.execute from
BDS2006 is:

function execute(var Cursor: ISQLCursor30): SQLResult; stdcall;

if an old style Pascal written dbx3 driver implements/derives from
ISQLCommand30, the first assignment to Cursor in the driver will crash,
as dbxadapter30.dll is passing a non-nil value for Cursor (and in a
sense dbxadapter is correctly doing so, it assumes Cursor is an out
parameter). Of course the driver could be modified by changing the
definition to "out Cursor: ISQLCursor30" or the driver writer could do
a "Pointer(Cursor):= nil" as the first thing in the implementing
method, but this is probably not the case for most drivers.

So I suggest to modify dbxadapter30.dll to initialize all (incorrectly
defined) parameters it expects to receive. I think the following calls
need to be modified:

before calling ISQLCommand30.execute, set Pointer(Cursor):= nil;
before calling ISQLCommand30.executeImmediate, set Pointer(Cursor):=
nil;
before calling ISQLCommand30.getNextCursor, set Pointer(Cursor):= nil;"

Peter


Martijn Tonies wrote:

Quote:
Hi,

I'm working on making our driver DBX3 compatible. So far so good, I'd
say.

D2006 loads the driver without problems and displays data.

However, when trying to use the driver with D2007, the DBXDynalink
thingy tries to load it and the driver raises an error.


It happens here:
function TDBXDynalinkDriverCommonLoader.Load(DriverDef:
TDBXDriverDef): TDBXDriver;

...
ErrorResult := FMethodTable.FDBXLoader_GetDriver(Count, Names,
Values,

TDBXWideStringBuilder(ErrorMessageBuilder),

FDriverHandle); ...

I have no idea whatsoever what's going on. I cannot debug the driver
from the D2007 IDE, cause it cannot compile it (due to missing
dbExpress interfaces, as those are deprecated).


How are we supposed to compile DBX3 drivers with D2007??


Got any clue with regard to the driver?



--
Back to top
Peter Sawatzki
Guest





PostPosted: Fri Apr 13, 2007 11:55 pm    Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 Reply with quote

Craig,

the bug is in dbxadapter30 and the fact that the Pascal definions of
Cursor in ISQLCommand30.execute, ISQLCommand30.executeImmediate and
ISQLCommand30.getNextCursor are VAR and the C++ definions are OUT. As
soon as the Pascal code assigns something to Cursor the "Cursor" is
freed before the assignment. See my QC # 41784 which is marked as fixed
for build 2620.

Peter

Craig Stuntz [TeamB] wrote:

Quote:
Martijn Tonies wrote:

function getSQLDriverFB(sVendorLib : PChar; sResourceFile : PChar;
out Obj): SQLResult; stdcall;

Is this CodeGear's code or yours? I don't know much about dbExpress
innards, but returning an interface as an untyped argument is odd to
say the least.



--
Back to top
Martijn Tonies
Guest





PostPosted: Sat Apr 14, 2007 12:24 am    Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 Reply with quote

Hello Peter,

In the end, I figured this out, or at least, for ISQLDriver.

I've got another problem with the adapter now, the
Dynalink.DerivedOpen fails, please see my other post
in the dbExpress newsgroup.


--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com

If you can't dazzle em with brilliance, baffle em with bullshit

Quote:
this is a bug in dbxadapter30 because the C++ definitions of
ISQLCommand30.execute, ISQLCommand30.executeImmediate and
ISQLCommand30.getNextCursor define their parameters as OUT while the
Pascal definition is VAR. I filed a bug report on this earlier (QC
#41784) already and this should be fixed for the RTM release, it is
marked as fixed for build 2620 (RTM= 2627). I'm wondering why you are
still seeing this. In my own driver I circumvented the crash by
explicitly assigning nil to the variable casted to a pointer.

from the QC: "Original definition for ISQLCommand30.execute from
BDS2006 is:

function execute(var Cursor: ISQLCursor30): SQLResult; stdcall;

if an old style Pascal written dbx3 driver implements/derives from
ISQLCommand30, the first assignment to Cursor in the driver will crash,
as dbxadapter30.dll is passing a non-nil value for Cursor (and in a
sense dbxadapter is correctly doing so, it assumes Cursor is an out
parameter). Of course the driver could be modified by changing the
definition to "out Cursor: ISQLCursor30" or the driver writer could do
a "Pointer(Cursor):= nil" as the first thing in the implementing
method, but this is probably not the case for most drivers.

So I suggest to modify dbxadapter30.dll to initialize all (incorrectly
defined) parameters it expects to receive. I think the following calls
need to be modified:

before calling ISQLCommand30.execute, set Pointer(Cursor):= nil;
before calling ISQLCommand30.executeImmediate, set Pointer(Cursor):=
nil;
before calling ISQLCommand30.getNextCursor, set Pointer(Cursor):= nil;"

Peter


Martijn Tonies wrote:

Hi,

I'm working on making our driver DBX3 compatible. So far so good, I'd
say.

D2006 loads the driver without problems and displays data.

However, when trying to use the driver with D2007, the DBXDynalink
thingy tries to load it and the driver raises an error.


It happens here:
function TDBXDynalinkDriverCommonLoader.Load(DriverDef:
TDBXDriverDef): TDBXDriver;

...
ErrorResult := FMethodTable.FDBXLoader_GetDriver(Count, Names,
Values,

TDBXWideStringBuilder(ErrorMessageBuilder),

FDriverHandle); ...

I have no idea whatsoever what's going on. I cannot debug the driver
from the D2007 IDE, cause it cannot compile it (due to missing
dbExpress interfaces, as those are deprecated).


How are we supposed to compile DBX3 drivers with D2007??


Got any clue with regard to the driver?



--
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Databases (dbExpress) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.