views:

274

answers:

4

Hi,

We are trying to split up our monolithic EXE into a combination of an EXE and several packages. So far, we have one package that we're trying to use, and when running the EXE Codeguard shows the following error on startup:

CG Error

Two different CRTLDLLs are loaded. CG might report false errors
(C:\Windows\system32\CC32100MT.DLL)
(D:\Projects\Foo\Bar.bpl)

OK   

I read this as two different runtime libraries being loaded - one, the correct one (CC32100MT.dll), one incorrect, which is the package we're trying to use.

Continuing to run the program shows odd errors, especially casting between classes or passing a pointer to a class as a parameter in a method that crosses the EXE/DLL boundary. Codeguard itself doesn't show any other errors at all though. Edit: This is now resolved, and wasn't related. The program appears to run correctly, but the warning Codeguard shows is still worrying.

How do we solve this?

Some more details

We've looked at as many things as we (the developer working on this and I) can collectively think of:

  • Each project is built using runtime packages. The EXE host lists Bar in its package list.

  • Each project is set to compile with dynamic RTL. However, changing this does not solve the problem.

  • The package is linked to the EXE via its BPI file, but linking via a LIB makes no difference either.

  • The EXE and BPL are compiled with the same project settings, where the same options exist for both types of project. We think, anyway :)

  • There is only one copy of the BPL and BPI on the system: it's definitely linking to the right one.

  • Examining the EXE and BPL with Depends and TDump show they are both using C:\Windows\system32\CC32100MT.DLL. They should both be using the one RTL.

  • Creating a new project (a plain VCL forms application) and linking to the BPL (via its BPI) works fine. Something in the process of adding all the files and LIBs that make our EXE contain the code it needs to changes this, but we haven't been able to figure out what.

    • The LIBs all either correspond to DLLs we use (flat C interface, usually look as though they were built with MSVC) or are simple projects with lots of related files, compiled to a lib for the purpose of linking into the EXE - these correspond roughly to the areas of the program we want to split to BPLs, by the way. There don't seem to be project options for the LIB projects that would affect RTL linking, unless we've missed them.

    • I have exhaustively hunted through Depends and looked at all RTL and CC32*.dll files the EXE and every single DLL references. All are identical: rtl140.bpl and CC32100MT.DLL. Fully qualified paths show they are the same files, too. Everything should be using the one same run-time library.

Edit: The final EXE is complex, built with several libs, several DLLs, etc. All these, when built with C++Builder, are built with the current version. Is it possible there's something in one of these DLLs or LIBs that could cause a problem? I don't know enough about how the RTL is linked in to be sure about where to look... my (naive?) assumption is that the linker would normally link in one set of RTL functions, but that of course doesn't seem to be happening... and I don't know how things change when using packages. Is it possible this error has always existed and Codeguard has not flagged it before, because we haven't used something dynamic like a package?

Perhaps another question is, Why would a package have its own RTL anyway, or what would make it count as 'a RTL DLL' to Codeguard?

We're stumped. Absolutely stumped. We've had other problems using BPLs (they seem to be surprisingly tricky things, especially using C++) but have managed to solve them all. This one we've had no luck at all and we'd really appreciate any insights :)

We're using C++Builder 2010 (as part of RAD Studio actually, but with little Delphi code apart from components.)

Edit: Started a bounty. I'd really like to solve this!

