Board index » cppbuilder » Runtime code causing AV's

Runtime code causing AV's

I have the following code in a package:

class PACKAGE TMJFPatchPackageItemList : public TObjectList
{
typedef TObjectList Inherited;

private:

TMJFPatchEnumPackageItemDetail* __fastcall GetPackageItem(int Index)
{ return dynamic_cast<TMJFPatchEnumPackageItemDetail*>(Items[Index]); }

public:

__fastcall TMJFPatchPackageItemList(void) : TObjectList(true) {}

HIDESBASE int __fastcall Add(TMJFPatchEnumPackageItemDetail *AItem)
{
int Index = Inherited::Add(AItem);
return Index;

Quote
}

__property TMJFPatchEnumPackageItemDetail* PackageItem[int Index] = {
read = GetPackageItem };

Quote
};

I added an explicit Add() method so I could see what was being added. The
contents of 'AItem' are valid and the value of Index increments. The
de{*word*81} shows each 'PackageItem' as NULL after the Add operation (ie on the
return line).

The caller adds a TMJFPatchEnumPackageItemDetail* object - here is the code
within a loop:

TMJFPatchEnumPackageItemDetail *Detail = new TMJFPatchEnumPackageItemDetail;
// set Detail information
PackageItems->Add(Detail);

where PackageItems comes into the method as:

bool __fastcall TMJFPatch::EnumPatchPackage(AnsiString PatchFileName,
TMJFPatchPackageItemList *PackageItems, bool IncludeStats)
{
// ...

Quote
}

...and yes, here is the declaration for the item type being added, just to
show it descends from TObject
class PACKAGE TMJFPatchEnumPackageItemDetail : public TObject
{
private:
public:
AnsiString SourceFileName;
AnsiString PatchedFileName;
TMJFPatchFileHeader PFH;
TMJFPatchPackageItemStatInfo Stats;
__fastcall TMJFPatchEnumPackageItemDetail(void) : TObject() {}

Quote
};

Now, if I link my project WITHOUT packages it works fine.  Enable the
packages in the project and I get NULL items added to the list.  I am
linking the correct code because the de{*word*81} shows my additional test code
when I was tracing through.

Any ideas ?
--
Malcolm Smith
MJ Freelancing- http://www.mjfreelancing.com
Software Protection for C++Builder
Borland Technology Partner

 

Re:Runtime code causing AV's


No response to this one, may be I chose a bad subject line.

Original message below.  Basically, my dynamically linked apps are not
working the same as my static links.

--

I have the following code in a package:

class PACKAGE TMJFPatchPackageItemList : public TObjectList
{
typedef TObjectList Inherited;

private:

TMJFPatchEnumPackageItemDetail* __fastcall GetPackageItem(int Index)
{ return dynamic_cast<TMJFPatchEnumPackageItemDetail*>(Items[Index]); }

public:

__fastcall TMJFPatchPackageItemList(void) : TObjectList(true) {}

HIDESBASE int __fastcall Add(TMJFPatchEnumPackageItemDetail *AItem)
{
int Index = Inherited::Add(AItem);
return Index;

Quote
}

__property TMJFPatchEnumPackageItemDetail* PackageItem[int Index] = {
read = GetPackageItem };

Quote
};

I added an explicit Add() method so I could see what was being added. The
contents of 'AItem' are valid and the value of Index increments. The
de{*word*81} shows each 'PackageItem' as NULL after the Add operation (ie on the
return line).

The caller adds a TMJFPatchEnumPackageItemDetail* object - here is the code
within a loop:

TMJFPatchEnumPackageItemDetail *Detail = new TMJFPatchEnumPackageItemDetail;
// set Detail information
PackageItems->Add(Detail);

where PackageItems comes into the method as:

bool __fastcall TMJFPatch::EnumPatchPackage(AnsiString PatchFileName,
TMJFPatchPackageItemList *PackageItems, bool IncludeStats)
{
// ...

Quote
}

...and yes, here is the declaration for the item type being added, just to
show it descends from TObject
class PACKAGE TMJFPatchEnumPackageItemDetail : public TObject
{
private:
public:
AnsiString SourceFileName;
AnsiString PatchedFileName;
TMJFPatchFileHeader PFH;
TMJFPatchPackageItemStatInfo Stats;
__fastcall TMJFPatchEnumPackageItemDetail(void) : TObject() {}

Quote
};

Now, if I link my project WITHOUT packages it works fine.  Enable the
packages in the project and I get NULL items added to the list.  I am
linking the correct code because the de{*word*81} shows my additional test code
when I was tracing through.

