[Ctk-developers] Fwd: Re: Re: Crash in ~OFCondition()

Julien Finet julien.finet at kitware.com
Fri Feb 17 11:56:18 EST 2012


Hi Uli,

Thanks for your explanation, it starts to makes sense to me.
See at the end of the email the output I got when building with VERBOSE
mode on.
You are right when you say that the application (that links against shared
B that links against shared A that links against static DCMTK) links with
DCMTK.

When I specify in the CMakeList.txt :
a) target_link_libraries(A LINK_INTERFACE_LIBRARIES) or
b) target_link_libraries(B LINK_INTERFACE_LIBRARIES)

In a), only A links against dcmtk libs; in b), only A and B link against
dcmtk libs.

In a) and b) the main application doesn't link with DCMTK anymore and
doesn't crash either as you correctly guessed.

I wonder if the rule should be to set an empty LINK_INTERFACE_LIBRARIES for
each target that directly links to a static version of DCMTK.
That means that if a library links against A and if that library uses
symbols of DCMTK not in the link object of A, then it needs to manually
link against DCMTK and must also set the LINK_INTERFACE_LIBRARIES to "".
That seems like a fair system.

Any thoughts?

Thanks,
Julien.

$ make VERBOSE=1
...
[ 33%] Building CXX object CMakeFiles/A.dir/a.cpp.o
/usr/bin/c++   -DA_EXPORTS -fPIC -g -fPIC
-I/home/julien/Work/CTK/CTK-noPython/CMakeExternals/Install/include/dcmtk/config
[...]  -o CMakeFiles/A.dir/a.cpp.o -c
/home/julien/Work/DCMTK/OfConditionCrash/src/a.cpp
Linking CXX shared library libA.so
/usr/bin/cmake -E cmake_link_script CMakeFiles/A.dir/link.txt --verbose=1
/usr/bin/c++  -fPIC -fPIC -g   -shared -Wl,-soname,libA.so -o libA.so
CMakeFiles/A.dir/a.cpp.o
/home/julien/Work/CTK/CTK-noPython/CMakeExternals/Install/lib/libdcmimage.a
[..] -lpthread
[ 33%] Built target A
[ 66%] Building CXX object CMakeFiles/B.dir/b.cpp.o
/usr/bin/c++   -DB_EXPORTS -fPIC -g -fPIC
-I/home/julien/Work/CTK/CTK-noPython/CMakeExternals/Install/include/dcmtk/config
[...]  -o CMakeFiles/B.dir/b.cpp.o -c
/home/julien/Work/DCMTK/OfConditionCrash/src/b.cpp
Linking CXX shared library libB.so
/usr/bin/cmake -E cmake_link_script CMakeFiles/B.dir/link.txt --verbose=1
/usr/bin/c++  -fPIC -fPIC -g   -shared -Wl,-soname,libB.so -o libB.so
CMakeFiles/B.dir/b.cpp.o libA.so
/home/julien/Work/CTK/CTK-noPython/CMakeExternals/Install/lib/libdcmimage.a
[..] -lpthread
-Wl,-rpath,/home/julien/Work/DCMTK/OfConditionCrash/build-ctk
[ 66%] Built target B
[100%] Building CXX object CMakeFiles/ofConditionCrash.dir/main.cpp.o
/usr/bin/c++    -fPIC -g
-I/home/julien/Work/CTK/CTK-noPython/CMakeExternals/Install/include/dcmtk/config
[...] -o CMakeFiles/ofConditionCrash.dir/main.cpp.o -c
/home/julien/Work/DCMTK/OfConditionCrash/src/main.cpp
Linking CXX executable ofConditionCrash
/usr/bin/c++   -fPIC -g    CMakeFiles/ofConditionCrash.dir/main.cpp.o  -o
ofConditionCrash -rdynamic libB.so libA.so
/home/julien/Work/CTK/CTK-noPython/CMakeExternals/Install/lib/libdcmimage.a
[...] -lpthread
-Wl,-rpath,/home/julien/Work/DCMTK/OfConditionCrash/build-ctk
[100%] Built target ofConditionCrash

On Fri, Feb 17, 2012 at 10:03 AM, Uli Schlachter <
Uli.Schlachter at informatik.uni-oldenburg.de> wrote:

