| Author |
crash when passing iterators between modules
|
|
| Jakob Simon-Gaarde 2005-07-29, 9:07 am |
| Hi.
I want to use stl containers like std::set and std::vector to pass
information between several modules. The containers are defined using
typedef in the appropriate headerfiles within the domain of a common
library called vm2_common.dll. For instance I have the following
definition:
dbcontext.h:
------------
typedef std::set<GarageKey> GarageSet;
The problem is that when I pass an instance of such a container to
another module, say the main application, then things start going
wrong. If I pass the container as a reference then I can call some of
the methods like size(). If I use iterators then it crashes write away.
If copy the same code that crashes in the application into the common
library then everythin goes well:
In the application:
------------------
// ctx : DBContextHelper
// ctx is implemented in the common library, and
// the instantation of the GarageSet being passed
// is also implmentated in the common library
const GarageSet& s = ctx.taggedGarages();
GarageSet::const_iterator it = s.begin();
for (;it!=s.end();++it)
int garage = (*it).destnr(); // here
* This code crashes when executing (*it).destnr() second iteration (not
first)
In the common library:
---------------------
void DBContextHelper::dummytest()
{
const GarageSet& s = taggedGarages();
GarageSet::const_iterator it = s.begin();
for (;it!=s.end();++it)
int garage = (*it).destnr(); // here
}
* This code is identical to the application code but does not crash
What is wrong? I have googled myself to somthing about shared dll and
heap problems, is that it?
Best regards
Jakob Simon-Gaarde
| |
| Carl Daniel [VC++ MVP] 2005-07-29, 9:07 am |
| Jakob Simon-Gaarde wrote:
> Hi.
>
> I want to use stl containers like std::set and std::vector to pass
> information between several modules. The containers are defined using
> typedef in the appropriate headerfiles within the domain of a common
> library called vm2_common.dll. For instance I have the following
> definition:
[ snipped details]
>
> What is wrong? I have googled myself to somthing about shared dll and
> heap problems, is that it?
Most likely the cause is that you have two or more copies of the CRT in your
program. Make sure you're building your EXE and all of your DLLs with the
multi-threaded DLL runtime library. Otherwise you have separate heaps in
each module and, among other things, you can't share C++ standard library
components across module boundaries.
-cd
| |
| Jakob Simon-Gaarde 2005-07-29, 5:07 pm |
| I have opened the main application and the common library in Dependncy
Walker:
The linker has made the application dependent on the following DLLs:
------------------------------------------------------------
c:\dev\tr\conan\32bit\bin\TRBROKER36D.DLL
c:\dev\tr\conan\32bit\bin\TRCONAN36D.DLL
c:\dev\tr\conan\32bit\bin\TRQTUI36D.DLL
c:\dev\tr\vehiclemanager\VEHICLEMANAGER.EXE
c:\dev\tr\vehiclemanager\VM2_COMMOND.DLL
c:\qt\3.3.3\bin\QT-MT333.DLL
c:\windows\system32\ADVAPI32.DLL
c:\windows\system32\COMDLG32.DLL
c:\windows\system32\GDI32.DLL
c:\windows\system32\IMM32.DLL
c:\windows\system32\KERNEL32.DLL
c:\windows\system32\MSVCP60D.DLL
c:\windows\system32\MSVCRT.DLL
c:\windows\system32\MSVCRTD.DLL
c:\windows\system32\NTDLL.DLL
c:\windows\system32\OLE32.DLL
c:\windows\system32\OLEAUT32.DLL
c:\windows\system32\RPCRT4.DLL
c:\windows\system32\SHELL32.DLL
c:\windows\system32\SHLWAPI.DLL
c:\windows\system32\USER32.DLL
c:\windows\system32\VERSION.DLL
c:\windows\system32\WINMM.DLL
c:\windows\system32\WINSPOOL.DRV
c:\windows\system32\WS2HELP.DLL
c:\windows\system32\WS2_32.DLL
c:\windows\system32\WSOCK32.DLL
c:\windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.0.0_x-ww_8a69ba05\COMCTL32.DLL
The linker has made the common library dependent on the following DLLs:
------------------------------------------------------------
c:\dev\tr\conan\32bit\bin\TRBROKER36D.DLL
c:\dev\tr\conan\32bit\bin\TRCONAN36D.DLL
c:\dev\tr\conan\32bit\bin\TRQTUI36D.DLL
c:\dev\tr\vehiclemanager\VM2_COMMOND.DLL
c:\qt\3.3.3\bin\QT-MT333.DLL
c:\windows\system32\ADVAPI32.DLL
c:\windows\system32\COMDLG32.DLL
c:\windows\system32\GDI32.DLL
c:\windows\system32\IMM32.DLL
c:\windows\system32\KERNEL32.DLL
c:\windows\system32\MSVCP60D.DLL
c:\windows\system32\MSVCRT.DLL
c:\windows\system32\MSVCRTD.DLL
c:\windows\system32\NTDLL.DLL
c:\windows\system32\OLE32.DLL
c:\windows\system32\OLEAUT32.DLL
c:\windows\system32\RPCRT4.DLL
c:\windows\system32\SHELL32.DLL
c:\windows\system32\SHLWAPI.DLL
c:\windows\system32\USER32.DLL
c:\windows\system32\VERSION.DLL
c:\windows\system32\WINMM.DLL
c:\windows\system32\WINSPOOL.DRV
c:\windows\system32\WS2HELP.DLL
c:\windows\system32\WS2_32.DLL
c:\windows\system32\WSOCK32.DLL
c:\windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.0.0_x-ww_8a69ba05\COMCTL32.DLL
I think the last entry on both the application and the common library
looks a little fishy. Could the msvcrt.dll and msvcrtd.dll be the
problem? They are both loaded for some reason.
| |
| Carl Daniel [VC++ MVP] 2005-07-29, 5:07 pm |
| Jakob Simon-Gaarde wrote:
> I have opened the main application and the common library in Dependncy
> Walker:
>
> The linker has made the application dependent on the following DLLs:
> ------------------------------------------------------------
[ snipped dependencies ]
>
>
> The linker has made the common library dependent on the following
> DLLs:
>
> ------------------------------------------------------------
[ snipped dependencies ]
>
> I think the last entry on both the application and the common library
> looks a little fishy. Could the msvcrt.dll and msvcrtd.dll be the
> problem? They are both loaded for some reason.
It could be, but there's not enough information here to tell. You'll just
about always get MSVCRT.DLL, even in a debug build, so seeing both is not in
an of itself a cause for alarm.
That said, if you do have a mix of Debug and Release modules in your
EXE+DLL, then that could be the source of your problem.
What are the compiler and linker options that you're using? In order to
share C++ library components between an EXE and a DLL, everything must be
compiled with /MD (or /MDd, but not a mix of both), and everything must link
with msvcrt.lib (or msvcrtd.lib, but not both).
-cd
| |
| Jakob Simon-Gaarde 2005-07-29, 5:07 pm |
| I was just looking a bit more closely at the facts provided by
Dependency Walker. I am building a debug version of the app and the
common lib, therefore the linker wants to link to msvcrtd.dll. The
msvcrt.dll is loaded via qt-mt333.dll (which by the way also is a debug
version):
qt-mt333.dll
--->comdlg32.dll
--->shlwapi.dll
--->msvcrt.dll
so msvcrt.dll links to msvcrt.dll, while qt-mt333 itself links to
msvcrtd.dll. What impact does this have, and is this the problem?
| |
| Carl Daniel [VC++ MVP] 2005-07-29, 5:07 pm |
| Jakob Simon-Gaarde wrote:
> I was just looking a bit more closely at the facts provided by
> Dependency Walker. I am building a debug version of the app and the
> common lib, therefore the linker wants to link to msvcrtd.dll. The
> msvcrt.dll is loaded via qt-mt333.dll (which by the way also is a
> debug version):
>
> qt-mt333.dll
> --->comdlg32.dll
> --->shlwapi.dll
> --->msvcrt.dll
>
> so msvcrt.dll links to msvcrt.dll, while qt-mt333 itself links to
> msvcrtd.dll. What impact does this have, and is this the problem?
It's normal to have msvcrt.dll in a debug build because as you discovered,
other system DLLs will drag it in. That's OK, because those DLLs don't
share heap-allocated structures with your code, so there's no issue with
allocating from one heap and freeing in another (which is most likely the
cause of your crash).
Is QT-MT333.DLL one of yours? Are you sharing heap-allocated structures
across the DLL interface?
-cd
| |
| Jakob Simon-Gaarde 2005-07-29, 5:07 pm |
| All parts of my project are compiled in debugmode right now, so it's
not that kind of mix.
Here are the compiler flags:
The common lib:
-----------------
cl -c -nologo -Zm200 -W3 -MDd -Zi
-I"C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE"
-I"C:\Program Files\Microsoft Visual Studio\VC98\MFC\INCLUDE"
-I"C:\Program Files\Microsoft Visual Studio\VC98\ATL\INCLUDE"
-I"C:\QT\3.3.3\INCLUDE" -I"C:\DEV\TR\CONAN\32BIT\INCLUDE"
-I" C:\DEV\TR\VEHICLEMANAGER\VM2_COMMON\INCL
UDE" /GZ /GR -GX
/FI"src/warnings.h" -D"WIN32" -D"_DEBUG" -D"_WINDOWS"
-D"VM2_COMMON_DLL" -DQT_DLL -DQT_THREAD_SUPPORT
-I"C:\Qt\3.3.3\include" -I"C:\dev\tr\VehicleManager\vm2_common"
-I"C:\Qt\3.3.3\mkspecs\win32-msvc"
-FoDebug\ @C:\DOCUME~1\tsejsg\LOCALS~1\Temp\1\nmk0
1736.
The application:
------------------
cl -c -nologo -Zm200 -W3 -MDd -Zi
-I"C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE"
-I"C:\Program Files\Microsoft Visual Studio\VC98\MFC\INCLUDE"
-I"C:\Program Files\Microsoft Visual Studio\VC98\ATL\INCLUDE"
-I"C:\QT\3.3.3\INCLUDE" -I"C:\DEV\TR\CONAN\32BIT\INCLUDE"
-I" C:\DEV\TR\VEHICLEMANAGER\VM2_COMMON\INCL
UDE"
/GZ /GR -GX -D"WIN32" -D"_DEBUG" -D"_WINDOWS"
-DQT_DLL -DQT_THREAD_SUPPORT -I"C:\Qt\3.3.3\include" -I"src\ui"
-I"src/ui" -I"src\commonwidgets" -I"src/commonwidgets" -I"src\tr\ui"
-I"src/tr/ui" -I"C:\dev\tr\VehicleManager"
-I"C:\Qt\3.3.3\mkspecs\win32-msvc"
-FoDebug\ @C:\DOCUME~1\tsejsg\LOCALS~1\Temp\1\nma0
9808.
Best regards Jakob
| |
| Jakob Simon-Gaarde 2005-07-29, 5:07 pm |
| qt-mt333.dll is just Qt (trolltech.com) a cross platform C++ GUI
framework.
Mine are:
c:\dev\tr\conan\32bit\bin\TRBROKER36D.DLL
c:\dev\tr\conan\32bit\bin\TRCONAN36D.DLL
c:\dev\tr\conan\32bit\bin\TRQTUI36D.DLL
c:\dev\tr\vehiclemanager\VEHICLEMANAGER.EXE
c:\dev\tr\vehiclemanager\VM2_COMMOND.DLL
| |
| Carl Daniel [VC++ MVP] 2005-07-29, 5:07 pm |
| Jakob Simon-Gaarde wrote:
> All parts of my project are compiled in debugmode right now, so it's
> not that kind of mix.
> Here are the compiler flags:
>
> The common lib:
> -----------------
> cl -c -nologo -Zm200 -W3 -MDd -Zi
> -I"C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE"
> -I"C:\Program Files\Microsoft Visual Studio\VC98\MFC\INCLUDE"
> -I"C:\Program Files\Microsoft Visual Studio\VC98\ATL\INCLUDE"
> -I"C:\QT\3.3.3\INCLUDE" -I"C:\DEV\TR\CONAN\32BIT\INCLUDE"
> -I" C:\DEV\TR\VEHICLEMANAGER\VM2_COMMON\INCL
UDE" /GZ /GR -GX
> /FI"src/warnings.h" -D"WIN32" -D"_DEBUG" -D"_WINDOWS"
> -D"VM2_COMMON_DLL" -DQT_DLL -DQT_THREAD_SUPPORT
> -I"C:\Qt\3.3.3\include" -I"C:\dev\tr\VehicleManager\vm2_common"
> -I"C:\Qt\3.3.3\mkspecs\win32-msvc"
> -FoDebug\ @C:\DOCUME~1\tsejsg\LOCALS~1\Temp\1\nmk0
1736.
>
> The application:
> ------------------
> cl -c -nologo -Zm200 -W3 -MDd -Zi
> -I"C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE"
> -I"C:\Program Files\Microsoft Visual Studio\VC98\MFC\INCLUDE"
> -I"C:\Program Files\Microsoft Visual Studio\VC98\ATL\INCLUDE"
> -I"C:\QT\3.3.3\INCLUDE" -I"C:\DEV\TR\CONAN\32BIT\INCLUDE"
> -I" C:\DEV\TR\VEHICLEMANAGER\VM2_COMMON\INCL
UDE"
> /GZ /GR -GX -D"WIN32" -D"_DEBUG" -D"_WINDOWS"
> -DQT_DLL -DQT_THREAD_SUPPORT -I"C:\Qt\3.3.3\include" -I"src\ui"
> -I"src/ui" -I"src\commonwidgets" -I"src/commonwidgets" -I"src\tr\ui"
> -I"src/tr/ui" -I"C:\dev\tr\VehicleManager"
> -I"C:\Qt\3.3.3\mkspecs\win32-msvc"
> -FoDebug\ @C:\DOCUME~1\tsejsg\LOCALS~1\Temp\1\nma0
9808.
Hrmpf!
You do appear to be compiling everything with /MTd, so you should be OK.
The only other suggestion I can think of at the moment is to make sure that
you don't have any conflicting options set on a per-file basis.
Have you done any debugging to try to narrow down exactly what's going wrong
when your code "crashes"?
-cd
| |
| Jakob Simon-Gaarde 2005-07-29, 5:07 pm |
| I can offer you to look at the problem live through a webex meeting if
you want by sharing my desktop.
| |
| Duane Hebert 2005-07-30, 9:02 am |
|
"Jakob Simon-Gaarde" <jsgaarde@gmail.com> wrote in message news:1122672233.543070.120900@g44g2000cwa.googlegroups.com...
> qt-mt333.dll is just Qt (trolltech.com) a cross platform C++ GUI
> framework.
> Mine are:
> c:\dev\tr\conan\32bit\bin\TRBROKER36D.DLL
> c:\dev\tr\conan\32bit\bin\TRCONAN36D.DLL
> c:\dev\tr\conan\32bit\bin\TRQTUI36D.DLL
> c:\dev\tr\vehiclemanager\VEHICLEMANAGER.EXE
> c:\dev\tr\vehiclemanager\VM2_COMMOND.DLL
>
FWIW we specify ignore library MSVCRT.Lib in our
debug builds under the linker options for "ignore specific library".
We're building always with Qt's release build though.
We've had no problem with a separate QWT library linked
to our application and the QWT stuff shares vectors with
the main app.
| |
| Jakob Simon-Gaarde 2005-07-31, 5:19 pm |
| I seem to have narrowed the problem down to std::set and std::map.
Passing other types og stl objects like std::vector, std::array and
std::string does not seem to provoke crashes. Does this ring any bells
for someone?
| |
| Jakob Simon-Gaarde 2005-08-01, 4:13 am |
| Exactly what linker option is that?
| |
| Tom Widmer [VC++ MVP] 2005-08-02, 9:16 am |
| Jakob Simon-Gaarde wrote:
> I seem to have narrowed the problem down to std::set and std::map.
> Passing other types og stl objects like std::vector, std::array and
> std::string does not seem to provoke crashes. Does this ring any bells
> for someone?
What compiler are you using? If it's VC6, to share set and map across a
DLL boundary you need to apply the fixes to xtree here:
http://www.dinkumware.com/vc_fixes.html
Tom
| |
| Carl Daniel [VC++ MVP] 2005-08-02, 9:16 am |
| Jakob Simon-Gaarde wrote:
> Exactly what linker option is that?
Try link /?
In this case, it's /nodefaultlib:msvcrt.lib
-cd
| |
| Jakob Simon-Gaarde 2005-08-06, 5:02 pm |
| In short I found out that it's not my/our fault it isn't working (or to
be more presice, my configuration):
----------------------
http://support.microsoft.com/defaul...kb;en-us;172396
CAUSE (From Microsoft themselves)
Most classes in the Standard C++ Libraries use static data members
directly or indirectly. Since these classes are generated through
template instantiation, each executable image (usually with DLL or EXE
file name extensions) will contain its own copy of the static data
member for a given class. When a method of the class that requires the
static data member is executed, it uses the static data member in the
executable image in which the method code resides. Since the static
data members in the executable images are not in sync, this action
could result in an access violation or data may appear to be lost or
corrupted.
----------------------
I have also learned that a fix has been provided, but my experience is
that it's a bad idea to start making custom versions of very widespread
libraries, some day somebody forgets to use the "right" version and
nothing works anymore. Anyway here is the fix:
http://www.dinkumware.com/vc_fixes.html
Thanks for all your input guys
Jakob Simon-Gaarde
| |
| Stephen Howe 2005-08-07, 5:03 pm |
| > Thanks for all your input guys
>
> Jakob Simon-Gaarde
Note it has taken you 7 days to get to this point.
If you had stated that you were working with VC5/VC6 in your first message,
you would have been back in action in less time.
Stephen Howe
| |
| Jakob Simon-Gaarde 2005-08-07, 5:03 pm |
| Did you think I was linking to MSVCRT.DLL with VC7? No, 7 days ago I
just figured it must be Microsofts STL implementation and settled for
using a vector.
Jakob
| |
| Duane Hebert 2005-08-08, 9:10 am |
|
"Jakob Simon-Gaarde" <jsgaarde@gmail.com> wrote in message news:1123441766.855472.202600@g47g2000cwa.googlegroups.com...
> Did you think I was linking to MSVCRT.DLL with VC7? No, 7 days ago I
Yes.
|
|
|
|