Any ideas ?
--
Malcolm Smith
MJ Freelancing- http://www.mjfreelancing.com
Software Protection for C++Builder
Borland Technology Partner

Re:Runtime code causing AV's


Can someone please try and look at this issue below.  I've had other
developers looking at it and no one can see any problems with the code.  I
am wondering if it is a BCB5 compiler bug.

TIA

--
Malcolm Smith
MJ Freelancing- http://www.mjfreelancing.com
Software Protection for C++Builder
Borland Technology Partner

Quote
"Malcolm Smith" <mjfreelanc...@optusnet.com.au> wrote in message

news:3e6f967a$1@newsgroups.borland.com...
Quote
> No response to this one, may be I chose a bad subject line.

> Original message below.  Basically, my dynamically linked apps are not
> working the same as my static links.

> --

> I have the following code in a package:

> class PACKAGE TMJFPatchPackageItemList : public TObjectList
> {
> typedef TObjectList Inherited;

> private:

> TMJFPatchEnumPackageItemDetail* __fastcall GetPackageItem(int Index)
> { return dynamic_cast<TMJFPatchEnumPackageItemDetail*>(Items[Index]); }

> public:

> __fastcall TMJFPatchPackageItemList(void) : TObjectList(true) {}

> HIDESBASE int __fastcall Add(TMJFPatchEnumPackageItemDetail *AItem)
> {
> int Index = Inherited::Add(AItem);
> return Index;
> }

> __property TMJFPatchEnumPackageItemDetail* PackageItem[int Index] = {
> read = GetPackageItem };

> };

> I added an explicit Add() method so I could see what was being added. The
> contents of 'AItem' are valid and the value of Index increments. The
> de{*word*81} shows each 'PackageItem' as NULL after the Add operation (ie on
the
> return line).

> The caller adds a TMJFPatchEnumPackageItemDetail* object - here is the
code
> within a loop:

> TMJFPatchEnumPackageItemDetail *Detail = new

TMJFPatchEnumPackageItemDetail;

- Show quoted text -

Quote
> // set Detail information
> PackageItems->Add(Detail);

> where PackageItems comes into the method as:

> bool __fastcall TMJFPatch::EnumPatchPackage(AnsiString PatchFileName,
> TMJFPatchPackageItemList *PackageItems, bool IncludeStats)
> {
> // ...
> }

> ...and yes, here is the declaration for the item type being added, just to
> show it descends from TObject
> class PACKAGE TMJFPatchEnumPackageItemDetail : public TObject
> {
> private:
> public:
> AnsiString SourceFileName;
> AnsiString PatchedFileName;
> TMJFPatchFileHeader PFH;
> TMJFPatchPackageItemStatInfo Stats;
> __fastcall TMJFPatchEnumPackageItemDetail(void) : TObject() {}
> };

> Now, if I link my project WITHOUT packages it works fine.  Enable the
> packages in the project and I get NULL items added to the list.  I am
> linking the correct code because the de{*word*81} shows my additional test
code
> when I was tracing through.

> Any ideas ?
> --
> Malcolm Smith
> MJ Freelancing- http://www.mjfreelancing.com
> Software Protection for C++Builder
> Borland Technology Partner

Re:Runtime code causing AV's


Quote
> Now, if I link my project WITHOUT packages it works fine.  Enable the
> packages in the project and I get NULL items added to the list.

(As I understand it, you have problems when the bpl is dynamically linked,
right?)

What do you mean by 'I get NULL items added to list'?  Do you mean to say
that you get a NULL pointer in the Add() function or that GetPackageItem()
returns NULL?  If the latter is the case, I'd suspect that the dynamic_cast
operator returns NULL simply because the typecast failed.  Are you by any
change using more packages which depend on each other?  If so, try
rebuilding them all.

Anyway, statically or dynamically linked, the code you posted code works
fine here (using one package and one executable).  I have BCB5 with Update
Pack 1 installed, running on XP.  I had to modify the code a little though.
I commented out two lines in the TMJFPatchEnumPackageItemDetail class
definition, since you didn't post the definitions for TMJFPatchFileHeader
nor TMJFPatchPackageItemStatInfo.  Nevertheless, I fail to see how these
structs/classes would influence anything.

Looking at the code you posted, the only thing I can think of is that the
dynamic_cast fails.  In that case something must be wrong with the RTTI.
This might happen whenever the 'same' classes are defined in different
targets (dll/bpl/exe).  I believe it might be possible to{*word*222}things up
when a class is defined in the executable _and_ in the bpl as well.  When
the bpl is loaded, I think you'll end up with two different RTTI entries for
the class.