> Hi everyone,
>
> > Nice job, I tried the head of DCMTK, and the OfCondition crash
> disappeared.
> > However I'm experiencing another crash. I can reproduce in my small
> program
> > (ofConditionCrash) and in the test application ctkDICOM in CTK.
> >
> > This is very odd, a static OFList is instantiated twice with the same
> > address  and deleted twice at the same address, therefore a crash. See
> below
> > the backtrace when I place a breakpoint in OFList() and ~OFList(). Note
> that
> > the address is always the same (0xa6ea70).
> [...]
>
> (I shortened and modified the following backtraces to make this more
> readable)
>
> > First time the OFList at address 0xa6ea70 is constructed:
> >
> > Breakpoint 1, OFList<DcmCodecList*>::OFList (this=0xa6ea70)
> > (gdb) backtrace
> > #0  OFList<DcmCodecList*>::OFList (this=0xa6ea70)
> > #1  0x00007ffff5711005 in __static_initialization_and_destruction_0 ()
> >       at
> /home/julien/Work/CTK/CTK-noPython/DCMTK/dcmdata/libsrc/dccodec.cc:43
> > #2  0x00007ffff5711069 in _GLOBAL__sub_I_dccodec.cc(void) ()
> > #3  0x00007ffff7deab26 in ?? () from /lib64/ld-linux-x86-64.so.2
> >
> > Second time the OFList at address 0xa6ea70 is constructed
> >
> > Breakpoint 1, OFList<DcmCodecList*>::OFList (this=0xa6ea70)
> > 330        OFList() : OFListBase() { }
> > (gdb) backtrace
> > #0  OFList<DcmCodecList*>::OFList (this=0xa6ea70)
> > #1  0x00000000006f997d in __static_initialization_and_destruction_0 ()
> >       at
> /home/julien/Work/CTK/CTK-noPython/DCMTK/dcmdata/libsrc/dccodec.cc:43
> > #2  0x00000000006f99e1 in _GLOBAL__sub_I_dccodec.cc(void) ()
> > #3  0x00000000007469ed in __libc_csu_init ()
> > #4  0x00007ffff5be92a0 in __libc_start_main ()
> >      from /lib/x86_64-linux-gnu/libc.so.6
> > #5  0x00000000004b0fd9 in _start ()
> [...]
>
> This looks a lot like DCMTK ended up twice in the application. Just to be
> sure
> that I didn't get anything wrong:
>
> - This is the test from ofConditionCrash.tar.gz from Julien Finet.
> - We have two shared libraries (A and B) and the main application.
> - main links against B, B links against A
> - A links against a *static* version of the DCMTK
>
> The above backtrace looks to me as if this static version of the DCMTK was
> linked in more than once. The first call to the constructor of
> DcmCodecList::registeredCodecs is done by the dynamic linker, hence this
> should
> be the constructor which is registered inside of library A. The second
> call is
> done (indirectly) by __libc_start_main. I think this is when the list of
> the
> main application's static constructors is run.
>
> I hear you ask "But if DCMTK is linked in twice, shouldn't the two version
> be at
> different addresses?". Yes, that is correct. However, both copies export
> the
> same symbols. The dynamic linker now tries to fix up that mess and
> (re-)links
> everything against one of the versions. Judging from the pointer, I'd say
> that
> the DCMTK copy in the main application won.
>
> Since I have some problems with FindDCMTK (no installed version of DCMTK
> laying
> around), could someone compile the test from ofConditionCrash.tar.gz with
> cmake
> and run the resulting makefiles with "make VERBOSE=1"? I bet the output
> will
> show that CMake links ofConditionCrash against DCMTK, too.
>
> A quick look into the CMake docs found the following possible explanation
> in the
> docs for target_link_libraries():
>
>   Library dependencies are transitive by default. When this target is
> linked
>   into another target then the libraries linked to this target will appear
> on
>   the link line for the other target too.
>
> If I am correct, my preferred solution would be not to use static
> libraries when
> building DCMTK. The linker will never try to link in a dynamic library
> more than
> once. :-)
>
> Cheers,
> Uli
>
> --
> my $key =
> "\x49\x03\x93\x08\x19\x94\x96\x94\x28\x93\x83\x04\x68\x28\xa8\xf5".
>
>  "\x0a\xb9\x94\x02\x45\x81\x93\x1f\xbc\xd7\xf3\xad\x93\xf5\x32\x93";
> my $cipher = Crypt::Rijndael->new( $key, Crypt::Rijndael::MODE_ECB() );
> my $plain = $ciper->decrypt($daten);
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/ctk-developers/attachments/20120217/3701c92b/attachment.html>


More information about the Ctk-developers mailing list