Edit 2: Thanks to David Dean for his help (marked as answered below.) Via email, he pointed out this issue was reproduced in a simple test case by someone else, and is logged in Embarcadero QC as report 86335. Currently there is no fix, but the warning does not appear to indicate a genuine problem (ie, it's probably a spurious error, and while it's a pity to have to click past the dialog when you run, hopefully there's nothing in the error to worry about.)

+1  A: 

Since one of these is coming from a .bpl, did you try turning off "Build with runtime packages" in the project options?

David Dean - Embarcadero
In the EXE project options? No, this doesn't avoid the problem. In the package project options, the checkbox is disabled and so can't be either checked or unchecked, and the textfield is empty.
David M
You specifically state: Each project is built using runtime packages. The EXE host lists Bar in its package list. Where are you seeing this?
David Dean - Embarcadero
Sorry, I meant each project that has an option for runtime packages is built using runtime packages. I must have made a mistake thinking the BPL did too when I wrote that - it all gets confusing after a while! The BPL doesn't, LIBs linked into the EXE don't even have the option, the EXE does. Turning it off for the EXE doesn't make any difference. "Where" is in the Project Options, Packages item, 'Build with runtime packages' checkbox and the textbox underneath. Are BPLs supposed to have this option and is it a problem this one has the controls present in the dialog but disabled?
David M
What does the command line to the linker look like for the exe? You should see this in the "Output" tab of the message view.
David Dean - Embarcadero
Deleting lots of very similar stuff, it looks like this. "..." is stuff I've cut; "PartA.lib" etc are the library projects that are linked in too. Bar.bpi is our package. It is: c:\...\ilink32.exe -Lobjd;COM\Debug;"c:\...\7.0\lib\debug";[...other paths]";"C:\Users\Public\Documents\RAD Studio\7.0\DCP";Debug_Build -l. -c -v -t -GA"C:\Users\davidm\AppData\Local\Temp\vfs92B7.tmp"="C:\projects\Foo\Debug_Build\App.res" -GA"[other a=b, and .dfm files]" -aa -S:0x00800000 -GF:LARGEADDRESSAWARE -V5.0 -w -G8 c0w32w Bar.bpi memmgr.lib sysinit.obj objd\blah.obj [other .obj files]
David M
(continued) objd\blahagain.obj , .\Foo.exe , .\Foo.map , cg32.lib vclx.lib vcl.lib rtl.lib xmlrtl.lib vclactnband.lib tb2k_d12.lib SpTBXLib_d12.lib VirtualTreesD12.lib FooComponents.lib vclie.lib bcbie.lib vclimg.lib [...] Glut\glut32.lib Shared\Lib\GLee.lib PartA.lib PartB.lib PartC.lib import32.lib cp32mti.lib , , C:\Users\davidm\AppData\Local\Temp\vfs92B7.tmp C:\Users\davidm\AppData\Local\Temp\vfs92B8.tmp
David M
Apologies for splitting it over several comments - there's only a 600-character limit! I've tried to cut it down to a fairly small line (compared to what it actually is) without removing anything important. I spotted a bug in the Output view here - this particular entry draws completely blank in the view. Luckily it shows text in its hint so mousing over showed which "blank" line to select and copy.
David M
There was enough there for me to see that it is indeed trying to link using the dynamic RTL and the bpl, however, it is linking statically to the VCL. In the exe's project options look at the line under the checkbox for "build with runtime packages" if it doesn't have at least "vcl,rtl,vclx,foo" then you're likely to get a mismatch since some are linking statically while others are linking dynamically.
David Dean - Embarcadero
Yes, it only had Foo listed in the packages. I changed it to "vcl;rtl;vclx;Foo", but still get the Codeguard warning after building. I have also ensured the <Multithreaded>true</Multithreaded> line is present in both projects, as suggested by Carl, and looked at the <PackageImports> and <LinkPackageImports> items (both didn't, but now do, list the BPIs for the vcl/vclx/rtl/foo packages) and removed the .lib entries for the same packages from <LinkPackageStatics> and <AllPackageLibs>. This was all guesswork. I closed and reopened the project group and built the EXE each time. None of it worked!
David M
OK, some further digging is required. Is codeguard enabled when building foo.bpl? When you step into your exe in the debugger, does the module list show more than one RTL in the list? (cc32*)
David Dean - Embarcadero
No, there's just one: "cc32100mt.dll $32A00000 C:\Windows\SysWOW64\CC32100MT.DLL 38" Also only one of each other DLL. The package is also built with Codeguard. (But not building it with Codeguard makes no difference. The Codeguard error still shows if CG is built only into the package and not the EXE, and vice versa.)
David M
David, I'm going to be overseas (in the US, actually) for the next fortnight and mostly away from internet. Would you like me to award the bounty? You've been very helpful (and thanks!) What would you recommend for solving this when I get back?
David M
The module list confirms that this is probably a bug in codeguard, so your best bet is to turn off codeguard for this project. It's up to you on the bounty, but I don't feel like I've really solved your problem. I'm rather eager to duplicate this so that it can get fixed. Which OS are you using, that may help me pin down the bug. feel free to contact me directly via email my firstname dot my lastname at embarcadero dot com.
David Dean - Embarcadero
A: 

We had a similar problem. We tracked it down to a (non VCL) .cbproj that was created without the "Multithreaded" option.

As far as I can tell, the only time you get chance to set this option is when you create a new .cbproj, it cannot be changed afterwards using the GUI. We ended up "hacking" the .cbproj to include the following:

<Multithreaded>true</Multithreaded>

To determine which dll is causing the issue, it should be the last dll loaded in the output window just before you see the CG message.

Carl
Thanks for the suggestion! The EXE project did not have this line, but was using the multithreaded RTL DLL anyway, and manually adding the line didn't change anything. The last-listed DLL is UxTheme.dll, ie a Windows one, and most of our normal DLLs and the package are loaded much earlier in the list. Several DLLs load after the message, though, such as a VC-compiled third-party DLL and sxs.dll.
David M
A: 

Did you check if you use _TCHAR as char. We had some similar problems with RAD Studio and we found a workaround using _TCHAR as char. As soon as one DLL or BPL Project is compiled with wchar_t, this code guard error appears.

We also figured out, that EXE projects can be compiled with TCHAR = wchar_t without any problem (the main function will be WIDE).

The settings does not affect the GUI being able to handle UNICODE.

test
Hi test: yes, both the EXE and BPL are compiled with _TCHAR set to wchar_t. Thanks for the suggestion though!
David M
A: 

A customer logged a similar case in our public bug tracking system and the bug has been identified and fixed in the latest release.

David Dean - Embarcadero
Is that C++ Builder XE, David?
David M
Yes, it was fixed in C++Builder XE
David Dean - Embarcadero