I noticed that you implemented the class in the class definition it self.
Was it merely example for the NG?  Anyway, did you make sure that your class
isn't defined twice (once in the package and once in the executable itself)?
Typically, a header file looks like this:

  #ifndef headerfile_tag
  #define headerfile_tag

    <headerfile>

  #endif

Hope this helps you...  Good luck.

Ralph

Re:Runtime code causing AV's


Thanks for the response.

The class is defined in the package only.

By NULL I mean this:

Quote
> HIDESBASE int __fastcall Add(TMJFPatchEnumPackageItemDetail *AItem)
> {
> int Index = Inherited::Add(AItem);
> return Index;
> }

The above code is in the package.  I added a WATCH to return Items[0].  When
I trace into this code (in the package) 'AItem' has a valid pointer.  After
the Add() is processed Items[0] is NULL.  It isn't the dynamic_cast that is
failing.

The two lines you commented out are only structs so they won't have an
affect.

My headers have the correct #ifdef.

The code shown was declared in the header (for testing).  I will move it to
the .cpp file and see what happens.

--
Malcolm Smith
MJ Freelancing
http://www.mjfreelancing.com

Quote
"Ralph Kazemier" <ralph.kazem...@jess.nl> wrote in message

news:3e75e16b$1@newsgroups.borland.com...
Quote
> > Now, if I link my project WITHOUT packages it works fine.  Enable the
> > packages in the project and I get NULL items added to the list.

> (As I understand it, you have problems when the bpl is dynamically linked,
> right?)

[snip]

Re:Runtime code causing AV's


Quote
"Malcolm Smith" <m.sm...@comvision.org> wrote in message

news:3e76532d@newsgroups.borland.com...

Quote
> The above code is in the package.  I added a WATCH to return Items[0].

Did you try explitically inspecting the list directly after calling Add()
without using the Watch List at all?  Perhaps the Watch List simply wasn't
updating its display correctly.

There's no way TList can possibly store NULL pointers if you pass it valid
pointers to begin with, as your code appears to be doing, since it makes a
copy of the actual pointer you pass to it.  No runtime checking or anything
like that, so that can't be getting in the way.

Gambit

Re:Runtime code causing AV's


I moved the implementation into the source file instead of the header (was
only there for testing) and now it works fine.

Possibly a bad optimisation, yes ?

--
Malcolm Smith
MJ Freelancing
http://www.mjfreelancing.com

"Remy Lebeau (TeamB)" <gambi...@yahoo.com> wrote in message
news:3e765662@newsgroups.borland.com...

Quote

> "Malcolm Smith" <m.sm...@comvision.org> wrote in message
> news:3e76532d@newsgroups.borland.com...

> > The above code is in the package.  I added a WATCH to return Items[0].

> Did you try explitically inspecting the list directly after calling Add()
> without using the Watch List at all?  Perhaps the Watch List simply wasn't
> updating its display correctly.

> There's no way TList can possibly store NULL pointers if you pass it valid
> pointers to begin with, as your code appears to be doing, since it makes a
> copy of the actual pointer you pass to it.  No runtime checking or
anything
> like that, so that can't be getting in the way.

> Gambit

Re:Runtime code causing AV's


Maybe.  Whenever possible, you shouldn't be placing any kind of actual
coding into header files to begin with, except for templates and inline
functions.  Everything else should be an actual source file.

Gambit

Quote
"Malcolm Smith" <m.sm...@comvision.org> wrote in message

news:3e76579a@newsgroups.borland.com...
Quote
> I moved the implementation into the source file instead
> of the header (was only there for testing) and now it
> works fine.

> Possibly a bad optimisation, yes ?

Re:Runtime code causing AV's


Yes I know - I was originally testing preliminary code and forgot to move
it.

--
Malcolm Smith
MJ Freelancing
http://www.mjfreelancing.com

"Remy Lebeau (TeamB)" <gambi...@yahoo.com> wrote in message
news:3e765ecd$1@newsgroups.borland.com...

Quote
> Maybe.  Whenever possible, you shouldn't be placing any kind of actual
> coding into header files to begin with, except for templates and inline
> functions.  Everything else should be an actual source file.

> Gambit

> "Malcolm Smith" <m.sm...@comvision.org> wrote in message
> news:3e76579a@newsgroups.borland.com...
> > I moved the implementation into the source file instead
> > of the header (was only there for testing) and now it
> > works fine.

> > Possibly a bad optimisation, yes ?

Other Threads